reth_trie_common/
nibbles.rs1use alloc::vec::Vec;
2use derive_more::Deref;
3pub use nybbles::Nibbles;
4
5#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, derive_more::Index)]
7#[cfg_attr(any(test, feature = "serde"), derive(serde::Serialize, serde::Deserialize))]
8#[cfg_attr(feature = "test-utils", derive(arbitrary::Arbitrary))]
9pub struct StoredNibbles(pub Nibbles);
10
11impl From<Nibbles> for StoredNibbles {
12 #[inline]
13 fn from(value: Nibbles) -> Self {
14 Self(value)
15 }
16}
17
18impl From<Vec<u8>> for StoredNibbles {
19 #[inline]
20 fn from(value: Vec<u8>) -> Self {
21 Self(Nibbles::from_nibbles_unchecked(value))
22 }
23}
24
25#[cfg(any(test, feature = "reth-codec"))]
26impl reth_codecs::Compact for StoredNibbles {
27 fn to_compact<B>(&self, buf: &mut B) -> usize
28 where
29 B: bytes::BufMut + AsMut<[u8]>,
30 {
31 for i in self.0.iter() {
32 buf.put_u8(i);
33 }
34 self.0.len()
35 }
36
37 fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
38 use bytes::Buf;
39
40 let nibbles = &buf[..len];
41 buf.advance(len);
42 (Self(Nibbles::from_nibbles_unchecked(nibbles)), buf)
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deref)]
48#[cfg_attr(any(test, feature = "serde"), derive(serde::Serialize, serde::Deserialize))]
49#[cfg_attr(feature = "test-utils", derive(arbitrary::Arbitrary))]
50pub struct StoredNibblesSubKey(pub Nibbles);
51
52impl From<Nibbles> for StoredNibblesSubKey {
53 #[inline]
54 fn from(value: Nibbles) -> Self {
55 Self(value)
56 }
57}
58
59impl From<Vec<u8>> for StoredNibblesSubKey {
60 #[inline]
61 fn from(value: Vec<u8>) -> Self {
62 Self(Nibbles::from_nibbles_unchecked(value))
63 }
64}
65
66impl From<StoredNibblesSubKey> for Nibbles {
67 #[inline]
68 fn from(value: StoredNibblesSubKey) -> Self {
69 value.0
70 }
71}
72
73#[cfg(any(test, feature = "reth-codec"))]
74impl reth_codecs::Compact for StoredNibblesSubKey {
75 fn to_compact<B>(&self, buf: &mut B) -> usize
76 where
77 B: bytes::BufMut + AsMut<[u8]>,
78 {
79 assert!(self.0.len() <= 64);
80
81 for i in self.0.iter() {
83 buf.put_u8(i);
84 }
85 static ZERO: &[u8; 64] = &[0; 64];
86 buf.put_slice(&ZERO[self.0.len()..]);
87
88 buf.put_u8(self.0.len() as u8);
89 64 + 1
90 }
91
92 fn from_compact(buf: &[u8], _len: usize) -> (Self, &[u8]) {
93 let len = buf[64] as usize;
94 (Self(Nibbles::from_nibbles_unchecked(&buf[..len])), &buf[65..])
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use bytes::BytesMut;
102 use reth_codecs::Compact;
103
104 #[test]
105 fn test_stored_nibbles_from_nibbles() {
106 let nibbles = Nibbles::from_nibbles_unchecked(vec![0x02, 0x04, 0x06]);
107 let stored = StoredNibbles::from(nibbles);
108 assert_eq!(stored.0, nibbles);
109 }
110
111 #[test]
112 fn test_stored_nibbles_from_vec() {
113 let bytes = vec![0x02, 0x04, 0x06];
114 let stored = StoredNibbles::from(bytes.clone());
115 assert_eq!(stored.0.to_vec(), bytes);
116 }
117
118 #[test]
119 fn test_stored_nibbles_to_compact() {
120 let stored = StoredNibbles::from(vec![0x02, 0x04]);
121 let mut buf = BytesMut::with_capacity(10);
122 let len = stored.to_compact(&mut buf);
123 assert_eq!(len, 2);
124 assert_eq!(buf, &vec![0x02, 0x04][..]);
125 }
126
127 #[test]
128 fn test_stored_nibbles_from_compact() {
129 let buf = vec![0x02, 0x04, 0x06];
130 let (stored, remaining) = StoredNibbles::from_compact(&buf, 2);
131 assert_eq!(stored.0.to_vec(), vec![0x02, 0x04]);
132 assert_eq!(remaining, &[0x06]);
133 }
134
135 #[test]
136 fn test_stored_nibbles_subkey_to_compact() {
137 let subkey = StoredNibblesSubKey::from(vec![0x02, 0x04]);
138 let mut buf = BytesMut::with_capacity(65);
139 let len = subkey.to_compact(&mut buf);
140 assert_eq!(len, 65);
141 assert_eq!(buf[..2], [0x02, 0x04]);
142 assert_eq!(buf[64], 2); }
144
145 #[test]
146 fn test_stored_nibbles_subkey_from_compact() {
147 let mut buf = vec![0x02, 0x04];
148 buf.resize(65, 0);
149 buf[64] = 2;
150 let (subkey, remaining) = StoredNibblesSubKey::from_compact(&buf, 65);
151 assert_eq!(subkey.0.to_vec(), vec![0x02, 0x04]);
152 assert_eq!(remaining, &[] as &[u8]);
153 }
154
155 #[test]
156 fn test_serialization_stored_nibbles() {
157 let stored = StoredNibbles::from(vec![0x02, 0x04]);
158 let serialized = serde_json::to_string(&stored).unwrap();
159 let deserialized: StoredNibbles = serde_json::from_str(&serialized).unwrap();
160 assert_eq!(stored, deserialized);
161 }
162
163 #[test]
164 fn test_serialization_stored_nibbles_subkey() {
165 let subkey = StoredNibblesSubKey::from(vec![0x02, 0x04]);
166 let serialized = serde_json::to_string(&subkey).unwrap();
167 let deserialized: StoredNibblesSubKey = serde_json::from_str(&serialized).unwrap();
168 assert_eq!(subkey, deserialized);
169 }
170}