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