1#[cfg(all(feature = "std", unix))]
13mod raw_fd_container {
14 use std::os::unix::io::OwnedFd;
15
16 pub(crate) type RawFdContainer = OwnedFd;
17}
18
19#[cfg(not(all(feature = "std", unix)))]
20mod raw_fd_container {
21 use core::convert::Infallible;
22
23 #[derive(Debug)]
24 #[doc(hidden)]
25 pub struct RawFdContainer(Infallible);
26
27 impl Drop for RawFdContainer {
28 fn drop(&mut self) {
29 match self.0 {}
31 }
32 }
33}
34
35pub type RawFdContainer = raw_fd_container::RawFdContainer;
55
56mod pretty_printer {
57 use core::fmt::{Debug, Formatter, Result};
58
59 pub(crate) fn pretty_print_enum(
66 fmt: &mut Formatter<'_>,
67 value: u32,
68 cases: &[(u32, &str, &str)],
69 ) -> Result {
70 for (variant, name1, name2) in cases {
71 if &value == variant {
72 if fmt.alternate() {
73 return fmt.write_str(name2);
74 } else {
75 return fmt.write_str(name1);
76 }
77 }
78 }
79 Debug::fmt(&value, fmt)
80 }
81
82 pub(crate) fn pretty_print_bitmask(
89 fmt: &mut Formatter<'_>,
90 value: u32,
91 cases: &[(u32, &str, &str)],
92 ) -> Result {
93 let known_bits = cases.iter().fold(0, |acc, (value, _, _)| acc | value);
95 let remaining = value & !known_bits;
96 let mut already_printed = if value == 0 || remaining != 0 {
97 Debug::fmt(&remaining, fmt)?;
98 true
99 } else {
100 false
101 };
102 for (variant, name1, name2) in cases {
103 if variant & value != 0 {
104 if already_printed {
105 fmt.write_str(" | ")?;
106 }
107 already_printed = true;
108 if fmt.alternate() {
109 fmt.write_str(name2)?;
110 } else {
111 fmt.write_str(name1)?;
112 }
113 }
114 }
115 Ok(())
116 }
117
118 #[cfg(test)]
119 mod test {
120 use super::{pretty_print_bitmask, pretty_print_enum};
121 use alloc::format;
122 use core::fmt::{Display, Formatter, Result};
123
124 type CallbackType = fn(&mut Formatter<'_>, u32, &[(u32, &str, &str)]) -> Result;
125
126 struct CallbackFormating<'a, 'b> {
127 callback: CallbackType,
128 value: u32,
129 cases: &'a [(u32, &'b str, &'b str)],
130 }
131
132 fn new_enum<'a, 'b>(
133 value: u32,
134 cases: &'a [(u32, &'b str, &'b str)],
135 ) -> CallbackFormating<'a, 'b> {
136 CallbackFormating {
137 callback: pretty_print_enum,
138 value,
139 cases,
140 }
141 }
142
143 fn new_bitmask<'a, 'b>(
144 value: u32,
145 cases: &'a [(u32, &'b str, &'b str)],
146 ) -> CallbackFormating<'a, 'b> {
147 CallbackFormating {
148 callback: pretty_print_bitmask,
149 value,
150 cases,
151 }
152 }
153
154 impl Display for CallbackFormating<'_, '_> {
155 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
156 (self.callback)(f, self.value, self.cases)
157 }
158 }
159
160 #[test]
161 fn test_enum() {
162 let cases = [(0, "zero", "ZERO"), (42, "the answer", "ANSWER")];
163 let printer = new_enum(0, &cases);
164 assert_eq!(&format!("{}", printer), "zero");
165 assert_eq!(&format!("{:#}", printer), "ZERO");
166 let printer = new_enum(1, &cases);
167 assert_eq!(&format!("{}", printer), "1");
168 assert_eq!(&format!("{:#}", printer), "1");
169 let printer = new_enum(42, &cases);
170 assert_eq!(&format!("{}", printer), "the answer");
171 assert_eq!(&format!("{:#}", printer), "ANSWER");
172 }
173
174 #[test]
175 fn test_bitmask() {
176 let bits = [
177 (1 << 5, "b5", "B5"),
178 (1 << 1, "b1", "B1"),
179 (1 << 0, "unused", "UNUSED"),
180 ];
181 let printer = new_bitmask(8, &bits);
182 assert_eq!(&format!("{}", printer), "8");
183 assert_eq!(&format!("{:#}", printer), "8");
184 let printer = new_bitmask(32, &bits);
185 assert_eq!(&format!("{}", printer), "b5");
186 assert_eq!(&format!("{:#}", printer), "B5");
187 let printer = new_bitmask(34, &bits);
188 assert_eq!(&format!("{}", printer), "b5 | b1");
189 assert_eq!(&format!("{:#}", printer), "B5 | B1");
190 let printer = new_bitmask(42, &bits);
191 assert_eq!(&format!("{}", printer), "8 | b5 | b1");
192 assert_eq!(&format!("{:#}", printer), "8 | B5 | B1");
193 }
194 }
195}
196
197pub(crate) use pretty_printer::{pretty_print_bitmask, pretty_print_enum};