@@ -62,3 +62,48 @@ macro_rules! union_has_padding {
62
62
false $( || core:: mem:: size_of:: <$t>( ) != core:: mem:: size_of:: <$ts>( ) ) *
63
63
} ;
64
64
}
65
+
66
+ #[ doc( hidden) ]
67
+ pub use project:: project as __project;
68
+
69
+ /// Implements `TryFromBytes` for a struct type by delegating to existing
70
+ /// implementations for each of its fields.
71
+ ///
72
+ /// # Safety
73
+ ///
74
+ /// `$ty` must be a struct type, `$f` must list every field's name, and `$f_ty`
75
+ /// must be the correct types for those fields.
76
+ #[ doc( hidden) ] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
77
+ #[ macro_export]
78
+ macro_rules! impl_try_from_bytes_for_struct {
79
+ ( $ty: ty { $( $f: tt: $f_ty: ty) ,* } $( => $validation_method: ident) ?) => {
80
+ // SAFETY: The caller promises that all fields are listed with their
81
+ // correct types. We validate that every field is valid, which is the
82
+ // only requirement for the entire struct to be valid. Thus, we
83
+ // correctly implement `is_bit_valid` as required by the trait's safety
84
+ // documentation.
85
+ #[ allow( unused_qualifications) ]
86
+ unsafe impl zerocopy:: TryFromBytes for $ty {
87
+ fn is_bit_valid( bytes: & zerocopy:: MaybeValid <Self >) -> bool {
88
+ true $( && {
89
+ let f: & zerocopy:: MaybeValid <$f_ty>
90
+ = zerocopy:: derive_util:: __project!( & bytes. $f) ;
91
+ zerocopy:: TryFromBytes :: is_bit_valid( f)
92
+ } ) *
93
+ $( && {
94
+ // SAFETY: We just validated that all of the struct's fields
95
+ // are valid, which means that the struct itself is valid.
96
+ // That is the only precondition of `assume_valid_ref`.
97
+ let slf = unsafe { bytes. assume_valid_ref( ) } ;
98
+ // TODO: What about interior mutability? One approach would
99
+ // be to have the validation method operate on a
100
+ // `#[repr(transparent)]` `Freeze` container that implements
101
+ // `Projectable`. If we eventually get a `Freeze` or
102
+ // `NoCell` trait, that container could implement `Deref`
103
+ // for types which don't contain any cells.
104
+ slf. $validation_method( )
105
+ } ) ?
106
+ }
107
+ }
108
+ }
109
+ }
0 commit comments