basic_tree 0.2.5

basic tree for rust, for now including only trie
Documentation
use std::cell::RefCell;
use std::cmp::Eq;
use std::cmp::PartialEq;
use std::collections::HashMap;
use std::hash::Hash;
use std::rc::Rc;

#[derive(Debug, Clone)]
pub enum Leaf<T> {
    End(T),
    Nil,
}

impl<T: PartialEq> PartialEq for Leaf<T> {
    fn eq(&self, other: &Self) -> bool {
        match self {
            Leaf::End(d) => match other {
                Leaf::End(od) => d == od,
                Leaf::Nil => false,
            },
            Leaf::Nil => match other {
                Leaf::End(_) => false,
                Leaf::Nil => true,
            },
        }
    }
}

/// Adds one to the number given.
///
/// # Examples
///
/// Trie is the basic trait to implement for a trie tree
/// ```
/// let node = Node::new();
/// let seq = vec!["你".to_string(), "我".to_string(), "他".to_string()];
/// let seq1 = vec!["你".to_string(), "我".to_string()];
/// Node::insert_seq(node.clone(), &seq, Leaf::End("intention".to_string()));
/// let leaf = Node::get_leaf(node.clone(), &seq1);
/// assert_ne!(leaf, Leaf::End("intention".to_string()));
/// ```

#[derive(Debug)]
pub struct Node<T: Eq + Hash + Clone> {
    pub node: HashMap<T, Rc<RefCell<Node<T>>>>,
    pub leaf: Leaf<T>,
}

pub trait Trie<T: Eq + Hash + Clone> {
    /// add node chars and leaf chars to Node.
    fn insert_seq(node: Rc<RefCell<Node<T>>>, words: &[T], leaf: Leaf<T>) {
        let (index, mut m_node) = Node::find_last_node(node.clone(), &words);
        for word in &words[index..] {
            m_node = Node::add_node(m_node.clone(), word.to_owned());
        }
        Node::add_leaf(m_node, leaf);
    }
    /// get the corresponding leaf from the char seq.
    fn get_leaf(node: Rc<RefCell<Node<T>>>, words: &[T]) -> Leaf<T> {
        let length = words.len();
        let (index, node) = Node::find_last_node(node.clone(), words);
        if index + 1 == length {
            let m_node = node.borrow();
            m_node.leaf.to_owned()
        } else {
            Leaf::Nil
        }
    }
    /// get the node correspongding to char.
    fn find_node(node: Rc<RefCell<Node<T>>>, word: &T) -> (bool, Rc<RefCell<Node<T>>>) {
        let m_node = node.borrow();
        match m_node.node.get(word) {
            Some(mm_node) => (true, mm_node.clone()),
            None => (false, node.clone()),
        }
    }
    /// get the last node correspongding to chars.
    fn find_last_node(node: Rc<RefCell<Node<T>>>, words: &[T]) -> (usize, Rc<RefCell<Node<T>>>) {
        let mut m_node = node.clone();
        let mut out_index = 0;
        for (index, word) in words.iter().enumerate() {
            let (label, mm_node) = Node::find_node(m_node.clone(), word);
            if label {
                out_index = index + 1;
                m_node = mm_node;
            }
        }
        (out_index, m_node.clone())
    }

    /// add leaf to the node
    fn add_leaf(node: Rc<RefCell<Node<T>>>, leaf: Leaf<T>) -> bool {
        let mut m_node = node.borrow_mut();
        m_node.leaf = leaf;
        true
    }

    /// add node to the node
    fn add_node(node: Rc<RefCell<Node<T>>>, node_data: T) -> Rc<RefCell<Node<T>>> {
        let mut m_node = node.borrow_mut();
        let new_node = Node::new();
        m_node.node.insert(node_data, new_node.clone());
        new_node.clone()
    }
}

impl<T: Eq + Hash + Clone> Trie<T> for Node<T> {}

impl<T: Eq + Hash + Clone> Node<T> {
    pub fn new() -> Rc<RefCell<Node<T>>> {
        Rc::new(RefCell::new(Node {
            node: HashMap::new(),
            leaf: Leaf::Nil,
        }))
    }
}

#[test]
fn name() {
    let node = Node::new();
    let seq = vec!["".to_string(), "".to_string(), "".to_string()];
    let seq1 = vec!["".to_string(), "".to_string()];
    Node::insert_seq(node.clone(), &seq, Leaf::End("intention".to_string()));
    let leaf = Node::get_leaf(node.clone(), &seq1);
    assert_ne!(leaf, Leaf::End("intention".to_string()));
}