veecle_os_data_support_can/
id.rs1#[derive(Clone, Copy, PartialEq, Eq, serde::Serialize)]
3pub struct StandardId(u16);
4
5#[derive(Clone, Copy, PartialEq, Eq, serde::Serialize)]
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<'de> serde::Deserialize<'de> for StandardId {
63 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64 where
65 D: serde::Deserializer<'de>,
66 {
67 let value = u16::deserialize(deserializer)?;
68 StandardId::new(value)
69 .ok_or_else(|| serde::de::Error::custom("standard CAN id must be < 0x800"))
70 }
71}
72
73impl ExtendedId {
74 pub const fn new(value: u32) -> Option<Self> {
76 if value < 0x2000_0000 {
77 Some(Self(value))
78 } else {
79 None
80 }
81 }
82
83 pub const fn new_unwrap(value: u32) -> Self {
86 match Self::new(value) {
87 Some(value) => value,
88 None => panic!("out of range id"),
89 }
90 }
91
92 pub fn to_raw(self) -> u32 {
94 self.into()
95 }
96}
97
98impl TryFrom<u32> for ExtendedId {
99 type Error = ();
100
101 fn try_from(value: u32) -> Result<Self, Self::Error> {
102 Self::new(value).ok_or(())
103 }
104}
105
106impl From<ExtendedId> for u32 {
107 fn from(value: ExtendedId) -> Self {
108 value.0
109 }
110}
111
112impl core::fmt::Debug for ExtendedId {
113 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
114 write!(f, "{:#x}", self.0)?;
115 Ok(())
116 }
117}
118
119impl<'de> serde::Deserialize<'de> for ExtendedId {
120 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
121 where
122 D: serde::Deserializer<'de>,
123 {
124 let value = u32::deserialize(deserializer)?;
125 ExtendedId::new(value)
126 .ok_or_else(|| serde::de::Error::custom("extended CAN id must be < 0x2000_0000"))
127 }
128}
129
130#[derive(Clone, Copy, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
132pub enum Id {
133 Standard(StandardId),
135
136 Extended(ExtendedId),
138}
139
140impl From<StandardId> for Id {
141 fn from(standard: StandardId) -> Self {
142 Self::Standard(standard)
143 }
144}
145
146impl From<ExtendedId> for Id {
147 fn from(extended: ExtendedId) -> Self {
148 Self::Extended(extended)
149 }
150}
151
152#[derive(Clone, Copy, PartialEq, Eq, Debug)]
155#[repr(Rust, packed)]
156pub struct PackedId(u32);
157
158impl From<Id> for PackedId {
159 fn from(id: Id) -> Self {
160 match id {
161 Id::Standard(StandardId(value)) => PackedId(u32::from(value)),
162 Id::Extended(ExtendedId(value)) => PackedId(value | 0x8000_0000),
163 }
164 }
165}
166
167impl From<PackedId> for Id {
168 fn from(id: PackedId) -> Self {
169 let PackedId(value) = id;
170 if value & 0x8000_0000 == 0x8000_0000 {
171 Id::Extended(ExtendedId(value & !0x8000_0000))
172 } else {
173 Id::Standard(StandardId(value as u16))
174 }
175 }
176}
177
178impl serde::Serialize for PackedId {
181 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
182 where
183 S: serde::Serializer,
184 {
185 Id::from(*self).serialize(serializer)
186 }
187}
188
189impl<'de> serde::Deserialize<'de> for PackedId {
190 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
191 where
192 D: serde::Deserializer<'de>,
193 {
194 let id = Id::deserialize(deserializer)?;
195 Ok(PackedId::from(id))
196 }
197}
198
199#[cfg(test)]
200#[cfg_attr(coverage_nightly, coverage(off))]
201mod tests {
202 use std::format;
203 use std::string::ToString;
204
205 use crate::id::PackedId;
206 use crate::{ExtendedId, Id, StandardId};
207
208 const STANDARD_ID_VALIDS: [u16; 4] = [0, 1, 0x7FE, 0x7FF];
209 const STANDARD_ID_INVALIDS: [u16; 2] = [0x800, 0xFFFF];
210 const EXTENDED_ID_VALIDS: [u32; 4] = [0, 1, 0x1FFF_FFFE, 0x1FFF_FFFF];
211 const EXTENDED_ID_INVALIDS: [u32; 2] = [0x2000_0000, 0xFFFF_FFFF];
212
213 #[test]
214 fn pack_roundtrip() {
215 for id in STANDARD_ID_VALIDS {
216 let id = Id::Standard(StandardId::new(id).unwrap());
217 assert_eq!(id, Id::from(PackedId::from(id)));
218 }
219 for id in EXTENDED_ID_VALIDS {
220 let id = Id::Extended(ExtendedId::new(id).unwrap());
221 assert_eq!(id, Id::from(PackedId::from(id)));
222 }
223 }
224
225 #[test]
226 fn id_to_integer() {
227 for value in STANDARD_ID_VALIDS {
228 let standard_id = StandardId::new(value).unwrap();
229 assert_eq!(standard_id.to_raw(), u16::from(standard_id));
230 assert_eq!(value, standard_id.to_raw());
231 }
232 for value in EXTENDED_ID_VALIDS {
233 let extended_id = ExtendedId::new(value).unwrap();
234 assert_eq!(extended_id.to_raw(), u32::from(extended_id));
235 assert_eq!(value, extended_id.to_raw());
236 }
237 }
238
239 #[test]
240 fn test_deserialize_standard_id_valid() {
241 for value in STANDARD_ID_VALIDS {
242 let json = value.to_string();
243 let id: StandardId = serde_json::from_str(&json).unwrap();
244 assert_eq!(id, StandardId::new(value).unwrap());
245 assert_eq!(json, serde_json::to_string(&id).unwrap());
246 }
247 }
248
249 #[test]
250 fn test_deserialize_standard_id_invalid() {
251 for value in STANDARD_ID_INVALIDS {
252 let json = value.to_string();
253 assert!(serde_json::from_str::<StandardId>(&json).is_err());
254 }
255 }
256
257 #[test]
258 fn test_deserialize_extended_id_valid() {
259 for value in EXTENDED_ID_VALIDS {
260 let json = value.to_string();
261 let id: ExtendedId = serde_json::from_str(&json).unwrap();
262 assert_eq!(id, ExtendedId::new(value).unwrap());
263 assert_eq!(json, serde_json::to_string(&id).unwrap());
264 }
265 }
266
267 #[test]
268 fn test_deserialize_extended_id_invalid() {
269 for value in EXTENDED_ID_INVALIDS {
270 let json = value.to_string();
271 assert!(serde_json::from_str::<ExtendedId>(&json).is_err());
272 }
273 }
274
275 #[test]
276 fn test_deserialize_id_and_packed_id_valid() {
277 for value in STANDARD_ID_VALIDS {
278 let json = format!(r#"{{"Standard":{value}}}"#);
279 let id: Id = serde_json::from_str(&json).unwrap();
280 assert_eq!(id, Id::Standard(StandardId::new(value).unwrap()));
281 assert_eq!(json, serde_json::to_string(&id).unwrap());
282 let packed: PackedId = serde_json::from_str(&json).unwrap();
283 assert_eq!(packed, PackedId::from(id));
284 assert_eq!(json, serde_json::to_string(&packed).unwrap());
285 }
286 for value in EXTENDED_ID_VALIDS {
287 let json = format!(r#"{{"Extended":{value}}}"#);
288 let id: Id = serde_json::from_str(&json).unwrap();
289 assert_eq!(id, Id::Extended(ExtendedId::new(value).unwrap()));
290 assert_eq!(json, serde_json::to_string(&id).unwrap());
291 let packed: PackedId = serde_json::from_str(&json).unwrap();
292 assert_eq!(packed, PackedId::from(id));
293 assert_eq!(json, serde_json::to_string(&packed).unwrap());
294 }
295 }
296
297 #[test]
298 fn test_deserialize_id_and_packed_id_invalid() {
299 for value in STANDARD_ID_INVALIDS {
300 let json = format!(r#"{{"Standard":{value}}}"#);
301 assert!(serde_json::from_str::<Id>(&json).is_err());
302 assert!(serde_json::from_str::<PackedId>(&json).is_err());
303 }
304 for value in EXTENDED_ID_INVALIDS {
305 let json = format!(r#"{{"Extended":{value}}}"#);
306 assert!(serde_json::from_str::<Id>(&json).is_err());
307 assert!(serde_json::from_str::<PackedId>(&json).is_err());
308 }
309 }
310}