use crate::*;
use std::borrow::Borrow;
use std::fmt::Display;
use std::hash::Hash;
use std::ops::Deref;
use std::ops::DerefMut;
use std::ops::Range;
#[derive(Debug, Clone, PartialEq, Eq, Hash, AsRef)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Tree<T> {
value: T,
range: Range<usize>,
subtrees: Box<[Tree<T>]>,
}
impl<T: Hash + Clone, R: AsRef<Reducer<T>>> From<R> for Tree<T> {
fn from(reducer: R) -> Self {
let reducer = reducer.as_ref();
let value = reducer.value().clone();
let range = reducer.range();
let subtrees = reducer.antecedents_flattened().collect_trees().into_boxed_slice();
Self { value, range, subtrees }
}
}
impl<T> Tree<T> {
pub fn is_leaf(&self) -> bool { self.subtrees.is_empty() }
pub fn is_branch(&self) -> bool { !self.subtrees.is_empty() }
pub fn value(&self) -> &T { &self.value }
pub fn range(&self) -> Range<usize> { self.range.clone() }
pub fn subtrees(&self) -> &[Tree<T>] { &self.subtrees }
}
impl<T> AsRef<T> for Tree<T> {
fn as_ref(&self) -> &T { self.value() }
}
impl<T> Borrow<T> for Tree<T> {
fn borrow(&self) -> &T { self.value() }
}
impl<T> Deref for Tree<T> {
type Target = T;
fn deref(&self) -> &Self::Target { &self.value }
}
impl<T> DerefMut for Tree<T> {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.value }
}
impl<T: Display> Display for Tree<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Display::fmt(&DisplaySubtree { subtree: self, pre: &[], is_last_sibling: true }, f)
}
}
struct DisplaySubtree<'a, T> {
subtree: &'a Tree<T>,
pre: &'a [&'static str],
is_last_sibling: bool,
}
impl<T> Deref for DisplaySubtree<'_, T> {
type Target = Tree<T>;
fn deref(&self) -> &Self::Target { &self.subtree }
}
impl<T: Display> Display for DisplaySubtree<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let is_root = self.pre.is_empty();
if !is_root {
write!(f, "\n")?;
for str in self.pre.iter() {
write!(f, "{str}")?;
}
if self.is_last_sibling {
write!(f, "└─")?;
} else {
write!(f, "├─")?;
};
}
Display::fmt(&self.value, f)?;
write!(f, "@{:?}", self.range)?;
let pre: &Box<[&'static str]> = &self
.pre
.iter()
.cloned()
.chain([if is_root {
""
} else if self.is_last_sibling {
" "
} else {
"│ "
}])
.collect();
let len = self.subtrees.len();
for (index, subtree) in self.subtrees.iter().enumerate() {
let is_last_sibling = index == len - 1;
Display::fmt(&DisplaySubtree { subtree, pre, is_last_sibling }, f)?;
}
Ok(())
}
}