@@ -24,8 +24,6 @@ pub use hubpack::{SerializedSize, deserialize, serialize};
2424pub use mgs_to_sp:: * ;
2525pub use sp_to_mgs:: * ;
2626
27- use crate :: nullstr:: NullStr ;
28-
2927/// The SP should detach an attached serial console client if it has not heard
3028/// from it in this long (based on the assumption that it has gone away without
3129/// sending an explicit detach).
@@ -284,16 +282,23 @@ impl From<UpdateId> for uuid::Uuid {
284282mod nullstr {
285283 use super :: * ;
286284
285+ /// A reusable type that implements a fixed-max-capacity string where the
286+ /// unused capacity is always guaranteed to be zero-filled. This is used
287+ /// for strings sent over the wire using [`hubpack`], which requires fixed-size
288+ /// items.
289+ ///
290+ /// It is not intended for this type to be part of the public API, see
291+ /// [`SpComponent`] for usage guidance.
287292 #[ derive( Clone , Copy , PartialEq , Eq , Hash , SerializedSize ) ]
288293 pub struct NullStr < const N : usize > {
289294 contents : [ u8 ; N ] ,
290295 }
291296
292297 impl < const N : usize > NullStr < N > {
293- /// Interpret the component name as a human-readable string.
298+ /// Interpret the content as a human-readable string.
294299 ///
295- /// Our current expectation of component names is that this should never
296- /// fail (i.e., we're always storing component names as human-readable
300+ /// Our current expectation of contents is that this should never
301+ /// fail (i.e., we're always storing contents as human-readable
297302 /// strings), but because we reconstitute components from network messages
298303 /// we still need to check.
299304 pub fn as_str ( & self ) -> Option < & str > {
@@ -470,7 +475,10 @@ mod nullstr {
470475}
471476
472477/// Identifier for a single component managed by an SP.
473- #[ derive( Clone , Copy , PartialEq , Eq , Hash , SerializedSize ) ]
478+ #[ derive(
479+ Clone , Copy , PartialEq , Eq , Hash , SerializedSize , Serialize , Deserialize ,
480+ ) ]
481+ #[ serde( transparent) ]
474482pub struct SpComponent {
475483 /// The ID of the component.
476484 ///
@@ -483,34 +491,6 @@ pub struct SpComponent {
483491 id : nullstr:: NullStr < { Self :: MAX_ID_LENGTH } > ,
484492}
485493
486- impl Serialize for SpComponent {
487- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
488- where
489- S : serde:: Serializer ,
490- {
491- // TODO(AJM): I don't think we can just derive deserialize here because I think the old impl
492- // served as an implicit "flatten", and we don't want to introduce another level of nesting.
493- nullstr:: NullStr :: < { Self :: MAX_ID_LENGTH } > :: serialize (
494- & self . id , serializer,
495- )
496- }
497- }
498-
499- impl < ' de > Deserialize < ' de > for SpComponent {
500- fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
501- where
502- D : serde:: Deserializer < ' de > ,
503- {
504- // TODO(AJM): I don't think we can just derive deserialize here because I think the old impl
505- // served as an implicit "flatten", and we don't want to introduce another level of nesting.
506- Ok ( Self {
507- id : NullStr :: < { Self :: MAX_ID_LENGTH } > :: deserialize :: < D > (
508- deserializer,
509- ) ?,
510- } )
511- }
512- }
513-
514494impl core:: fmt:: Display for SpComponent {
515495 fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
516496 self . id . fmt ( f)
@@ -638,42 +618,15 @@ impl TryFrom<&str> for SpComponent {
638618 }
639619}
640620
641- // -----
642-
643621/// Identifier for a single power rail.
644- #[ derive( Clone , Copy , PartialEq , Eq , Hash , SerializedSize ) ]
622+ #[ derive(
623+ Clone , Copy , PartialEq , Eq , Hash , SerializedSize , Serialize , Deserialize ,
624+ ) ]
625+ #[ serde( transparent) ]
645626pub struct PowerRailName {
646627 name : nullstr:: NullStr < { Self :: MAX_NAME_LENGTH } > ,
647628}
648629
649- impl Serialize for PowerRailName {
650- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
651- where
652- S : serde:: Serializer ,
653- {
654- // TODO(AJM): I don't think we can just derive deserialize here because I think the old impl
655- // served as an implicit "flatten", and we don't want to introduce another level of nesting.
656- nullstr:: NullStr :: < { Self :: MAX_NAME_LENGTH } > :: serialize (
657- & self . name , serializer,
658- )
659- }
660- }
661-
662- impl < ' de > Deserialize < ' de > for PowerRailName {
663- fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
664- where
665- D : serde:: Deserializer < ' de > ,
666- {
667- // TODO(AJM): I don't think we can just derive deserialize here because I think the old impl
668- // served as an implicit "flatten", and we don't want to introduce another level of nesting.
669- Ok ( Self {
670- name : NullStr :: < { Self :: MAX_NAME_LENGTH } > :: deserialize :: < D > (
671- deserializer,
672- ) ?,
673- } )
674- }
675- }
676-
677630impl core:: fmt:: Display for PowerRailName {
678631 fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
679632 self . name . fmt ( f)
@@ -701,7 +654,7 @@ impl PowerRailName {
701654 /// This function should only be used in const contexts when the caller
702655 /// knows the component is valid (e.g., one of this type's associated
703656 /// constants); for component names parsed or constructed at runtime, prefer
704- /// [`SpComponent ::as_str()`] which performs runtime validation.
657+ /// [`PowerRailName ::as_str()`] which performs runtime validation.
705658 #[ inline]
706659 pub const fn const_as_str ( & self ) -> & str {
707660 self . name . const_as_str ( )
@@ -730,8 +683,6 @@ impl fmt::Debug for PowerRailName {
730683 }
731684}
732685
733- // -----
734-
735686/// Minimum guaranteed space for trailing data in a single packet.
736687///
737688/// Depending on the [`Message`] payload, there may be more space for trailing
@@ -850,4 +801,33 @@ mod tests {
850801 ( component, & [ ] as & [ u8 ] )
851802 ) ;
852803 }
804+
805+ #[ test]
806+ fn test_human_readable_power_rail ( ) {
807+ let rail = const { PowerRailName :: from_const ( "V0P96_NIC_VDD_A0HP" ) } ;
808+ let expected_value =
809+ serde_json:: Value :: String ( "V0P96_NIC_VDD_A0HP" . to_string ( ) ) ;
810+
811+ assert_eq ! ( serde_json:: to_value( rail) . unwrap( ) , expected_value) ;
812+ assert_eq ! (
813+ serde_json:: from_value:: <PowerRailName >( expected_value) . unwrap( ) ,
814+ rail
815+ ) ;
816+ }
817+
818+ #[ test]
819+ fn test_non_human_readable_power_rail ( ) {
820+ let rail = const { PowerRailName :: from_const ( "V0P96_NIC_VDD_A0HP" ) } ;
821+ let expected_value = rail. name ;
822+
823+ let mut out = [ 0 ; PowerRailName :: MAX_SIZE ] ;
824+ let n = hubpack:: serialize ( & mut out, & rail) . unwrap ( ) ;
825+ assert_eq ! ( & out[ ..n] , expected_value. contents( ) ) ;
826+
827+ assert_eq ! (
828+ hubpack:: deserialize:: <PowerRailName >( expected_value. contents( ) )
829+ . unwrap( ) ,
830+ ( rail, & [ ] as & [ u8 ] )
831+ ) ;
832+ }
853833}
0 commit comments