use core::fmt;
#[derive(Debug, Clone)]
pub struct Node<T, S = T> {
pub id: usize,
pub content: NodeContent<T, S>,
pub level: usize,
pub children: Vec<usize>,
pub metadata: Option<NodeMetadata>,
}
#[derive(Debug, Clone)]
pub enum NodeContent<T, S = T> {
Leaf(T),
Summary(S),
}
#[derive(Debug, Clone, Default)]
pub struct NodeMetadata {
pub leaf_count: usize,
pub cluster_method: Option<String>,
pub summary_method: Option<String>,
}
impl<T, S> Node<T, S> {
pub fn leaf(id: usize, item: T) -> Self {
Self {
id,
content: NodeContent::Leaf(item),
level: 0,
children: Vec::new(),
metadata: None,
}
}
pub fn internal(id: usize, summary: S, level: usize, children: Vec<usize>) -> Self {
Self {
id,
content: NodeContent::Summary(summary),
level,
children,
metadata: None,
}
}
pub fn is_leaf(&self) -> bool {
matches!(self.content, NodeContent::Leaf(_))
}
pub fn as_leaf(&self) -> Option<&T> {
match &self.content {
NodeContent::Leaf(item) => Some(item),
_ => None,
}
}
pub fn as_summary(&self) -> Option<&S> {
match &self.content {
NodeContent::Summary(summary) => Some(summary),
_ => None,
}
}
pub fn with_metadata(mut self, metadata: NodeMetadata) -> Self {
self.metadata = Some(metadata);
self
}
}
impl<T: fmt::Display, S: fmt::Display> fmt::Display for Node<T, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.content {
NodeContent::Leaf(item) => write!(f, "Leaf[{}]: {}", self.id, item),
NodeContent::Summary(summary) => {
write!(f, "Node[{}] L{}: {}", self.id, self.level, summary)
}
}
}
}