diff --git a/embedded-can/src/id.rs b/embedded-can/src/id.rs index b0d6d4d5..017d557b 100644 --- a/embedded-can/src/id.rs +++ b/embedded-can/src/id.rs @@ -10,7 +10,10 @@ impl StandardId { pub const ZERO: Self = Self(0); /// CAN ID `0x7FF`, the lowest priority. - pub const MAX: Self = Self(0x7FF); + pub const MAX: Self = Self(Self::MAX_RAW); + + /// Raw CAN ID `0x7FF`, the lowest priority. + const MAX_RAW: u16 = 0x7FF; /// Tries to create a `StandardId` from a raw 16-bit integer. /// @@ -18,7 +21,7 @@ impl StandardId { #[inline] #[must_use] pub const fn new(raw: u16) -> Option { - if raw <= 0x7FF { + if raw <= Self::MAX_RAW { Some(Self(raw)) } else { None @@ -53,7 +56,10 @@ impl ExtendedId { pub const ZERO: Self = Self(0); /// CAN ID `0x1FFFFFFF`, the lowest priority. - pub const MAX: Self = Self(0x1FFF_FFFF); + pub const MAX: Self = Self(Self::MAX_RAW); + + /// Raw CAN ID `0x1FFFFFFF`, the lowest priority. + const MAX_RAW: u32 = 0x1FFF_FFFF; /// Tries to create a `ExtendedId` from a raw 32-bit integer. /// @@ -61,7 +67,7 @@ impl ExtendedId { #[inline] #[must_use] pub const fn new(raw: u32) -> Option { - if raw <= 0x1FFF_FFFF { + if raw <= Self::MAX_RAW { Some(Self(raw)) } else { None @@ -104,6 +110,27 @@ pub enum Id { Extended(ExtendedId), } +impl Id { + /// Creates a CAN identifier as a standard ID. + pub fn new_standard(raw: u16) -> Option { + Some(Id::from(StandardId::new(raw)?)) + } + + /// Creates a CAN identifier as an extended ID. + pub fn new_extended(raw: u32) -> Option { + Some(Id::from(ExtendedId::new(raw)?)) + } + + /// Determines if the value is a standard, 11-bit, identifier. + pub fn is_standard(&self) -> bool { + matches!(self, Id::Standard(_)) + } + /// Determines if the value is an extended, 29-bit, identifier. + pub fn is_extended(&self) -> bool { + matches!(self, Id::Extended(_)) + } +} + /// Implement `Ord` according to the CAN arbitration rules /// /// When performing arbitration, frames are looked at bit for bit starting @@ -162,20 +189,17 @@ mod tests { #[test] fn standard_id_new() { - assert_eq!( - StandardId::new(StandardId::MAX.as_raw()), - Some(StandardId::MAX) - ); + assert_eq!(StandardId::new(StandardId::MAX_RAW), Some(StandardId::MAX)); } #[test] fn standard_id_new_out_of_range() { - assert_eq!(StandardId::new(StandardId::MAX.as_raw() + 1), None); + assert_eq!(StandardId::new(StandardId::MAX_RAW + 1), None); } #[test] fn standard_id_new_unchecked_out_of_range() { - let id = StandardId::MAX.as_raw() + 1; + let id = StandardId::MAX_RAW + 1; assert_eq!(unsafe { StandardId::new_unchecked(id) }, StandardId(id)); } @@ -189,12 +213,12 @@ mod tests { #[test] fn extended_id_new_out_of_range() { - assert_eq!(ExtendedId::new(ExtendedId::MAX.as_raw() + 1), None); + assert_eq!(ExtendedId::new(ExtendedId::MAX_RAW + 1), None); } #[test] fn extended_id_new_unchecked_out_of_range() { - let id = ExtendedId::MAX.as_raw() + 1; + let id = ExtendedId::MAX_RAW + 1; assert_eq!(unsafe { ExtendedId::new_unchecked(id) }, ExtendedId(id)); } @@ -216,4 +240,32 @@ mod tests { assert!(Id::Extended(ExtendedId((1 << 11) - 1)) < Id::Standard(StandardId(1))); assert!(Id::Standard(StandardId(1)) < Id::Extended(ExtendedId::MAX)); } + + #[test] + fn id_new() { + let id = Id::new_standard(StandardId::MAX_RAW).unwrap(); + assert!(id.is_standard()); + assert!(!id.is_extended()); + match id { + Id::Standard(id) => assert_eq!(StandardId::MAX, id), + _ => assert!(false), + } + + let id = Id::new_extended(ExtendedId::MAX_RAW).unwrap(); + assert!(!id.is_standard()); + assert!(id.is_extended()); + match id { + Id::Extended(id) => assert_eq!(ExtendedId::MAX, id), + _ => assert!(false), + } + } + + #[test] + fn id_raw() { + let id = StandardId::new(StandardId::MAX_RAW).unwrap(); + assert_eq!(StandardId::MAX_RAW, id.as_raw()); + + let id = ExtendedId::new(ExtendedId::MAX_RAW).unwrap(); + assert_eq!(ExtendedId::MAX_RAW, id.as_raw()); + } }