midnight_base_crypto/fab/
alignments.rs1use crate::fab::{AlignedValue, AlignedValueSlice, Alignment, AlignmentAtom};
18use crate::hash::{HashOutput, PERSISTENT_HASH_BYTES as PHB};
19
20pub trait Aligned {
23 fn alignment() -> Alignment;
25}
26
27pub trait DynAligned {
30 fn dyn_alignment(&self) -> Alignment;
32}
33
34impl<T: Aligned> DynAligned for T {
35 fn dyn_alignment(&self) -> Alignment {
36 T::alignment()
37 }
38}
39
40macro_rules! tuple_aligned {
41 () => {
42 impl Aligned for () {
43 fn alignment() -> Alignment {
44 Alignment(Vec::new())
45 }
46 }
47 };
48 ($a:ident$(, $as:ident)*) => {
49 impl<$a: Aligned$(, $as: Aligned)*> Aligned for ($a$(, $as)* ,) {
50 fn alignment() -> Alignment {
51 Alignment::concat([&$a::alignment()$(, &$as::alignment())*])
52 }
53 }
54
55 tuple_aligned!($($as),*);
56 }
57}
58
59tuple_aligned!(A, B, C, D, E, F, G, H, I, J, K);
60
61macro_rules! fixed_bytes_aligned {
62 ($($ty:ty; $size:expr_2021),*) => {
63 $(
64 impl Aligned for $ty {
65 fn alignment() -> Alignment {
66 Alignment::singleton(AlignmentAtom::Bytes { length: $size as u32 })
67 }
68 }
69 )*
70 }
71}
72
73fixed_bytes_aligned!(
74 HashOutput; PHB,
75 bool; 1,
76 u8; 1,
77 u16; 2,
78 u32; 4,
79 u64; 8,
80 u128; 16
81);
82
83impl<const N: usize> Aligned for [u8; N] {
84 fn alignment() -> Alignment {
85 Alignment::singleton(AlignmentAtom::Bytes { length: N as u32 })
86 }
87}
88
89impl Aligned for &[u8] {
90 fn alignment() -> Alignment {
91 Alignment::singleton(AlignmentAtom::Compress)
92 }
93}
94
95impl Aligned for Vec<u8> {
96 fn alignment() -> Alignment {
97 Alignment::singleton(AlignmentAtom::Compress)
98 }
99}
100
101impl<T: Aligned> Aligned for Option<T> {
102 fn alignment() -> Alignment {
103 Alignment::concat([&bool::alignment(), &T::alignment()])
104 }
105}
106
107impl Alignment {
108 pub fn option_of(&self) -> Alignment {
111 Alignment::concat([&bool::alignment(), self])
112 }
113}
114
115impl DynAligned for AlignedValue {
116 fn dyn_alignment(&self) -> Alignment {
117 self.alignment.clone()
118 }
119}
120
121impl DynAligned for AlignedValueSlice<'_> {
122 fn dyn_alignment(&self) -> Alignment {
123 self.1.clone()
124 }
125}