use super::{CharSeq, ParserResult, Parser, ParserHook};
use std::marker::PhantomData;
pub struct FunctionWrapper<F, T> {
func: F,
phantom: PhantomData<T>
}
impl<F, T> Parser<T> for FunctionWrapper<F, T> where F: Fn(&mut CharSeq) -> ParserResult<T> {
fn _parse(&self, cs: &mut CharSeq) -> ParserResult<T> {
(self.func)(cs)
}
}
impl<F, T> ParserHook for FunctionWrapper<F, T> where F: Fn(&mut CharSeq) -> ParserResult<T> {
fn hook(&self, cs: &mut CharSeq) {
(self.func)(cs);
}
}
pub fn wrap<F, T>(f: F) -> FunctionWrapper<F, T> where F: Fn(&mut CharSeq) -> ParserResult<T> {
FunctionWrapper{func: f, phantom:PhantomData}
}
#[cfg(test)]
#[allow(unused_variables)]
#[allow(unused_imports)]
mod tests {
use super::wrap;
use super::super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
fn some_parser(cs: &mut CharSeq) -> ParserResult<Vec<String>> {
let x = "abc";
let y = "def";
let z = "ghi";
cs.accept(&x).and_then(|a|
cs.accept(&y).and_then(|b|
cs.accept(&z).map(|c| {
vec!(a.to_string(), b.to_string(), c.to_string())
}
)))
}
#[test]
fn test_wrap1() {
let mut cs = CharSeq::new("abcdefghi", "");
let w = wrap(some_parser);
match cs.accept(&w) {
Succ(x) => assert_eq!(x, vec!("abc".to_string(), "def".to_string(), "ghi".to_string())),
Fail(m, l) => assert!(false, "failed"),
Error(m, l) => assert!(false, "error")
}
}
#[test]
fn test_wrap2() {
let w = wrap(some_parser);
let mut cs = CharSeq::new("abcdefghixxxabcdefghi", "");
cs.add_hook(&w);
match cs.accept(&"xxx") {
Succ(x) => assert_eq!(x.as_slice(), "xxx"),
Fail(m, l) => assert!(false, "failed"),
Error(m, l) => assert!(false, "error")
}
}
}