From c0eb5177d058aafccd05477b14eb245768f4272a Mon Sep 17 00:00:00 2001
From: fpagliughi <fpagliughi@mindspring.com>
Date: Sun, 4 Dec 2022 15:49:50 -0500
Subject: [PATCH] Added impl to Id make it more directly usable. Added MAX_RAW
 to StandardId and ExtendedId (private).

---
 embedded-can/src/id.rs | 76 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 64 insertions(+), 12 deletions(-)

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<Self> {
-        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<Self> {
-        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<Self> {
+        Some(Id::from(StandardId::new(raw)?))
+    }
+
+    /// Creates a CAN identifier as an extended ID.
+    pub fn new_extended(raw: u32) -> Option<Self> {
+        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());
+    }
 }