use crate::bitvec::prelude::{BitVec, Msb0};
use super::{
leaf::HuffLeaf,
letter::HuffLetter,
};
use std::cmp::Ordering;
#[derive(Debug, Clone, Eq)]
pub struct HuffBranch<L: HuffLetter>{
leaf: HuffLeaf<L>,
left_child: Option<Box<HuffBranch<L>>>,
right_child: Option<Box<HuffBranch<L>>>,
}
impl<L: HuffLetter> Ord for HuffBranch<L>{
fn cmp(&self, other: &Self) -> Ordering {
self.leaf().cmp(other.leaf())
}
}
impl<L: HuffLetter> PartialOrd for HuffBranch<L>{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<L: HuffLetter> PartialEq for HuffBranch<L>{
fn eq(&self, other: &Self) -> bool {
self.leaf() == other.leaf()
}
}
impl<L: HuffLetter> HuffBranch<L>{
pub fn new(leaf: HuffLeaf<L>, children: Option<(HuffBranch<L>, HuffBranch<L>)>) -> Self{
if let Some(children) = children{
HuffBranch{
leaf,
left_child: Some(Box::new(children.0)),
right_child: Some(Box::new(children.1)),
}
}
else{
HuffBranch{
leaf,
left_child: None,
right_child: None,
}
}
}
pub fn leaf(&self) -> &HuffLeaf<L>{
&self.leaf
}
pub fn children_iter(&self) -> Option<ChildrenIter<L>>{
if self.has_children(){Some(ChildrenIter::new(self))}
else{None}
}
pub fn left_child(&self) -> Option<&HuffBranch<L>>{
self.left_child.as_deref()
}
pub fn left_child_mut(&mut self) -> Option<&mut HuffBranch<L>>{
self.left_child.as_deref_mut()
}
pub fn right_child(&self) -> Option<&HuffBranch<L>>{
self.right_child.as_deref()
}
pub fn right_child_mut(&mut self) -> Option<&mut HuffBranch<L>>{
self.right_child.as_deref_mut()
}
pub fn has_children(&self) -> bool{
self.left_child.is_some()
}
pub fn set_children(&mut self, children: Option<(HuffBranch<L>, HuffBranch<L>)>){
if let Some(children) = children{
self.left_child = Some(Box::new(children.0));
self.right_child = Some(Box::new(children.1));
}
else{
self.left_child = None;
self.right_child = None;
}
}
pub fn set_code(&mut self, code: BitVec<Msb0, u8>){
self.leaf.set_code(code);
}
}
pub struct ChildrenIter<'a, L: HuffLetter>{
parent: &'a HuffBranch<L>,
child_pos: u8,
}
impl<'a, L: HuffLetter> Iterator for ChildrenIter<'a, L>{
type Item = &'a HuffBranch<L>;
fn next(&mut self) -> Option<Self::Item>{
match self.child_pos{
0 =>{
self.child_pos += 1;
self.parent.left_child()
}
1 =>{
self.child_pos += 1;
self.parent.right_child()
}
_ =>
None,
}
}
}
impl<'a, L: HuffLetter> ChildrenIter<'a, L>{
pub fn new(parent: &'a HuffBranch<L>) -> Self{
ChildrenIter{
parent,
child_pos: 0,
}
}
}