#![allow(clippy::needless_lifetimes)]
pub mod simple_rnode;
use crate::node::simple_rnode::{
RootedMetaNode, RootedTreeNode, RootedWeightedNode, RootedZetaNode, EdgeWeight, NodeWeight, NodeTaxa
};
use std::fmt::{Debug, Display};
use std::sync::Arc;
pub type NodeID = usize;
pub type PhyloNode = Node<String,f32,f32>;
pub type DemoNode = Node<u32,f32,f32>;
#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Node<T,W,Z>
where
T: NodeTaxa,
W: EdgeWeight,
Z: NodeWeight,
{
id: NodeID,
parent: Option<NodeID>,
children: Vec<NodeID>,
taxa: Option<Arc<T>>,
weight: Option<W>,
zeta: Option<Z>,
}
impl<T,W,Z> RootedTreeNode for Node<T,W,Z>
where
T: NodeTaxa,
W: EdgeWeight,
Z: NodeWeight,
{
type NodeID = NodeID;
fn new(id: Self::NodeID) -> Self {
Node {
id,
parent: None,
children: vec![],
taxa: None,
weight: None,
zeta: None,
}
}
fn get_id(&self) -> Self::NodeID {
self.id
}
fn set_id(&mut self, id: Self::NodeID) {
self.id = id
}
fn set_parent(&mut self, parent: Option<Self::NodeID>) {
self.parent = parent;
}
fn get_parent(&self) -> Option<Self::NodeID> {
self.parent
}
fn get_children(&self) -> &[Self::NodeID] {
&self.children
}
fn add_child(&mut self, child: Self::NodeID) {
self.children.push(child);
}
fn remove_child(&mut self, child: &Self::NodeID) {
self.children.retain(|x| x != child);
}
}
impl<T,W,Z> Node<T,W,Z>
where
T: NodeTaxa,
W: EdgeWeight,
Z: NodeWeight,
{
pub(crate) fn get_taxa_arc(&self) -> Option<&Arc<T>> {
self.taxa.as_ref()
}
pub(crate) fn set_taxa_arc(&mut self, taxa: Option<Arc<T>>) {
self.taxa = taxa;
}
}
impl<T,W,Z> RootedMetaNode for Node<T,W,Z>
where
T: NodeTaxa,
W: EdgeWeight,
Z: NodeWeight,
{
type Meta = T;
fn get_taxa<'a>(&'a self) -> Option<&'a Self::Meta> {
self.taxa.as_deref()
}
fn set_taxa(&mut self, taxa: Option<Self::Meta>) {
self.taxa = taxa.map(Arc::new);
}
}
impl<T,W,Z> RootedWeightedNode for Node<T,W,Z>
where
T: NodeTaxa,
W: EdgeWeight,
Z: NodeWeight,
{
type Weight = W;
fn get_weight(&self) -> Option<Self::Weight> {
self.weight
}
fn set_weight(&mut self, w: Option<Self::Weight>) {
self.weight = w;
}
}
impl<T,W,Z> RootedZetaNode for Node<T,W,Z>
where
T: NodeTaxa,
W: EdgeWeight,
Z: NodeWeight,
{
type Zeta = Z;
fn get_zeta(&self) -> Option<Self::Zeta> {
self.zeta
}
fn set_zeta(&mut self, w: Option<Self::Zeta>) {
self.zeta = w;
}
}
impl<T,W,Z> Debug for Node<T,W,Z>
where
T: NodeTaxa,
W: EdgeWeight,
Z: NodeWeight,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}:{}:{}:{}:{}",
self.get_id(),
self.node_type(),
match self.get_taxa() {
None => "No Taxa".to_string(),
Some(t) => t.to_string(),
},
match self.get_weight() {
None => "Unweighted".to_string(),
Some(t) => t.to_string(),
},
match self.get_zeta() {
None => "No Zeta".to_string(),
Some(z) => z.to_string(),
}
)
}
}
impl<T,W,Z> Display for Node<T,W,Z>
where
T: NodeTaxa,
W: EdgeWeight,
Z: NodeWeight,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}:{}:{}:{}:{}",
self.get_id(),
self.node_type(),
match self.get_taxa() {
None => "None".to_string(),
Some(t) => t.to_string(),
},
match self.get_weight() {
None => "".to_string(),
Some(t) => t.to_string(),
},
match self.get_zeta() {
None => "No Zeta".to_string(),
Some(z) => z.to_string(),
}
)
}
}