veecle_os_data_support_can/
id.rs1#[derive(Clone, Copy, PartialEq, Eq)]
3pub struct StandardId(u16);
4
5#[derive(Clone, Copy, PartialEq, Eq)]
7pub struct ExtendedId(u32);
8
9impl StandardId {
10 pub const fn new(value: u16) -> Option<Self> {
12 if value < 0x800 {
13 Some(Self(value))
14 } else {
15 None
16 }
17 }
18
19 pub const fn new_unwrap(value: u16) -> Self {
22 match Self::new(value) {
23 Some(value) => value,
24 None => panic!("out of range id"),
25 }
26 }
27
28 pub fn to_raw(self) -> u16 {
30 self.into()
31 }
32}
33
34impl TryFrom<u16> for StandardId {
35 type Error = ();
36
37 fn try_from(value: u16) -> Result<Self, Self::Error> {
38 Self::new(value).ok_or(())
39 }
40}
41
42impl TryFrom<u32> for StandardId {
43 type Error = ();
44
45 fn try_from(value: u32) -> Result<Self, Self::Error> {
46 u16::try_from(value).ok().and_then(Self::new).ok_or(())
47 }
48}
49
50impl From<StandardId> for u16 {
51 fn from(value: StandardId) -> Self {
52 value.0
53 }
54}
55
56impl core::fmt::Debug for StandardId {
57 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
58 write!(f, "{:#x}", self.0)
59 }
60}
61
62impl ExtendedId {
63 pub const fn new(value: u32) -> Option<Self> {
65 if value < 0x2000_0000 {
66 Some(Self(value))
67 } else {
68 None
69 }
70 }
71
72 pub const fn new_unwrap(value: u32) -> Self {
75 match Self::new(value) {
76 Some(value) => value,
77 None => panic!("out of range id"),
78 }
79 }
80
81 pub fn to_raw(self) -> u32 {
83 self.into()
84 }
85}
86
87impl TryFrom<u32> for ExtendedId {
88 type Error = ();
89
90 fn try_from(value: u32) -> Result<Self, Self::Error> {
91 Self::new(value).ok_or(())
92 }
93}
94
95impl From<ExtendedId> for u32 {
96 fn from(value: ExtendedId) -> Self {
97 value.0
98 }
99}
100
101impl core::fmt::Debug for ExtendedId {
102 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
103 write!(f, "{:#x}", self.0)?;
104 Ok(())
105 }
106}
107
108#[derive(Clone, Copy, PartialEq, Eq, Debug)]
110pub enum Id {
111 Standard(StandardId),
113
114 Extended(ExtendedId),
116}
117
118impl From<StandardId> for Id {
119 fn from(standard: StandardId) -> Self {
120 Self::Standard(standard)
121 }
122}
123
124impl From<ExtendedId> for Id {
125 fn from(extended: ExtendedId) -> Self {
126 Self::Extended(extended)
127 }
128}
129
130#[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize)]
133#[repr(Rust, packed)]
134pub struct PackedId(u32);
135
136impl From<Id> for PackedId {
137 fn from(id: Id) -> Self {
138 match id {
139 Id::Standard(StandardId(value)) => PackedId(u32::from(value)),
140 Id::Extended(ExtendedId(value)) => PackedId(value | 0x8000_0000),
141 }
142 }
143}
144
145impl From<PackedId> for Id {
146 fn from(id: PackedId) -> Self {
147 let PackedId(value) = id;
148 if value & 0x8000_0000 == 0x8000_0000 {
149 Id::Extended(ExtendedId(value & !0x8000_0000))
150 } else {
151 Id::Standard(StandardId(value as u16))
152 }
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use crate::id::PackedId;
159 use crate::{ExtendedId, Id, StandardId};
160
161 #[test]
162 fn pack_roundtrip() {
163 for id in [0, 1, 0x7FE, 0x7FF] {
164 let id = Id::Standard(StandardId::new(id).unwrap());
165 assert_eq!(id, Id::from(PackedId::from(id)));
166 }
167 for id in [0, 1, 0x1FFF_FFFE, 0x1FFF_FFFF] {
168 let id = Id::Extended(ExtendedId::new(id).unwrap());
169 assert_eq!(id, Id::from(PackedId::from(id)));
170 }
171 }
172
173 #[test]
174 fn id_to_integer() {
175 for id in [0, 1, 0x7FE, 0x7FF] {
176 let standard_id = StandardId::new(id).unwrap();
177 assert_eq!(standard_id.to_raw(), u16::from(standard_id));
178 assert_eq!(id, standard_id.to_raw());
179 }
180 for id in [0, 1, 0x1FFF_FFFE, 0x1FFF_FFFF] {
181 let extended_id = ExtendedId::new(id).unwrap();
182 assert_eq!(extended_id.to_raw(), u32::from(extended_id));
183 assert_eq!(id, extended_id.to_raw());
184 }
185 }
186}