use num::{Float, Signed, Zero};
use std::{hash::Hash, marker::Sync, fmt::{Debug, Display}, str::FromStr, iter::Sum};
pub trait EdgeWeight: Display + Debug + Sum + FromStr + Float + Signed + Sync + Send{}
pub trait NodeWeight: Display + Debug + Sum + FromStr + Float + Zero + Signed + Sync + Send{}
pub trait NodeTaxa: Display + Debug + Clone + FromStr + Ord + Hash + Sync + Send{}
impl NodeTaxa for String{}
impl NodeTaxa for u32{}
impl EdgeWeight for f32{}
impl EdgeWeight for f64{}
impl NodeWeight for f32{}
impl NodeWeight for f64{}
pub trait RootedTreeNode
where
Self: Clone,
{
type NodeID: Display + Debug + Hash + Ord + PartialEq + Eq + Copy;
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<'a>(&'a self) -> Option<&'a 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);
}
}