use std::{fmt, num::TryFromIntError};
use serde::{Deserialize, Serialize};
use crate::block::Height;
#[cfg(any(test, feature = "proptest-impl"))]
use proptest_derive::Arbitrary;
pub const TRACKED_SUBTREE_HEIGHT: u8 = 16;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
#[serde(transparent)]
pub struct NoteCommitmentSubtreeIndex(pub u16);
impl fmt::Display for NoteCommitmentSubtreeIndex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.0.to_string())
}
}
impl From<u16> for NoteCommitmentSubtreeIndex {
fn from(value: u16) -> Self {
Self(value)
}
}
impl TryFrom<u64> for NoteCommitmentSubtreeIndex {
type Error = TryFromIntError;
fn try_from(value: u64) -> Result<Self, Self::Error> {
u16::try_from(value).map(Self)
}
}
impl From<NoteCommitmentSubtreeIndex> for u64 {
fn from(value: NoteCommitmentSubtreeIndex) -> Self {
value.0.into()
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
pub struct NoteCommitmentSubtree<SubtreeRoot> {
pub index: NoteCommitmentSubtreeIndex,
pub root: SubtreeRoot,
pub end_height: Height,
}
impl<SubtreeRoot> NoteCommitmentSubtree<SubtreeRoot> {
pub fn new(
index: impl Into<NoteCommitmentSubtreeIndex>,
end_height: Height,
root: SubtreeRoot,
) -> Self {
let index = index.into();
Self {
index,
end_height,
root,
}
}
pub fn into_data(self) -> NoteCommitmentSubtreeData<SubtreeRoot> {
NoteCommitmentSubtreeData::new(self.end_height, self.root)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, serde::Serialize)]
#[cfg_attr(any(test, feature = "proptest-impl"), derive(Arbitrary))]
pub struct NoteCommitmentSubtreeData<SubtreeRoot> {
pub root: SubtreeRoot,
pub end_height: Height,
}
impl<SubtreeRoot> NoteCommitmentSubtreeData<SubtreeRoot> {
pub fn new(end_height: Height, root: SubtreeRoot) -> Self {
Self { end_height, root }
}
pub fn with_index(
self,
index: impl Into<NoteCommitmentSubtreeIndex>,
) -> NoteCommitmentSubtree<SubtreeRoot> {
NoteCommitmentSubtree::new(index, self.end_height, self.root)
}
}