1use tetsy_hash_db::Hasher;
16use crate::nibble::{self, NibbleSlice};
17use crate::nibble::nibble_ops;
18use crate::node_codec::NodeCodec;
19
20use crate::rstd::{borrow::Borrow, ops::Range};
21
22pub type NodeKey = (usize, nibble::BackingByteVec);
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub enum NodeHandle<'a> {
29 Hash(&'a [u8]),
30 Inline(&'a [u8]),
31}
32
33pub fn decode_hash<H: Hasher>(data: &[u8]) -> Option<H::Out> {
35 if data.len() != H::LENGTH {
36 return None;
37 }
38 let mut hash = H::Out::default();
39 hash.as_mut().copy_from_slice(data);
40 Some(hash)
41}
42
43#[derive(Eq, PartialEq, Clone)]
45#[cfg_attr(feature = "std", derive(Debug))]
46pub enum Node<'a> {
47 Empty,
49 Leaf(NibbleSlice<'a>, &'a [u8]),
51 Extension(NibbleSlice<'a>, NodeHandle<'a>),
53 Branch([Option<NodeHandle<'a>>; nibble_ops::NIBBLE_LENGTH], Option<&'a [u8]>),
56 NibbledBranch(NibbleSlice<'a>, [Option<NodeHandle<'a>>; nibble_ops::NIBBLE_LENGTH], Option<&'a [u8]>),
58}
59
60#[derive(Debug, Clone, PartialEq, Eq)]
63pub enum NodeHandlePlan {
64 Hash(Range<usize>),
65 Inline(Range<usize>),
66}
67
68impl NodeHandlePlan {
69 pub fn build<'a, 'b>(&'a self, data: &'b [u8]) -> NodeHandle<'b> {
73 match self {
74 NodeHandlePlan::Hash(range) => NodeHandle::Hash(&data[range.clone()]),
75 NodeHandlePlan::Inline(range) => NodeHandle::Inline(&data[range.clone()]),
76 }
77 }
78}
79
80#[derive(Eq, PartialEq, Clone)]
83#[cfg_attr(feature = "std", derive(Debug))]
84pub struct NibbleSlicePlan {
85 bytes: Range<usize>,
86 offset: usize,
87}
88
89impl NibbleSlicePlan {
90 pub fn new(bytes: Range<usize>, offset: usize) -> Self {
92 NibbleSlicePlan {
93 bytes,
94 offset
95 }
96 }
97
98 pub fn len(&self) -> usize {
100 (self.bytes.end - self.bytes.start) * nibble_ops::NIBBLE_PER_BYTE - self.offset
101 }
102
103 pub fn build<'a, 'b>(&'a self, data: &'b [u8]) -> NibbleSlice<'b> {
107 NibbleSlice::new_offset(&data[self.bytes.clone()], self.offset)
108 }
109}
110
111#[derive(Eq, PartialEq, Clone)]
118#[cfg_attr(feature = "std", derive(Debug))]
119pub enum NodePlan {
120 Empty,
122 Leaf {
124 partial: NibbleSlicePlan,
125 value: Range<usize>,
126 },
127 Extension {
129 partial: NibbleSlicePlan,
130 child: NodeHandlePlan,
131 },
132 Branch {
135 value: Option<Range<usize>>,
136 children: [Option<NodeHandlePlan>; nibble_ops::NIBBLE_LENGTH],
137 },
138 NibbledBranch {
140 partial: NibbleSlicePlan,
141 value: Option<Range<usize>>,
142 children: [Option<NodeHandlePlan>; nibble_ops::NIBBLE_LENGTH],
143 },
144}
145
146impl NodePlan {
147 pub fn build<'a, 'b>(&'a self, data: &'b [u8]) -> Node<'b> {
151 match self {
152 NodePlan::Empty => Node::Empty,
153 NodePlan::Leaf { partial, value } =>
154 Node::Leaf(partial.build(data), &data[value.clone()]),
155 NodePlan::Extension { partial, child } =>
156 Node::Extension(partial.build(data), child.build(data)),
157 NodePlan::Branch { value, children } => {
158 let mut child_slices = [None; nibble_ops::NIBBLE_LENGTH];
159 for i in 0..nibble_ops::NIBBLE_LENGTH {
160 child_slices[i] = children[i].as_ref().map(|child| child.build(data));
161 }
162 let value_slice = value.clone().map(|value| &data[value]);
163 Node::Branch(child_slices, value_slice)
164 },
165 NodePlan::NibbledBranch { partial, value, children } => {
166 let mut child_slices = [None; nibble_ops::NIBBLE_LENGTH];
167 for i in 0..nibble_ops::NIBBLE_LENGTH {
168 child_slices[i] = children[i].as_ref().map(|child| child.build(data));
169 }
170 let value_slice = value.clone().map(|value| &data[value]);
171 Node::NibbledBranch(partial.build(data), child_slices, value_slice)
172 },
173 }
174 }
175}
176
177#[cfg_attr(feature = "std", derive(Debug))]
180#[derive(PartialEq, Eq)]
181pub struct OwnedNode<D: Borrow<[u8]>> {
182 data: D,
183 plan: NodePlan,
184}
185
186impl<D: Borrow<[u8]>> OwnedNode<D> {
187 pub fn new<C: NodeCodec>(data: D) -> Result<Self, C::Error> {
189 let plan = C::decode_plan(data.borrow())?;
190 Ok(OwnedNode { data, plan })
191 }
192
193 pub fn data(&self) -> &[u8] {
195 self.data.borrow()
196 }
197
198 pub fn node_plan(&self) -> &NodePlan {
200 &self.plan
201 }
202
203 pub fn node(&self) -> Node {
205 self.plan.build(self.data.borrow())
206 }
207}