use num::{Float, Signed, Zero};
use std::{
fmt::{Debug, Display},
hash::Hash,
iter::Sum,
marker::Sync,
str::FromStr,
sync::Arc,
};
pub trait EdgeWeight: Display + Debug + Sum + FromStr + Float + Signed + Sync + Send {}
impl<T: Display + Debug + Sum + FromStr + Float + Signed + Sync + Send> EdgeWeight for T {}
pub trait NodeWeight:
Display + Debug + Sum + FromStr + Float + Zero + Signed + Sync + Send
{
}
impl<T: Display + Debug + Sum + FromStr + Float + Zero + Signed + Sync + Send> NodeWeight for T {}
pub trait NodeTaxa: Display + Debug + Clone + FromStr + Ord + Hash + Sync + Send {}
impl<T: Display + Debug + Clone + FromStr + Ord + Hash + Sync + Send> NodeTaxa for T {}
pub trait RootedTreeNode
where
Self: Clone,
{
type NodeID: Display + Debug + Hash + Ord + Copy + Into<usize> + Sync;
fn new(id: Self::NodeID) -> Self;
fn get_id(&self) -> Self::NodeID;
fn set_id(&mut self, id: Self::NodeID);
fn get_parent(&self) -> Option<Self::NodeID>;
fn set_parent(&mut self, parent: Option<Self::NodeID>);
fn get_children(&self) -> &[Self::NodeID];
fn add_child(&mut self, child: Self::NodeID);
fn remove_child(&mut self, child: &Self::NodeID);
fn is_leaf(&self) -> bool {
self.get_children().is_empty()
}
fn node_type(&self) -> String {
match self.is_leaf() {
false => "Internal".to_string(),
true => "Leaf".to_string(),
}
}
fn add_children(&mut self, children: impl Iterator<Item = Self::NodeID>) {
for child in children {
self.add_child(child);
}
}
fn remove_children(&mut self, children: impl Iterator<Item = Self::NodeID>) {
for child in children {
self.remove_child(&child);
}
}
fn remove_all_children(&mut self) {
let children = self.get_children().to_vec();
for child in children {
self.remove_child(&child);
}
}
fn num_children(&self) -> usize {
self.get_children().len()
}
fn has_children(&self) -> bool {
self.num_children() > 0
}
fn degree(&self) -> usize {
match self.get_parent() {
Some(_) => self.num_children() + 1,
None => self.num_children(),
}
}
fn neighbours(&self) -> impl ExactSizeIterator<Item = Self::NodeID> {
let mut children = self.get_children().to_vec();
if let Some(p) = self.get_parent() {
children.push(p);
}
children.into_iter()
}
}
pub trait RootedMetaNode: RootedTreeNode {
type Meta: NodeTaxa;
fn get_taxa(&self) -> Option<&Self::Meta>;
fn set_taxa(&mut self, taxa: Option<Self::Meta>);
}
pub trait RootedWeightedNode: RootedTreeNode {
type Weight: EdgeWeight;
fn get_weight(&self) -> Option<Self::Weight>;
fn set_weight(&mut self, w: Option<Self::Weight>);
fn unweight(&mut self) {
self.set_weight(None);
}
fn is_weighted(&self) -> bool {
self.get_weight().is_some()
}
}
pub trait RootedZetaNode: RootedTreeNode {
type Zeta: NodeWeight;
fn get_zeta(&self) -> Option<Self::Zeta>;
fn set_zeta(&mut self, w: Option<Self::Zeta>);
fn is_zeta_set(&self) -> bool {
self.get_zeta().is_some()
}
fn remove_zeta(&mut self) {
self.set_zeta(None);
}
}
pub trait RootedAnnotatedNode: RootedTreeNode {
fn get_annotation(&self) -> Option<&str>;
fn set_annotation(&mut self, annotation: Option<Arc<str>>);
fn is_annotated(&self) -> bool {
self.get_annotation().is_some()
}
fn remove_annotation(&mut self) {
self.set_annotation(None);
}
}