1use bitfield_struct::bitfield;
4use num_enum::{IntoPrimitive, TryFromPrimitive};
5
6use crate::Ident;
7
8#[bitfield(u32, debug = false)]
10#[derive(PartialEq)]
11pub struct IoFlags {
12 #[bits(1)]
13 data_or_constant: bool,
14 #[bits(1)]
15 array_or_variable: bool,
16 #[bits(1)]
17 absolute_or_relative: bool,
18 #[bits(1)]
19 wrap: bool,
20 #[bits(1)]
21 non_linear: bool,
22 #[bits(1)]
23 no_preferred: bool,
24 #[bits(1)]
25 null_state: bool,
26 #[bits(1)]
28 volatile: bool,
29 #[bits(1)]
30 bitfield_or_buffered: bool,
31 #[bits(23)]
32 reserved: u32,
33}
34
35impl IoFlags {
36 pub const fn data() -> Self {
38 Self::new()
39 }
40
41 pub const fn constant() -> Self {
43 Self::new().with_data_or_constant(true)
44 }
45
46 pub const fn variable(self) -> Self {
48 self.with_array_or_variable(true)
49 }
50
51 pub const fn relative(self) -> Self {
53 self.with_absolute_or_relative(true)
54 }
55}
56
57pub mod ioflags {
62 use super::IoFlags;
63
64 pub const DATA_VARIABLE_ABSOLUTE: IoFlags = IoFlags::data().variable();
68
69 pub const CONSTANT: IoFlags = IoFlags::constant();
73
74 pub const ARRAY: IoFlags = IoFlags::data();
78}
79
80#[derive(Clone, Copy, PartialEq)]
82pub struct InputFlags(pub IoFlags);
83
84#[derive(Clone, Copy, PartialEq)]
86pub struct OutputFeatureFlags(pub IoFlags);
87
88#[expect(missing_docs)]
90#[derive(Clone, Copy, Debug, PartialEq, TryFromPrimitive, IntoPrimitive)]
91#[repr(u8)]
92pub enum KnownCollectionType {
93 Physical = 0,
94 Application = 1,
95 Logical = 2,
96 Report = 3,
97 NamedArray = 4,
98 UsageSwitch = 5,
99 UsageModifier = 6,
100}
101
102pub type CollectionType = Ident<KnownCollectionType, u8>;
104
105#[expect(missing_docs)]
110#[derive(Clone, Copy, Debug, PartialEq, TryFromPrimitive)]
111#[repr(u32)]
112#[non_exhaustive]
113pub enum KnownUnit {
114 Centimeter = 0x11,
116 Radian = 0x12,
118 Inch = 0x13,
120 Degree = 0x14,
122}
123
124pub type Unit = Ident<KnownUnit, u32>;
126
127#[cfg(feature = "std")]
128mod std_impls {
129 use super::*;
130
131 use std::fmt::{self, Debug};
132
133 fn debug_flags(is_input: bool, flags: IoFlags, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 if flags.data_or_constant() {
135 f.write_str("Constant ")?;
136 } else {
137 f.write_str("Data ")?;
138 }
139 if flags.array_or_variable() {
140 f.write_str("Variable ")?;
141 } else {
142 f.write_str("Array ")?;
143 }
144 if flags.absolute_or_relative() {
145 f.write_str("Relative ")?;
146 } else {
147 f.write_str("Absolute ")?;
148 }
149 if flags.wrap() {
150 f.write_str("Wrap ")?;
151 } else {
152 f.write_str("No-Wrap ")?;
153 }
154 if flags.non_linear() {
155 f.write_str("Non-Linear ")?;
156 } else {
157 f.write_str("Linear ")?;
158 }
159 if flags.no_preferred() {
160 f.write_str("No-Preferred ")?;
161 } else {
162 f.write_str("Preferred-State ")?;
163 }
164 if flags.null_state() {
165 f.write_str("Null-State ")?
166 } else {
167 f.write_str("No-Null-Position ")?;
168 }
169
170 if flags.volatile() {
172 f.write_str("Volatile ")?;
173 } else {
174 if !is_input {
175 f.write_str("Non-Volatile ")?;
176 }
177 }
178
179 if flags.bitfield_or_buffered() {
180 f.write_str("Buffered-Bytes")?;
181 } else {
182 f.write_str("Bit-Field")?;
183 }
184 Ok(())
185 }
186
187 impl Debug for InputFlags {
188 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189 debug_flags(true, self.0, f)
190 }
191 }
192
193 impl Debug for OutputFeatureFlags {
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 debug_flags(false, self.0, f)
196 }
197 }
198}