stable_hash/
macros.rs

1/// Implements StableHash. This macro supports two forms:
2/// Struct { field1, field2, ... } and Tuple(transparent). Each field supports
3/// an optional modifier. For example: Tuple(transparent: AsBytes)
4///
5/// This API is unstable and will likely be modified for a 1.0 release.
6/// It's just a stub to cover some common cases.
7#[macro_export]
8macro_rules! impl_stable_hash {
9    ($T:ident$(<$lt:lifetime>)? {$($field:ident$(:$e:path)?),*}) => {
10        impl $crate::StableHash for $T$(<$lt>)? {
11            // This suppressed warning is for the final index + 1, which is unused
12            // in the next "iteration of the loop"
13            #[allow(unused_assignments)]
14            fn stable_hash<H: $crate::StableHasher>(&self, field_address: H::Addr, state: &mut H) {
15                // Destructuring ensures we have all of the fields. If a field is added to the struct,
16                // it must be added to the macro or it will fail to compile.
17                let $T { $($field,)* } = self;
18                let mut index = 0;
19                $(
20                    // We might need to "massage" the value, for example, to wrap
21                    // it in AsBytes. So we provide a way to inject those.
22                    $(let $field = $e($field);)?
23                    $crate::StableHash::stable_hash(&$field, $crate::FieldAddress::child(&field_address, index), state);
24                    index += 1;
25                )*
26            }
27        }
28    };
29    ($T:ident$(<$lt:lifetime>)? (transparent$(:$e:path)?)) => {
30        impl $crate::StableHash for $T$(<$lt>)? {
31            #[allow(unused_assignments)]
32            fn stable_hash<H: $crate::StableHasher>(&self, field_address: H::Addr, state: &mut H) {
33                let Self(transparent) = self;
34                $(let transparent = $e(transparent);)?
35                $crate::StableHash::stable_hash(&transparent, field_address, state);
36            }
37        }
38    };
39}