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