1use crate::prelude::*;
2use crate::verification::*;
3
4pub struct AsBytes<'a>(pub &'a [u8]);
8
9impl StableHash for AsBytes<'_> {
10 fn stable_hash<H: StableHasher>(&self, field_address: H::Addr, state: &mut H) {
11 profile_method!(stable_hash);
12
13 if !self.0.is_empty() {
14 state.write(field_address, self.0)
15 }
16 }
17}
18
19fn trim_zeros(bytes: &[u8]) -> &[u8] {
20 profile_fn!(trim_zeros);
21
22 let mut end = bytes.len();
23 while end != 0 && bytes[end - 1] == 0 {
24 end -= 1;
25 }
26 &bytes[0..end]
27}
28
29pub struct AsInt<'a> {
35 pub is_negative: bool,
36 pub little_endian: &'a [u8],
37}
38
39impl StableHash for AsInt<'_> {
40 fn stable_hash<H: StableHasher>(&self, field_address: H::Addr, state: &mut H) {
41 profile_method!(stable_hash);
42
43 if self.is_negative {
48 state.write(field_address.child(0), &[]);
49 }
50 let canon = trim_zeros(self.little_endian);
51 if !canon.is_empty() {
52 state.write(field_address, canon);
53 }
54 }
55}
56
57pub(crate) fn generic_stable_hash<T: StableHash, H: StableHasher>(value: &T) -> H::Out {
58 let mut hasher = H::new();
59 value.stable_hash(FieldAddress::root(), &mut hasher);
60 hasher.finish()
61}
62
63pub fn check_for_child_errors<T: StableHash>(value: &T) -> Result<(), (ChildErr, Vec<PathItem>)> {
65 profile_fn!(check_for_child_errors);
66 generic_stable_hash::<T, crate::verification::ChildChecker>(value)
67}