1use rlp::{RlpStream, Rlp};
4use std::cmp::min;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum Nibble {
9 N0, N1, N2, N3, N4, N5, N6, N7,
10 N8, N9, N10, N11, N12, N13, N14, N15,
11}
12
13impl From<usize> for Nibble {
14 fn from(val: usize) -> Nibble {
15 match val {
16 0 => Nibble::N0, 1 => Nibble::N1, 2 => Nibble::N2, 3 =>
17 Nibble::N3, 4 => Nibble::N4, 5 => Nibble::N5, 6 =>
18 Nibble::N6, 7 => Nibble::N7, 8 => Nibble::N8, 9 =>
19 Nibble::N9, 10 => Nibble::N10, 11 => Nibble::N11, 12 =>
20 Nibble::N12, 13 => Nibble::N13, 14 => Nibble::N14, 15 =>
21 Nibble::N15, _ => panic!(),
22 }
23 }
24}
25
26impl Into<usize> for Nibble {
27 fn into(self) -> usize {
28 match self {
29 Nibble::N0 => 0, Nibble::N1 => 1, Nibble::N2 => 2,
30 Nibble::N3 => 3, Nibble::N4 => 4, Nibble::N5 => 5,
31 Nibble::N6 => 6, Nibble::N7 => 7, Nibble::N8 => 8,
32 Nibble::N9 => 9, Nibble::N10 => 10, Nibble::N11 => 11,
33 Nibble::N12 => 12, Nibble::N13 => 13, Nibble::N14 => 14,
34 Nibble::N15 => 15,
35 }
36 }
37}
38
39impl From<u8> for Nibble {
40 fn from(val: u8) -> Nibble {
41 match val {
42 0 => Nibble::N0, 1 => Nibble::N1, 2 => Nibble::N2, 3 =>
43 Nibble::N3, 4 => Nibble::N4, 5 => Nibble::N5, 6 =>
44 Nibble::N6, 7 => Nibble::N7, 8 => Nibble::N8, 9 =>
45 Nibble::N9, 10 => Nibble::N10, 11 => Nibble::N11, 12 =>
46 Nibble::N12, 13 => Nibble::N13, 14 => Nibble::N14, 15 =>
47 Nibble::N15, _ => panic!(),
48 }
49 }
50}
51
52impl Into<u8> for Nibble {
53 fn into(self) -> u8 {
54 match self {
55 Nibble::N0 => 0, Nibble::N1 => 1, Nibble::N2 => 2,
56 Nibble::N3 => 3, Nibble::N4 => 4, Nibble::N5 => 5,
57 Nibble::N6 => 6, Nibble::N7 => 7, Nibble::N8 => 8,
58 Nibble::N9 => 9, Nibble::N10 => 10, Nibble::N11 => 11,
59 Nibble::N12 => 12, Nibble::N13 => 13, Nibble::N14 => 14,
60 Nibble::N15 => 15,
61 }
62 }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
67pub enum NibbleType {
68 Leaf,
69 Extension
70}
71
72pub type NibbleVec = Vec<Nibble>;
74pub type NibbleSlice<'a> = &'a [Nibble];
76
77pub fn from_key(key: &[u8]) -> NibbleVec {
79 let mut vec = NibbleVec::new();
80
81 for i in 0..(key.len()*2) {
82 if i & 1 == 0 { vec.push(((key[i / 2] & 0xf0) >> 4).into());
84 } else {
85 vec.push((key[i / 2] & 0x0f).into());
86 }
87 }
88
89 vec
90}
91
92pub fn into_key(nibble: NibbleSlice) -> Vec<u8> {
94 let mut ret = Vec::new();
95
96 for i in 0..nibble.len() {
97 if i & 1 == 0 { let value: u8 = nibble[i].into();
99 ret.push(value << 4);
100 } else {
101 let value: u8 = nibble[i].into();
102 ret[i / 2] |= value;
103 }
104 }
105
106 ret
107}
108
109pub fn decode(rlp: &Rlp) -> (NibbleVec, NibbleType) {
111 let mut vec = NibbleVec::new();
112
113 let data = rlp.data();
114 let start_odd = if data[0] & 0b00010000 == 0b00010000 { true } else { false };
115 let start_index = if start_odd { 1 } else { 2 };
116 let is_leaf = data[0] & 0b00100000 == 0b00100000;
117
118 let len = data.len() * 2;
119
120 for i in start_index..len {
121 if i & 1 == 0 { vec.push(((data[i / 2] & 0xf0) >> 4).into());
123 } else {
124 vec.push((data[i / 2] & 0x0f).into());
125 }
126 }
127
128 (vec, if is_leaf { NibbleType::Leaf } else { NibbleType::Extension })
129}
130
131pub fn encode(vec: NibbleSlice, typ: NibbleType, s: &mut RlpStream) {
133 let mut ret: Vec<u8> = Vec::new();
134
135 if vec.len() & 1 == 0 { ret.push(0b00000000);
137
138 for i in 0..vec.len() {
139 if i & 1 == 0 {
140 let v: u8 = vec[i].into();
141 ret.push(v << 4);
142 } else {
143 let end = ret.len() - 1;
144 let v: u8 = vec[i].into();
145 ret[end] |= v;
146 }
147 }
148 } else {
149 ret.push(0b00010000);
150
151 for i in 0..vec.len() {
152 if i & 1 == 0 {
153 let end = ret.len() - 1;
154 let v: u8 = vec[i].into();
155 ret[end] |= v;
156 } else {
157 let v: u8 = vec[i].into();
158 ret.push(v << 4);
159 }
160 }
161 }
162
163 ret[0] |= match typ {
164 NibbleType::Leaf => 0b00100000,
165 NibbleType::Extension => 0b00000000
166 };
167
168 s.append(&ret);
169}
170
171pub fn common<'a, 'b>(a: NibbleSlice<'a>, b: NibbleSlice<'b>) -> NibbleSlice<'a> {
173 let mut common_len = 0;
174
175 for i in 0..min(a.len(), b.len()) {
176 if a[i] == b[i] {
177 common_len += 1;
178 } else {
179 break;
180 }
181 }
182
183 &a[0..common_len]
184}
185
186pub fn common_with_sub<'a, 'b>(
188 a: NibbleSlice<'a>, b: NibbleSlice<'b>
189) -> (NibbleSlice<'a>, NibbleVec, NibbleVec) {
190 let common = common(a, b);
191 let asub = a[common.len()..].into();
192 let bsub = b[common.len()..].into();
193
194 (common, asub, bsub)
195}
196
197pub fn common_all<'a, T: Iterator<Item=NibbleSlice<'a>>>(mut iter: T) -> NibbleSlice<'a> {
199 let first = match iter.next() {
200 Some(val) => val,
201 None => return &[],
202 };
203 let second = match iter.next() {
204 Some(val) => val,
205 None => return first,
206 };
207
208 let mut common_cur = common(first, second);
209 for key in iter {
210 common_cur = common(common_cur, key);
211 }
212
213 common_cur
214}
215
216#[cfg(test)]
217mod tests {
218 use super::*;
219
220 #[test]
221 fn from_into_key() {
222 let key = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 244, 233, 188];
223
224 assert_eq!(key, into_key(&from_key(&key)));
225 }
226}