pub fn rec_parser<'a, 'b, C, O, I>(
handler: impl Fn(RecursiveCtor<'b, C, O>) -> I
) -> RecursiveCtor<'b, C, O>where
C: Context<'a>,
I: Fn(&mut C) -> Result<O, Error> + 'b,
Expand description
#[derive(Debug, PartialEq, Eq)]
enum Xml {
Element { name: String, child: Vec<Xml> },
Enclosed(String),
}
pub fn parser<'a: 'b, 'b>(
ctor: RecursiveCtor<'b, CharsCtx<'a>, Vec<Xml>>,
) -> impl Fn(&mut CharsCtx<'a>) -> Result<Vec<Xml>, Error> + 'b {
move |ctx| {
let alpha = neu::alphabetic()
.repeat_full()
.map(|v: &str| Ok(v.to_string()));
let s = alpha.quote("<", ">");
let e = alpha.quote("</", ">");
let c = alpha.quote("<", "/>").map(|v| Ok(Xml::Enclosed(v)));
let m = |((l, c), r): ((String, Vec<Xml>), String)| {
if l != r {
Err(Error::Uid(0))
} else {
Ok(Xml::Element { name: l, child: c })
}
};
ctx.ctor(&s.then(ctor.clone()).then(e).map(m).or(c).repeat(1..))
}
}
let xml = rec_parser(parser);
let ret = CharsCtx::new("<language><rust><linux/></rust><cpp><windows/></cpp></language>")
.ctor(&xml)?;
let chk = vec![Xml::Element {
name: "language".to_owned(),
child: vec![
Xml::Element {
name: "rust".to_owned(),
child: vec![Xml::Enclosed("linux".to_owned())],
},
Xml::Element {
name: "cpp".to_owned(),
child: vec![Xml::Enclosed("windows".to_owned())],
},
],
}];
assert_eq!(ret, chk);
Ok(())