pub use crate::weights::Weights;
use super::{
letter::HuffLetter,
branch::HuffBranch,
leaf::HuffLeaf,
};
use std::{
collections::BinaryHeap,
cmp::Ordering,
};
#[derive(Debug, Clone)]
pub struct HuffBranchHeap<L: HuffLetter>{
heap: BinaryHeap<HuffBranchHeapItem<L>>,
}
impl<L: HuffLetter> HuffBranchHeap<L>{
pub fn from_weights<W: Weights<L>>(weights: W) -> Self{
let mut heap = HuffBranchHeap::new();
heap.build(weights);
heap
}
pub fn new() -> Self{
HuffBranchHeap::<L>{
heap: BinaryHeap::new(),
}
}
pub fn len(&self) -> usize{
self.heap.len()
}
pub fn push(&mut self, branch: HuffBranch<L>){
self.heap.push(HuffBranchHeapItem(branch));
}
pub fn pop_min(&mut self) -> HuffBranch<L>{
self.heap.pop().unwrap().unwrap()
}
fn build<W: Weights<L>>(&mut self, weights: W){
for (l, f) in weights.into_iter(){
let new_branch = HuffBranch::new(HuffLeaf::new(Some(l), f), None);
self.push(new_branch);
}
}
}
#[derive(Debug, Clone, Eq)]
struct HuffBranchHeapItem<L: HuffLetter>(HuffBranch<L>);
impl<L: HuffLetter> Ord for HuffBranchHeapItem<L>{
fn cmp(&self, other: &Self) -> Ordering {
other.0.leaf().cmp(&self.0.leaf())
}
}
impl<L: HuffLetter> PartialOrd for HuffBranchHeapItem<L>{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<L: HuffLetter> PartialEq for HuffBranchHeapItem<L>{
fn eq(&self, other: &Self) -> bool {
self.0.leaf().weight() == other.0.leaf().weight()
}
}
impl<L: HuffLetter> HuffBranchHeapItem<L>{
pub fn unwrap(self) -> HuffBranch<L>{
self.0
}
}