tom 0.0.1

Yet another format-preserving TOML parser/manipulator.
Documentation
use {AstNode, CstNode, TomlDoc};

pub(crate) struct Visitor<'c, C> {
    ctx: C,
    callbacks: Vec<Box<FnMut(&mut C, CstNode, &TomlDoc) + 'c>>,
}

pub(crate) fn visitor<'c, C>(ctx: C) -> Visitor<'c, C> {
    Visitor {
        ctx,
        callbacks: Vec::new(),
    }
}

pub(crate) fn process<'c, C>(node: CstNode, doc: &TomlDoc, mut v: Visitor<'c, C>) -> C {
    go(node, doc, &mut v);
    return v.ctx;

    fn go<'c, C>(node: CstNode, doc: &TomlDoc, v: &mut Visitor<'c, C>) {
        v.do_visit(node, doc);
        for child in node.children(doc) {
            go(child, doc, v);
        }
    }
}

impl<'c, C> Visitor<'c, C> {
    pub fn visit<A: AstNode, F: FnMut(&mut C, A) + 'c>(mut self, mut f: F) -> Self {
        let cb: Box<FnMut(&mut C, CstNode, &TomlDoc) + 'c> =
            Box::new(move |c, node, doc| match A::cast(node, doc) {
                None => (),
                Some(a) => f(c, a),
            });
        self.callbacks.push(cb);
        self
    }

    fn do_visit(&mut self, node: CstNode, doc: &TomlDoc) {
        for cb in self.callbacks.iter_mut() {
            cb(&mut self.ctx, node, doc);
        }
    }
}