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