yamlette 0.1.1

Complete and comprehensive YAML 1.2 processor, written in pure rust
Documentation
pub mod pointer;
pub mod traits;

pub use self::pointer::Pointer;
pub use self::traits::FromPointer;

#[macro_export]
macro_rules! yamlette_reckon {
    ( book ; $book:expr ; [ $( $rules:tt ),* ] ) => {
        let mut _counter: usize = 0;
        $(
            let volume = $book.volumes.get (_counter);
            $crate::yamlette_reckon! ( volume ; volume ; $rules );
            _counter += 1;
        )*
    };


    ( volume ; $volume:expr ; [ $( $rules:tt ),* ] ) => {
        let _pointer = if let Some (volume) = $volume { $crate::book::extractor::pointer::Pointer::new (volume) } else { None };
        $(
            $crate::yamlette_reckon! ( ptr ; _pointer ; $rules );
            let _pointer = if let Some (p) = _pointer { p.next_sibling () } else { None };
        )*
    };


    ( ptr ; $pointer:expr ; [ $( $v:tt ),* ] ) => {
        let _pointer = if let Some (p) = $pointer { p.into_seq () } else { None };
        $(
            $crate::yamlette_reckon! ( ptr ; _pointer ; $v );
            let _pointer = if let Some (p) = _pointer { p.next_sibling () } else { None };
        )*
    };


    ( ptr ; $pointer:expr ; { $( $k:tt > $v:tt ),* } ) => {
        let _pointer = if let Some (p) = $pointer { p.into_map () } else { None };
        $(
            $crate::yamlette_reckon! ( ptr ; _pointer ; $k );
            let _pointer = if let Some (p) = _pointer { p.next_sibling () } else { None };
            $crate::yamlette_reckon! ( ptr ; _pointer ; $v );
            let _pointer = if let Some (p) = _pointer { p.next_sibling () } else { None };
        )*
    };


    ( ptr ; $pointer:expr ; { $( $k:expr => $v:tt ),* } ) => {
        $(
            let mut _pointer = if let Some (p) = $pointer { p.into_map () } else { None };
            {
                let mut found = false;

                loop {
                    if _pointer.is_none () { break; }
                    let ptr = _pointer.unwrap ();

                    if ptr == $k {
                        found = true;
                        _pointer = ptr.next_sibling ();
                        break;
                    }

                    _pointer = ptr.next_sibling ();
                    _pointer = if let Some (p) = _pointer { p.next_sibling () } else { None };
                }

                if !found { _pointer = None; }
            }
            $crate::yamlette_reckon! ( ptr ; _pointer ; $v );
        )*
    };


    ( ptr ; $pointer:expr ; { $( ( $v:ident:$t:ty ) ),* } ) => {
        $( let mut $v: Option<$t> = None; )*

        {
            let mut _pointer = if let Some (p) = $pointer { p.into_map () } else { None };

            loop {
                if _pointer.is_none () { break; }

                let ptr = _pointer.unwrap ();

                $(
                    if ptr == stringify! ($v) {
                        if let Some (p) = ptr.next_sibling () {
                            use $crate::book::extractor::traits::FromPointer;
                            $v = <$t as FromPointer>::from_pointer (p);
                        }

                        _pointer = ptr.next_sibling ();
                        _pointer = if let Some (p) = _pointer { p.next_sibling () } else { None };

                        continue;
                    }
                )*

                _pointer = ptr.next_sibling ();
                _pointer = if let Some (p) = _pointer { p.next_sibling () } else { None };
            }
        }
    };


    ( ptr ; $pointer:expr ; ( $($v:ident:$t:ty),* ) ) => {
        $(
            let $v: Option<$t> = if let Some (p) = $pointer {
                use $crate::book::extractor::traits::FromPointer;
                <$t as FromPointer>::from_pointer (p)
            } else { None };
        )*
    };


    ( ptr ; $pointer:expr ; (list $($v:ident:$t:ty),* ) ) => {
        $(
            let $v: Option<$t> = if let Some (p) = $pointer {
                use $crate::book::extractor::traits::List;
                let _word = p.unalias ().to_word ();
                let mut some: Option<$t> = match *_word {
                    $crate::book::word::Word::Seq (_) => Some (List::list_new ()),
                    _ => None
                };

                if let Some (ref mut val) = some {
                    let mut _pointer = if let Some (p) = $pointer { p.into_seq () } else { None };
                    if let Some (p) = _pointer { val.list_reserve (p.count_siblings ()) };
                    loop {
                        _pointer = if let Some (p) = _pointer {
                            val.list_update (p);
                            p.next_sibling ()
                        } else { break };
                    }
                };
                some
            } else { None };
        )*
    };


    ( ptr ; $pointer:expr ; (dict $($v:ident:$t:ty),* ) ) => {
        $(
            let $v: Option<$t> = if let Some (p) = $pointer {
                use $crate::book::extractor::traits::Dict;
                let _word = p.unalias ().to_word ();
                let mut some: Option<$t> = match *_word {
                    $crate::book::word::Word::Map (_) => Some (Dict::dict_new ()),
                    _ => None
                };

                if let Some (ref mut val) = some {
                    let mut _pointer = if let Some (p) = $pointer { p.into_map () } else { None };
                    if let Some (p) = _pointer { val.dict_reserve (p.count_siblings ()/2usize) };
                    loop {
                        _pointer = if let Some (p) = _pointer {
                            let key = p;
                            if let Some (p) = p.next_sibling () {
                                val.dict_update (key, p);
                                p.next_sibling ()
                            } else { break }
                        } else { break };
                    }
                };
                some
            } else { None };
        )*
    };


    ( ptr ; $pointer:expr ; (call $($f:expr),*) ) => {
        use $crate::book::extractor::pointer::Pointer;
        fn _clo<'a, F>(clo: &mut F, ptr: Pointer<'a>) where F: FnMut(Pointer<'a>) -> () { clo (ptr); }

        $(
            if $pointer.is_some () {
                _clo ($f, $pointer.unwrap ());
            }
        )*
    };


    ( ptr ; $pointer:expr ; (foreach $($f:expr),*) ) => {
        use $crate::book::extractor::pointer::Pointer;
        fn _clo<'a, F>(clo: &mut F, ptr: Pointer<'a>) where F: FnMut(Pointer<'a>) -> () { clo (ptr); }

        let mut _ptr = $pointer;

        loop {
            _ptr = match _ptr {
                Some (ptr) => {
                    $( _clo ($f, ptr); )*;
                    ptr.next_sibling ()
                }
                None => break
            };
        }
    };
}