use crate::node::Node;
use std::cmp::Ordering;
use std::collections::VecDeque;
#[derive(Debug, Clone, PartialOrd, PartialEq)]
pub(crate) enum TreeKnot<T>
where T: Copy + Clone + PartialOrd + PartialEq
{
Empty,
NonEmpty(Box<Node<T>>),
}
impl<T> Default for TreeKnot<T>
where T: Copy + Clone + PartialOrd + PartialEq
{
#[inline]
fn default() -> Self {
TreeKnot::Empty
}
}
#[allow(dead_code)]
impl<T> TreeKnot<T>
where T: Copy + Clone + PartialOrd + PartialEq
{
#[inline]
pub(crate) fn new() -> Self {
TreeKnot::default()
}
#[inline]
pub(crate) fn ignore(&self) -> &Box<Node<T>> {
if let TreeKnot::NonEmpty(ref node) = *self {
return node;
} else {
panic!("Empty tree");
}
}
#[inline]
pub(crate) fn ignore_mut(&mut self) -> &mut Box<Node<T>> {
if let TreeKnot::NonEmpty(ref mut node) = *self {
return node;
} else {
panic!("Empty tree");
}
}
#[inline]
pub(crate) fn get_key(&self) -> &T {
&self.ignore().key
}
pub(crate) fn insert(&mut self, val: &T) {
match *self {
TreeKnot::Empty => {
*self = TreeKnot::NonEmpty(Box::new(Node {
key: (*val).clone(),
right: TreeKnot::Empty,
left: TreeKnot::Empty,
}))
}
TreeKnot::NonEmpty(ref mut node) => {
if node.key <= *val {
node.right.insert(val);
} else {
node.left.insert(val);
}
}
}
}
pub(crate) fn find(&self, val: &T) -> &Self {
let mut find = self;
while let TreeKnot::NonEmpty(ref node) = *find {
match val.partial_cmp(find.get_key()) {
Some(Ordering::Less) => find = &node.left,
Some(Ordering::Greater) => find = &node.right,
Some(Ordering::Equal) => return find,
None => panic!("NAN value can't be used"),
}
}
&TreeKnot::Empty
}
pub(crate) fn min(&self) -> &Self {
let mut min = self;
while min.ignore().left != TreeKnot::Empty {
min = &min.ignore().left;
}
min
}
pub(crate) fn max(&self) -> &Self {
let mut max = self;
while max.ignore().right != TreeKnot::Empty {
max = &max.ignore().right;
}
max
}
pub(crate) fn walk(&self) -> VecDeque<T> {
return match *self {
TreeKnot::Empty => VecDeque::new(),
TreeKnot::NonEmpty(ref node) => {
let mut result = node.left.walk();
result.push_back(node.key.clone());
result.extend(node.right.walk());
result
}
}
}
}