1use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
2
3use crate::{EntryKind, EntryLink, Error, Version, MAX_NODE_DATA_SIZE};
4
5pub const MAX_ENTRY_SIZE: usize = MAX_NODE_DATA_SIZE + 9;
7
8#[derive(Debug)]
10pub struct Entry<V: Version> {
11 pub(crate) kind: EntryKind,
12 pub(crate) data: V::NodeData,
13}
14
15impl<V: Version> Entry<V> {
16 pub fn new(data: V::NodeData, left: EntryLink, right: EntryLink) -> Self {
18 Entry {
19 kind: EntryKind::Node(left, right),
20 data,
21 }
22 }
23
24 pub fn data(&self) -> &V::NodeData {
26 &self.data
27 }
28
29 pub fn new_leaf(data: V::NodeData) -> Self {
31 Entry {
32 kind: EntryKind::Leaf,
33 data,
34 }
35 }
36
37 pub fn complete(&self) -> bool {
39 self.leaf_count().is_power_of_two()
40 }
41
42 pub fn leaf_count(&self) -> u64 {
44 V::end_height(&self.data) - (V::start_height(&self.data) - 1)
45 }
46
47 pub fn leaf(&self) -> bool {
49 matches!(self.kind, EntryKind::Leaf)
50 }
51
52 pub fn left(&self) -> Result<EntryLink, Error> {
54 match self.kind {
55 EntryKind::Leaf => Err(Error::node_expected()),
56 EntryKind::Node(left, _) => Ok(left),
57 }
58 }
59
60 pub fn right(&self) -> Result<EntryLink, Error> {
62 match self.kind {
63 EntryKind::Leaf => Err(Error::node_expected()),
64 EntryKind::Node(_, right) => Ok(right),
65 }
66 }
67
68 pub fn read<R: std::io::Read>(consensus_branch_id: u32, r: &mut R) -> std::io::Result<Self> {
70 let kind = {
71 match r.read_u8()? {
72 0 => {
73 let left = r.read_u32::<LittleEndian>()?;
74 let right = r.read_u32::<LittleEndian>()?;
75 EntryKind::Node(EntryLink::Stored(left), EntryLink::Stored(right))
76 }
77 1 => EntryKind::Leaf,
78 _ => return Err(std::io::Error::from(std::io::ErrorKind::InvalidData)),
79 }
80 };
81
82 let data = V::read(consensus_branch_id, r)?;
83
84 Ok(Entry { kind, data })
85 }
86
87 pub fn write<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
89 match self.kind {
90 EntryKind::Node(EntryLink::Stored(left), EntryLink::Stored(right)) => {
91 w.write_u8(0)?;
92 w.write_u32::<LittleEndian>(left)?;
93 w.write_u32::<LittleEndian>(right)?;
94 }
95 EntryKind::Leaf => {
96 w.write_u8(1)?;
97 }
98 _ => {
99 return Err(std::io::Error::from(std::io::ErrorKind::InvalidData));
100 }
101 }
102
103 V::write(&self.data, w)?;
104
105 Ok(())
106 }
107
108 pub fn from_bytes<T: AsRef<[u8]>>(consensus_branch_id: u32, buf: T) -> std::io::Result<Self> {
110 let mut cursor = std::io::Cursor::new(buf);
111 Self::read(consensus_branch_id, &mut cursor)
112 }
113}
114
115impl<V: Version> std::fmt::Display for Entry<V> {
116 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117 match self.kind {
118 EntryKind::Node(l, r) => write!(f, "node({l}, {r}, ..)"),
119 EntryKind::Leaf => write!(f, "leaf(..)"),
120 }
121 }
122}