1use bitfield_struct::bitfield;
4
5#[bitfield(u32, debug = false, new = false)]
15#[derive(PartialEq)]
16pub struct IoFlags {
17 #[bits(1)]
18 data_or_constant: bool,
19 #[bits(1)]
20 array_or_variable: bool,
21 #[bits(1)]
22 absolute_or_relative: bool,
23 #[bits(1)]
24 no_wrap_or_wrap: bool,
25 #[bits(1)]
26 linear_or_nonlinear: bool,
27 #[bits(1)]
28 preferred_or_no_preferred: bool,
29 #[bits(1)]
30 no_null_position_or_null_state: bool,
31 #[bits(1)]
33 non_volatile_or_volatile: bool,
34 #[bits(1)]
35 bitfield_or_buffered: bool,
36 #[bits(23)]
37 _reserved: u32,
38}
39
40impl IoFlags {
41 const fn new() -> Self {
42 Self(0)
43 }
44
45 pub const fn data() -> Self {
47 Self::new()
48 }
49
50 pub const fn constant() -> Self {
52 Self::new().with_data_or_constant(true)
53 }
54
55 pub const fn is_constant(self) -> bool {
57 self.data_or_constant()
58 }
59 pub const fn is_data(self) -> bool {
61 !self.is_constant()
62 }
63
64 pub const fn variable(self) -> Self {
68 self.with_array_or_variable(true)
69 }
70
71 pub const fn is_variable(self) -> bool {
73 self.array_or_variable()
74 }
75 pub const fn is_array(self) -> bool {
77 !self.is_variable()
78 }
79
80 pub const fn relative(self) -> Self {
84 self.with_absolute_or_relative(true)
85 }
86
87 pub const fn is_relative(self) -> bool {
89 self.absolute_or_relative()
90 }
91 pub const fn is_absolute(self) -> bool {
93 !self.is_relative()
94 }
95
96 pub const fn wrap(self) -> Self {
100 self.with_no_wrap_or_wrap(true)
101 }
102
103 pub const fn wraps(self) -> bool {
105 self.no_wrap_or_wrap()
106 }
107
108 pub const fn non_linear(self) -> Self {
112 self.with_linear_or_nonlinear(true)
113 }
114
115 pub const fn is_linear(self) -> bool {
117 !self.linear_or_nonlinear()
118 }
119
120 pub const fn no_preferred_state(self) -> Self {
128 self.with_preferred_or_no_preferred(true)
129 }
130
131 pub const fn has_preferred_state(self) -> bool {
133 !self.preferred_or_no_preferred()
134 }
135
136 pub const fn null_state(self) -> Self {
143 self.with_no_null_position_or_null_state(true)
144 }
145
146 pub const fn has_null_state(self) -> bool {
148 !self.no_null_position_or_null_state()
149 }
150
151 pub const fn volatile(self) -> Self {
159 self.with_non_volatile_or_volatile(true)
160 }
161
162 pub const fn is_volatile(self) -> bool {
164 self.non_volatile_or_volatile()
165 }
166
167 pub const fn buffered(self) -> Self {
174 self.with_bitfield_or_buffered(true)
175 }
176
177 pub const fn is_buffered(self) -> bool {
179 self.bitfield_or_buffered()
180 }
181 pub const fn is_bitfield(self) -> bool {
183 !self.is_buffered()
184 }
185}
186
187pub mod ioflags {
192 use super::IoFlags;
193
194 pub const DATA_VARIABLE_ABSOLUTE: IoFlags = IoFlags::data().variable();
198
199 pub const CONSTANT: IoFlags = IoFlags::constant();
203
204 pub const ARRAY: IoFlags = IoFlags::data();
208}
209
210#[derive(Clone, Copy, PartialEq)]
212pub struct InputFlags(pub IoFlags);
213
214impl core::ops::Deref for InputFlags {
215 type Target = IoFlags;
216
217 fn deref(&self) -> &Self::Target {
218 &self.0
219 }
220}
221
222impl InputFlags {
223 pub fn from_unchecked(flags: IoFlags) -> Self {
225 Self(flags)
226 }
227
228 #[doc(hidden)]
229 #[deprecated = "`InputFlags` should not use the volatile bit"]
230 pub fn is_volatile(&self) -> bool {
232 self.0.is_volatile()
233 }
234}
235
236#[derive(Clone, Copy, PartialEq)]
238pub struct OutputFeatureFlags(pub IoFlags);
239
240impl core::ops::Deref for OutputFeatureFlags {
241 type Target = IoFlags;
242
243 fn deref(&self) -> &Self::Target {
244 &self.0
245 }
246}
247
248impl From<IoFlags> for OutputFeatureFlags {
249 fn from(flags: IoFlags) -> Self {
253 Self(flags)
254 }
255}
256
257#[cfg(feature = "std")]
258mod std_impls {
259 use super::*;
260
261 use std::fmt::{self, Debug};
262
263 fn debug_flags(is_input: bool, flags: IoFlags, f: &mut fmt::Formatter<'_>) -> fmt::Result {
264 if flags.data_or_constant() {
265 f.write_str("Constant ")?;
266 } else {
267 f.write_str("Data ")?;
268 }
269 if flags.array_or_variable() {
270 f.write_str("Variable ")?;
271 } else {
272 f.write_str("Array ")?;
273 }
274 if flags.absolute_or_relative() {
275 f.write_str("Relative ")?;
276 } else {
277 f.write_str("Absolute ")?;
278 }
279 if flags.no_wrap_or_wrap() {
280 f.write_str("Wrap ")?;
281 } else {
282 f.write_str("No-Wrap ")?;
283 }
284 if flags.linear_or_nonlinear() {
285 f.write_str("Non-Linear ")?;
286 } else {
287 f.write_str("Linear ")?;
288 }
289 if flags.preferred_or_no_preferred() {
290 f.write_str("No-Preferred ")?;
291 } else {
292 f.write_str("Preferred-State ")?;
293 }
294 if flags.no_null_position_or_null_state() {
295 f.write_str("Null-State ")?
296 } else {
297 f.write_str("No-Null-Position ")?;
298 }
299
300 if flags.non_volatile_or_volatile() {
302 f.write_str("Volatile ")?;
303 } else {
304 if !is_input {
305 f.write_str("Non-Volatile ")?;
306 }
307 }
308
309 if flags.bitfield_or_buffered() {
310 f.write_str("Buffered-Bytes")?;
311 } else {
312 f.write_str("Bit-Field")?;
313 }
314 Ok(())
315 }
316
317 impl Debug for InputFlags {
318 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
319 debug_flags(true, self.0, f)
320 }
321 }
322
323 impl Debug for OutputFeatureFlags {
324 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
325 debug_flags(false, self.0, f)
326 }
327 }
328}
329
330#[cfg(test)]
331mod tests {
332 use super::*;
333
334 #[test]
335 fn test_ioflags() {
336 const DATA: IoFlags = IoFlags::data();
337 const CONSTANT: IoFlags = IoFlags::constant();
338
339 assert!(DATA.is_data());
340 assert!(!DATA.is_constant());
341 assert!(!CONSTANT.is_data());
342 assert!(CONSTANT.is_constant());
343
344 assert!(DATA.is_array());
345 assert!(!DATA.is_variable());
346 assert!(!DATA.variable().is_array());
347 assert!(DATA.variable().is_variable());
348
349 assert!(DATA.is_absolute());
350 assert!(!DATA.is_relative());
351 assert!(!DATA.relative().is_absolute());
352 assert!(DATA.relative().is_relative());
353
354 assert!(!DATA.wraps());
355 assert!(DATA.wrap().wraps());
356
357 assert!(DATA.is_linear());
358 assert!(!DATA.non_linear().is_linear());
359
360 assert!(DATA.has_preferred_state());
361 assert!(!DATA.no_preferred_state().has_preferred_state());
362
363 assert!(DATA.has_null_state());
364 assert!(!DATA.null_state().has_null_state());
365
366 assert!(!DATA.is_volatile());
367 assert!(DATA.volatile().is_volatile());
368
369 assert!(DATA.is_bitfield());
370 assert!(!DATA.is_buffered());
371 assert!(!DATA.buffered().is_bitfield());
372 assert!(DATA.buffered().is_buffered());
373 }
374}