libfdt: Make Phandle::new() const

Decouple the definition of valid phandle values enforced by
Phandle::new() from the FdtError type and allow callers to generate a
libfdt::Result<Phandle> by implementing the standard TryFrom trait.

This was initially intended to be used in const expressions e.g.

    const PHANDLE: Phandle = Phandle::new().unwrap();

but this will actually required stabilization of const_option first. For
now, the constructor is at least marked const.

Test: atest liblibfdt.integration_test
Change-Id: Ib9893595b1dd3972782e488f087fec2872679293
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index d800c13..0a97141 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -505,12 +505,18 @@
 pub struct Phandle(u32);
 
 impl Phandle {
+    /// Minimum valid value for device tree phandles.
+    pub const MIN: Self = Self(1);
+    /// Maximum valid value for device tree phandles.
+    pub const MAX: Self = Self(libfdt_bindgen::FDT_MAX_PHANDLE);
+
     /// Creates a new Phandle
-    pub fn new(value: u32) -> Result<Self> {
-        if value == 0 || value > libfdt_bindgen::FDT_MAX_PHANDLE {
-            return Err(FdtError::BadPhandle);
+    pub const fn new(value: u32) -> Option<Self> {
+        if Self::MIN.0 <= value && value <= Self::MAX.0 {
+            Some(Self(value))
+        } else {
+            None
         }
-        Ok(Self(value))
     }
 }
 
@@ -520,6 +526,14 @@
     }
 }
 
+impl TryFrom<u32> for Phandle {
+    type Error = FdtError;
+
+    fn try_from(value: u32) -> Result<Self> {
+        Self::new(value).ok_or(FdtError::BadPhandle)
+    }
+}
+
 /// Mutable FDT node.
 pub struct FdtNodeMut<'a> {
     fdt: &'a mut Fdt,
@@ -964,7 +978,7 @@
         let ret = unsafe { libfdt_bindgen::fdt_find_max_phandle(self.as_ptr(), &mut phandle) };
 
         fdt_err_expect_zero(ret)?;
-        Phandle::new(phandle)
+        phandle.try_into()
     }
 
     /// Returns a node with the phandle
diff --git a/libs/libfdt/tests/api_test.rs b/libs/libfdt/tests/api_test.rs
index 61503eb..bd2b306 100644
--- a/libs/libfdt/tests/api_test.rs
+++ b/libs/libfdt/tests/api_test.rs
@@ -142,10 +142,30 @@
 
 #[test]
 fn phandle_new() {
-    let phandle_u32 = 0x55;
-    let phandle = Phandle::new(phandle_u32).unwrap();
+    let valid_phandles = [
+        u32::from(Phandle::MIN),
+        u32::from(Phandle::MIN).checked_add(1).unwrap(),
+        0x55,
+        u32::from(Phandle::MAX).checked_sub(1).unwrap(),
+        u32::from(Phandle::MAX),
+    ];
 
-    assert_eq!(u32::from(phandle), phandle_u32);
+    for value in valid_phandles {
+        let phandle = Phandle::new(value).unwrap();
+
+        assert_eq!(value.try_into(), Ok(phandle));
+        assert_eq!(u32::from(phandle), value);
+    }
+
+    let bad_phandles = [
+        u32::from(Phandle::MIN).checked_sub(1).unwrap(),
+        u32::from(Phandle::MAX).checked_add(1).unwrap(),
+    ];
+
+    for value in bad_phandles {
+        assert_eq!(Phandle::new(value), None);
+        assert_eq!(Phandle::try_from(value), Err(FdtError::BadPhandle));
+    }
 }
 
 #[test]