mqtt-protocol 0.3.0

MQTT Protocol Library
Documentation
use std::collections::HashMap;
use std::ptr;
use std::mem;

use control::variable_header::TopicName;
use topic_filter::TopicFilter;

struct Node<V> {
    next: HashMap<String, Box<Node<V>>>,
    value: Option<V>,
}

pub struct TopicMap<V> {
    head: Box<Node<V>>,
    size: usize,
}

impl<V> TopicMap<V> {
    pub fn new() -> TopicMap<V> {
        TopicMap {
            head: Box::new(Node {
                next: HashMap::new(),
                value: None,
            }),
            size: 0,
        }
    }

    pub fn len(&self) -> usize {
        self.size
    }

    pub fn insert(&mut self, topic_name: &TopicName, value: V) -> Option<V> {
        let mut cur: *mut Node<V> = &mut *self.head;
        for part in topic_name.split('/') {
            let next = unsafe {
                (&mut *cur).next
                   .entry(part.to_owned())
                   .or_insert_with(|| Box::new(Node {
                                        next: HashMap::new(),
                                        value: None,
                                    }))
            };

            cur = &mut **next;
        }

        let mut opt_val = Some(value);
        unsafe {
            mem::swap(&mut opt_val, &mut (&mut *cur).value);
        }

        if opt_val.is_none() {
            self.size += 1;
        }

        opt_val
    }

    // pub fn search(&self, topic_filter: &TopicFilter) -> Option<V> {
    //
    // }
}

#[cfg(test)]
mod test {
    use super::*;

    use control::variable_header::TopicName;

    #[test]
    fn test_topic_map_insert() {
        let mut map = TopicMap::new();

        let name = TopicName::new("abc/def/ghi".to_owned()).unwrap();
        map.insert(&name, 123);

        assert_eq!(map.len(), 1);
    }
}