Skip to content

Commit

Permalink
Merge pull request #81 from turbofish-org/key-length-support
Browse files Browse the repository at this point in the history
Key length support
  • Loading branch information
mappum authored Nov 1, 2024
2 parents cc49630 + bf2e0ca commit 058839b
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 54 deletions.
49 changes: 25 additions & 24 deletions src/merk/chunks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,70 +311,71 @@ mod tests {
assert_eq!(
chunk,
vec![
3, 8, 0, 0, 0, 0, 0, 0, 0, 18, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123,
3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 18, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 3, 8, 0, 0, 0, 0, 0, 0, 0, 19, 0, 60, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, 0, 60, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 16, 3, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 60, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 16, 3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0,
60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 17, 3, 8, 0, 0, 0, 0, 0, 0, 0,
21, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 17, 3, 0, 8, 0, 0, 0,
0, 0, 0, 0, 21, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 16, 3, 8, 0,
0, 0, 0, 0, 0, 0, 22, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 16,
3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 22, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 3, 8, 0, 0, 0, 0, 0, 0, 0, 23, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 23, 0, 60, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 16, 3, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 60, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 16, 3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0,
60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 17, 17, 3, 0, 8, 0, 0,
0, 0, 0, 0, 0, 25, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 17, 17, 3, 8, 0, 0, 0, 0, 0, 0, 0, 25, 0,
60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 16, 3, 8, 0, 0, 0, 0,
0, 0, 0, 26, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 16, 3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 26, 0, 60, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 3,
8, 0, 0, 0, 0, 0, 0, 0, 27, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 27, 0, 60, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 16, 3, 8, 0, 0, 0, 0, 0, 0, 0, 28, 0, 60, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 16, 3, 0, 8, 0, 0, 0, 0, 0, 0, 0,
28, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 17, 3, 8, 0, 0, 0, 0, 0, 0, 0, 29, 0, 60, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 17, 3, 0, 8,
0, 0, 0, 0, 0, 0, 0, 29, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 16, 3, 8, 0, 0, 0, 0, 0, 0,
0, 30, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 16, 3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 30, 0, 60, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 3, 8, 0, 0,
0, 0, 0, 0, 0, 31, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 31, 0, 60, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 16, 3, 8, 0, 0, 0, 0, 0, 0, 0, 32, 0, 60, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 16, 3, 0, 8, 0, 0, 0, 0, 0,
0, 0, 32, 0, 60, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 17, 17, 17
123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 17, 17,
17
]
);
}
Expand Down
18 changes: 9 additions & 9 deletions src/proofs/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ impl Encode for Op {
dest.write_all(kv_hash)?;
}
Op::Push(Node::KV(key, value)) => {
debug_assert!(key.len() < 256);
debug_assert!(key.len() < 65536);
debug_assert!(value.len() < 65536);

dest.write_all(&[0x03, key.len() as u8])?;
dest.write_all(&[0x03])?;
(key.len() as u16).encode_into(dest)?;
dest.write_all(key)?;
(value.len() as u16).encode_into(dest)?;
dest.write_all(value)?;
Expand All @@ -36,7 +36,7 @@ impl Encode for Op {
Ok(match self {
Op::Push(Node::Hash(_)) => 1 + HASH_LENGTH,
Op::Push(Node::KVHash(_)) => 1 + HASH_LENGTH,
Op::Push(Node::KV(key, value)) => 4 + key.len() + value.len(),
Op::Push(Node::KV(key, value)) => 5 + key.len() + value.len(),
Op::Parent => 1,
Op::Child => 1,
})
Expand All @@ -59,7 +59,7 @@ impl Decode for Op {
Op::Push(Node::KVHash(hash))
}
0x03 => {
let key_len: u8 = Decode::decode(&mut input)?;
let key_len: u16 = Decode::decode(&mut input)?;
let mut key = vec![0; key_len as usize];
input.read_exact(key.as_mut_slice())?;

Expand Down Expand Up @@ -173,11 +173,11 @@ mod test {
#[test]
fn encode_push_kv() {
let op = Op::Push(Node::KV(vec![1, 2, 3], vec![4, 5, 6]));
assert_eq!(op.encoding_length(), 10);
assert_eq!(op.encoding_length(), 11);

let mut bytes = vec![];
op.encode_into(&mut bytes).unwrap();
assert_eq!(bytes, vec![0x03, 3, 1, 2, 3, 0, 3, 4, 5, 6]);
assert_eq!(bytes, vec![0x03, 0, 3, 1, 2, 3, 0, 3, 4, 5, 6]);
}

#[test]
Expand All @@ -203,7 +203,7 @@ mod test {
#[test]
#[should_panic]
fn encode_push_kv_long_key() {
let op = Op::Push(Node::KV(vec![123; 300], vec![4, 5, 6]));
let op = Op::Push(Node::KV(vec![123; 70_000], vec![4, 5, 6]));
let mut bytes = vec![];
op.encode_into(&mut bytes).unwrap();
}
Expand All @@ -230,7 +230,7 @@ mod test {

#[test]
fn decode_push_kv() {
let bytes = [0x03, 3, 1, 2, 3, 0, 3, 4, 5, 6];
let bytes = [0x03, 0, 3, 1, 2, 3, 0, 3, 4, 5, 6];
let op = Op::decode(&bytes[..]).expect("decode failed");
assert_eq!(op, Op::Push(Node::KV(vec![1, 2, 3], vec![4, 5, 6])));
}
Expand Down
10 changes: 5 additions & 5 deletions src/proofs/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -932,11 +932,11 @@ mod test {
assert_eq!(
bytes,
vec![
3, 1, 1, 0, 1, 1, 3, 1, 2, 0, 1, 2, 16, 3, 1, 3, 0, 1, 3, 3, 1, 4, 0, 1, 4, 16, 17,
2, 169, 4, 73, 65, 62, 49, 160, 159, 37, 166, 195, 249, 63, 31, 23, 11, 169, 0, 24,
104, 179, 211, 218, 38, 108, 129, 117, 232, 65, 101, 194, 157, 16, 1, 148, 241,
151, 144, 247, 220, 92, 79, 70, 252, 168, 222, 27, 218, 53, 156, 0, 136, 161, 107,
83, 78, 150, 246, 51, 230, 164, 248, 17, 30, 147, 91, 17
3, 0, 1, 1, 0, 1, 1, 3, 0, 1, 2, 0, 1, 2, 16, 3, 0, 1, 3, 0, 1, 3, 3, 0, 1, 4, 0,
1, 4, 16, 17, 2, 169, 4, 73, 65, 62, 49, 160, 159, 37, 166, 195, 249, 63, 31, 23,
11, 169, 0, 24, 104, 179, 211, 218, 38, 108, 129, 117, 232, 65, 101, 194, 157, 16,
1, 148, 241, 151, 144, 247, 220, 92, 79, 70, 252, 168, 222, 27, 218, 53, 156, 0,
136, 161, 107, 83, 78, 150, 246, 51, 230, 164, 248, 17, 30, 147, 91, 17
]
);

Expand Down
8 changes: 4 additions & 4 deletions src/tree/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ mod tests {
assert_eq!(
tree.encode(),
vec![
1, 1, 2, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
1, 0, 1, 2, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 123, 124, 0, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 1
Expand All @@ -113,7 +113,7 @@ mod tests {
assert_eq!(
tree.encode(),
vec![
1, 1, 2, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
1, 0, 1, 2, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 123, 124, 0, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 1
Expand All @@ -139,7 +139,7 @@ mod tests {
assert_eq!(
tree.encode(),
vec![
1, 1, 2, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
1, 0, 1, 2, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 123, 124, 0, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 1
Expand All @@ -161,7 +161,7 @@ mod tests {
#[test]
fn decode_reference_tree() {
let bytes = vec![
1, 1, 2, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
1, 0, 1, 2, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 123, 124, 0, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 1,
Expand Down
7 changes: 6 additions & 1 deletion src/tree/kv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::{
// field and value field.

/// Contains a key/value pair, and the hash of the key/value pair.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct KV {
pub(super) key: Vec<u8>,
pub(super) value: Vec<u8>,
Expand Down Expand Up @@ -75,7 +76,11 @@ impl Encode for KV {

#[inline]
fn encoding_length(&self) -> Result<usize> {
debug_assert!(self.key().len() < 256, "Key length must be less than 256");
debug_assert!(
self.key().len() < 65536,
"Key length must be less than 65536"
);

Ok(HASH_LENGTH + self.value.len())
}
}
Expand Down
46 changes: 37 additions & 9 deletions src/tree/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use super::Tree;

/// Represents a reference to a child tree node. Links may or may not contain
/// the child's `Tree` instance (storing its key if not).
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Link {
/// Represents a child tree node which has been pruned from memory, only
/// retaining a reference to it (its key). The child node can always be
Expand Down Expand Up @@ -221,9 +222,12 @@ impl Encode for Link {
Link::Modified { .. } => panic!("No encoding for Link::Modified"),
};

debug_assert!(key.len() < 256, "Key length must be less than 256");
debug_assert!(
self.key().len() < 65536,
"Key length must be less than 65536"
);

out.write_all(&[key.len() as u8])?;
out.write_all(&(key.len() as u16).to_be_bytes())?;
out.write_all(key)?;

out.write_all(hash)?;
Expand All @@ -235,7 +239,10 @@ impl Encode for Link {

#[inline]
fn encoding_length(&self) -> Result<usize> {
debug_assert!(self.key().len() < 256, "Key length must be less than 256");
debug_assert!(
self.key().len() < 65536,
"Key length must be less than 65536"
);

Ok(match self {
Link::Reference { key, .. } => 1 + key.len() + 32 + 2,
Expand Down Expand Up @@ -279,7 +286,7 @@ impl Decode for Link {
ref mut child_heights,
} = self
{
let length = read_u8(&mut input)? as usize;
let length = read_u16(&mut input)? as usize;

key.resize(length, 0);
input.read_exact(key.as_mut())?;
Expand All @@ -298,6 +305,13 @@ impl Decode for Link {

impl Terminated for Link {}

#[inline]
fn read_u16<R: Read>(mut input: R) -> Result<u16> {
let mut length = [0, 0];
input.read_exact(length.as_mut())?;
Ok(u16::from_be_bytes(length))
}

#[inline]
fn read_u8<R: Read>(mut input: R) -> Result<u8> {
let mut length = [0];
Expand Down Expand Up @@ -451,17 +465,31 @@ mod test {
assert_eq!(
bytes,
vec![
3, 1, 2, 3, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 123, 124
0, 3, 1, 2, 3, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 123, 124
]
);
}

#[test]
#[should_panic]
fn encode_link_long_key() {
fn encode_link_long_key_valid() {
let link = Link::Reference {
key: vec![123; 60_000],
child_heights: (123, 124),
hash: [55; 32],
};
let mut bytes = vec![];
link.encode_into(&mut bytes).unwrap();

let decoded = Link::decode(&bytes[..]).unwrap();
assert_eq!(decoded, link);
}

#[test]
#[should_panic = "Key length must be less than 65536"]
fn encode_link_long_key_invalid() {
let link = Link::Reference {
key: vec![123; 300],
key: vec![123; 70_000],
child_heights: (123, 124),
hash: [55; 32],
};
Expand Down
4 changes: 2 additions & 2 deletions src/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub use walk::{Fetch, RefWalker, Walker};
// relevant methods

/// The fields of the `Tree` type, stored on the heap.
#[derive(Encode, Decode)]
#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode)]
pub struct TreeInner {
left: Option<Link>,
right: Option<Link>,
Expand All @@ -38,7 +38,7 @@ pub struct TreeInner {
/// Trees' inner fields are stored on the heap so that nodes can recursively
/// link to each other, and so we can detach nodes from their parents, then
/// reattach without allocating or freeing heap memory.
#[derive(Encode, Decode)]
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
pub struct Tree {
inner: Box<TreeInner>,
}
Expand Down

0 comments on commit 058839b

Please sign in to comment.