Skip to main content

hiroz_schema/
type_id.rs

1//! ROS 2 Type ID Constants
2//!
3//! Type IDs follow the ROS 2 RIHS01 specification:
4//! - 1-15: Single primitives
5//! - 49-63: Fixed arrays (base + 48)
6//! - 97-111: Bounded sequences (base + 96)
7//! - 145-159: Unbounded sequences (base + 144)
8//!
9//! Special type IDs:
10//! - 1, 49, 97, 145: Nested message types
11
12/// Type ID constants matching ROS 2 RIHS01 specification
13pub struct TypeId;
14
15impl TypeId {
16    // ===== Single Primitives (1-17) =====
17
18    /// Nested message type (single)
19    pub const NESTED_TYPE: u8 = 1;
20    /// int8 (single)
21    pub const INT8: u8 = 2;
22    /// uint8/byte/char (single)
23    pub const UINT8: u8 = 3;
24    /// int16 (single)
25    pub const INT16: u8 = 4;
26    /// uint16 (single)
27    pub const UINT16: u8 = 5;
28    /// int32 (single)
29    pub const INT32: u8 = 6;
30    /// uint32 (single)
31    pub const UINT32: u8 = 7;
32    /// int64 (single)
33    pub const INT64: u8 = 8;
34    /// uint64 (single)
35    pub const UINT64: u8 = 9;
36    /// float32 (single)
37    pub const FLOAT32: u8 = 10;
38    /// float64 (single)
39    pub const FLOAT64: u8 = 11;
40    /// bool (single)
41    pub const BOOL: u8 = 15;
42    /// byte (alias for uint8)
43    pub const BYTE: u8 = 16;
44    /// string (single)
45    pub const STRING: u8 = 17;
46    /// wstring (single) - wide string
47    pub const WSTRING: u8 = 18;
48    /// fixed string (single)
49    pub const FIXED_STRING: u8 = 19;
50    /// fixed wstring (single)
51    pub const FIXED_WSTRING: u8 = 20;
52    /// bounded string (single) - string with max length
53    pub const BOUNDED_STRING: u8 = 21;
54    /// bounded wstring (single)
55    pub const BOUNDED_WSTRING: u8 = 22;
56
57    // ===== Fixed Arrays (49-65) = base + 48 =====
58
59    /// Nested message type (fixed array)
60    pub const NESTED_TYPE_ARRAY: u8 = 49;
61    /// int8 (fixed array)
62    pub const INT8_ARRAY: u8 = 50;
63    /// uint8/byte/char (fixed array)
64    pub const UINT8_ARRAY: u8 = 51;
65    /// int16 (fixed array)
66    pub const INT16_ARRAY: u8 = 52;
67    /// uint16 (fixed array)
68    pub const UINT16_ARRAY: u8 = 53;
69    /// int32 (fixed array)
70    pub const INT32_ARRAY: u8 = 54;
71    /// uint32 (fixed array)
72    pub const UINT32_ARRAY: u8 = 55;
73    /// int64 (fixed array)
74    pub const INT64_ARRAY: u8 = 56;
75    /// uint64 (fixed array)
76    pub const UINT64_ARRAY: u8 = 57;
77    /// float32 (fixed array)
78    pub const FLOAT32_ARRAY: u8 = 58;
79    /// float64 (fixed array)
80    pub const FLOAT64_ARRAY: u8 = 59;
81    /// bool (fixed array)
82    pub const BOOL_ARRAY: u8 = 63;
83    /// string (fixed array)
84    pub const STRING_ARRAY: u8 = 65;
85
86    // ===== Bounded Sequences (97-113) = base + 96 =====
87
88    /// Nested message type (bounded sequence)
89    pub const NESTED_TYPE_BOUNDED_SEQUENCE: u8 = 97;
90    /// int8 (bounded sequence)
91    pub const INT8_BOUNDED_SEQUENCE: u8 = 98;
92    /// uint8/byte/char (bounded sequence)
93    pub const UINT8_BOUNDED_SEQUENCE: u8 = 99;
94    /// int16 (bounded sequence)
95    pub const INT16_BOUNDED_SEQUENCE: u8 = 100;
96    /// uint16 (bounded sequence)
97    pub const UINT16_BOUNDED_SEQUENCE: u8 = 101;
98    /// int32 (bounded sequence)
99    pub const INT32_BOUNDED_SEQUENCE: u8 = 102;
100    /// uint32 (bounded sequence)
101    pub const UINT32_BOUNDED_SEQUENCE: u8 = 103;
102    /// int64 (bounded sequence)
103    pub const INT64_BOUNDED_SEQUENCE: u8 = 104;
104    /// uint64 (bounded sequence)
105    pub const UINT64_BOUNDED_SEQUENCE: u8 = 105;
106    /// float32 (bounded sequence)
107    pub const FLOAT32_BOUNDED_SEQUENCE: u8 = 106;
108    /// float64 (bounded sequence)
109    pub const FLOAT64_BOUNDED_SEQUENCE: u8 = 107;
110    /// bool (bounded sequence)
111    pub const BOOL_BOUNDED_SEQUENCE: u8 = 111;
112    /// string (bounded sequence)
113    pub const STRING_BOUNDED_SEQUENCE: u8 = 113;
114
115    // ===== Unbounded Sequences (145-161) = base + 144 =====
116
117    /// Nested message type (unbounded sequence)
118    pub const NESTED_TYPE_UNBOUNDED_SEQUENCE: u8 = 145;
119    /// int8 (unbounded sequence)
120    pub const INT8_UNBOUNDED_SEQUENCE: u8 = 146;
121    /// uint8/byte/char (unbounded sequence)
122    pub const UINT8_UNBOUNDED_SEQUENCE: u8 = 147;
123    /// int16 (unbounded sequence)
124    pub const INT16_UNBOUNDED_SEQUENCE: u8 = 148;
125    /// uint16 (unbounded sequence)
126    pub const UINT16_UNBOUNDED_SEQUENCE: u8 = 149;
127    /// int32 (unbounded sequence)
128    pub const INT32_UNBOUNDED_SEQUENCE: u8 = 150;
129    /// uint32 (unbounded sequence)
130    pub const UINT32_UNBOUNDED_SEQUENCE: u8 = 151;
131    /// int64 (unbounded sequence)
132    pub const INT64_UNBOUNDED_SEQUENCE: u8 = 152;
133    /// uint64 (unbounded sequence)
134    pub const UINT64_UNBOUNDED_SEQUENCE: u8 = 153;
135    /// float32 (unbounded sequence)
136    pub const FLOAT32_UNBOUNDED_SEQUENCE: u8 = 154;
137    /// float64 (unbounded sequence)
138    pub const FLOAT64_UNBOUNDED_SEQUENCE: u8 = 155;
139    /// bool (unbounded sequence)
140    pub const BOOL_UNBOUNDED_SEQUENCE: u8 = 159;
141    /// string (unbounded sequence)
142    pub const STRING_UNBOUNDED_SEQUENCE: u8 = 161;
143
144    // ===== Offset Constants =====
145
146    /// Offset to convert single type to fixed array
147    pub const ARRAY_OFFSET: u8 = 48;
148    /// Offset to convert single type to bounded sequence
149    pub const BOUNDED_SEQUENCE_OFFSET: u8 = 96;
150    /// Offset to convert single type to unbounded sequence
151    pub const UNBOUNDED_SEQUENCE_OFFSET: u8 = 144;
152
153    /// Check if a type ID is a nested (message) type
154    pub const fn is_nested(type_id: u8) -> bool {
155        type_id == Self::NESTED_TYPE
156            || type_id == Self::NESTED_TYPE_ARRAY
157            || type_id == Self::NESTED_TYPE_BOUNDED_SEQUENCE
158            || type_id == Self::NESTED_TYPE_UNBOUNDED_SEQUENCE
159    }
160
161    /// Check if a type ID is an array (fixed size)
162    pub const fn is_array(type_id: u8) -> bool {
163        type_id >= 49 && type_id <= 65
164    }
165
166    /// Check if a type ID is a bounded sequence
167    pub const fn is_bounded_sequence(type_id: u8) -> bool {
168        type_id >= 97 && type_id <= 113
169    }
170
171    /// Check if a type ID is an unbounded sequence
172    pub const fn is_unbounded_sequence(type_id: u8) -> bool {
173        type_id >= 145 && type_id <= 161
174    }
175
176    /// Check if a type ID is a single (non-array, non-sequence) value
177    pub const fn is_single(type_id: u8) -> bool {
178        type_id >= 1 && type_id <= 17
179    }
180
181    /// Get the base type ID (strip array/sequence modifier)
182    pub const fn base_type(type_id: u8) -> u8 {
183        if Self::is_unbounded_sequence(type_id) {
184            type_id - Self::UNBOUNDED_SEQUENCE_OFFSET
185        } else if Self::is_bounded_sequence(type_id) {
186            type_id - Self::BOUNDED_SEQUENCE_OFFSET
187        } else if Self::is_array(type_id) {
188            type_id - Self::ARRAY_OFFSET
189        } else {
190            type_id
191        }
192    }
193
194    /// Get the type name for a base type ID
195    pub const fn type_name(type_id: u8) -> Option<&'static str> {
196        match Self::base_type(type_id) {
197            Self::NESTED_TYPE => Some("nested"),
198            Self::INT8 => Some("int8"),
199            Self::UINT8 => Some("uint8"),
200            Self::INT16 => Some("int16"),
201            Self::UINT16 => Some("uint16"),
202            Self::INT32 => Some("int32"),
203            Self::UINT32 => Some("uint32"),
204            Self::INT64 => Some("int64"),
205            Self::UINT64 => Some("uint64"),
206            Self::FLOAT32 => Some("float32"),
207            Self::FLOAT64 => Some("float64"),
208            Self::BOOL => Some("bool"),
209            Self::STRING => Some("string"),
210            _ => None,
211        }
212    }
213}
214
215#[cfg(test)]
216mod tests {
217    use super::*;
218
219    #[test]
220    fn test_type_id_offsets() {
221        assert_eq!(TypeId::INT32_ARRAY, TypeId::INT32 + TypeId::ARRAY_OFFSET);
222        assert_eq!(
223            TypeId::INT32_BOUNDED_SEQUENCE,
224            TypeId::INT32 + TypeId::BOUNDED_SEQUENCE_OFFSET
225        );
226        assert_eq!(
227            TypeId::INT32_UNBOUNDED_SEQUENCE,
228            TypeId::INT32 + TypeId::UNBOUNDED_SEQUENCE_OFFSET
229        );
230    }
231
232    #[test]
233    fn test_is_nested() {
234        assert!(TypeId::is_nested(TypeId::NESTED_TYPE));
235        assert!(TypeId::is_nested(TypeId::NESTED_TYPE_ARRAY));
236        assert!(TypeId::is_nested(TypeId::NESTED_TYPE_BOUNDED_SEQUENCE));
237        assert!(TypeId::is_nested(TypeId::NESTED_TYPE_UNBOUNDED_SEQUENCE));
238        assert!(!TypeId::is_nested(TypeId::INT32));
239    }
240
241    #[test]
242    fn test_is_array() {
243        assert!(TypeId::is_array(TypeId::INT32_ARRAY));
244        assert!(TypeId::is_array(TypeId::STRING_ARRAY));
245        assert!(!TypeId::is_array(TypeId::INT32));
246        assert!(!TypeId::is_array(TypeId::INT32_UNBOUNDED_SEQUENCE));
247    }
248
249    #[test]
250    fn test_base_type() {
251        assert_eq!(TypeId::base_type(TypeId::INT32), TypeId::INT32);
252        assert_eq!(TypeId::base_type(TypeId::INT32_ARRAY), TypeId::INT32);
253        assert_eq!(
254            TypeId::base_type(TypeId::INT32_BOUNDED_SEQUENCE),
255            TypeId::INT32
256        );
257        assert_eq!(
258            TypeId::base_type(TypeId::INT32_UNBOUNDED_SEQUENCE),
259            TypeId::INT32
260        );
261    }
262
263    #[test]
264    fn test_type_name() {
265        assert_eq!(TypeId::type_name(TypeId::INT32), Some("int32"));
266        assert_eq!(TypeId::type_name(TypeId::INT32_ARRAY), Some("int32"));
267        assert_eq!(TypeId::type_name(TypeId::STRING), Some("string"));
268        assert_eq!(TypeId::type_name(TypeId::NESTED_TYPE), Some("nested"));
269    }
270}