@@ -253,6 +253,23 @@ impl PartialEq for DevicePathNode {
253253 }
254254}
255255
256+ impl < ' a > TryFrom < & [ u8 ] > for & ' a DevicePathNode {
257+ type Error = ByteConversionError ;
258+
259+ fn try_from ( bytes : & [ u8 ] ) -> Result < Self , Self :: Error > {
260+ if mem:: size_of :: < DevicePathHeader > ( ) <= bytes. len ( ) {
261+ let dp: & DevicePathNode ;
262+ unsafe {
263+ dp = DevicePathNode :: from_ffi_ptr ( bytes. as_ptr ( ) . cast ( ) ) ;
264+ }
265+ if dp. length ( ) as usize <= bytes. len ( ) {
266+ return Ok ( dp) ;
267+ }
268+ }
269+ Err ( ByteConversionError :: InvalidLength )
270+ }
271+ }
272+
256273/// A single device path instance that ends with either an [`END_INSTANCE`]
257274/// or [`END_ENTIRE`] node. Use [`DevicePath::instance_iter`] to get the
258275/// path instances in a [`DevicePath`].
@@ -729,6 +746,15 @@ impl DeviceSubType {
729746 pub const END_ENTIRE : DeviceSubType = DeviceSubType ( 0xff ) ;
730747}
731748
749+ /// Error returned when atempting to convert from a `&[u8]` to a
750+ /// [`DevicePath`] type using:
751+ /// - [`DevicePathNode::try_from`](struct.DevicePathNode.html#method.try_from)
752+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
753+ pub enum ByteConversionError {
754+ /// The length of the given slice is not valid for its [`DevicePath`] type.
755+ InvalidLength ,
756+ }
757+
732758/// Error returned when converting from a [`DevicePathNode`] to a more
733759/// specific node type.
734760#[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
@@ -954,4 +980,33 @@ mod tests {
954980 let owned_dp_ref = & * owned_dp;
955981 assert_eq ! ( owned_dp_ref, dp)
956982 }
983+
984+ #[ test]
985+ fn test_device_path_from_bytes ( ) {
986+ let mut raw_data = Vec :: new ( ) ;
987+ let node = [ 0xa0 , 0xb0 ] ;
988+ let node_data = & [ 10 , 11 ] ;
989+ let mut dp;
990+
991+ // Raw data is less than size of a [`DevicePathNode`].
992+ raw_data. push ( node[ 0 ] ) ;
993+ dp = <& DevicePathNode >:: try_from ( raw_data. as_slice ( ) ) ;
994+ assert ! ( dp. is_err( ) ) ;
995+
996+ // Raw data is long enough to hold a [`DevicePathNode`].
997+ raw_data. push ( node[ 1 ] ) ;
998+ raw_data. extend (
999+ u16:: try_from ( mem:: size_of :: < DevicePathHeader > ( ) + node_data. len ( ) )
1000+ . unwrap ( )
1001+ . to_le_bytes ( ) ,
1002+ ) ;
1003+ raw_data. extend ( node_data) ;
1004+ dp = <& DevicePathNode >:: try_from ( raw_data. as_slice ( ) ) ;
1005+ assert ! ( dp. is_ok( ) ) ;
1006+
1007+ // [`DevicePathNode`] data length exceeds the raw_data slice.
1008+ raw_data[ 2 ] += 1 ;
1009+ dp = <& DevicePathNode >:: try_from ( raw_data. as_slice ( ) ) ;
1010+ assert ! ( dp. is_err( ) ) ;
1011+ }
9571012}
0 commit comments