extern crate pegtastic; pegtastic::parser!( grammar parse() for str { pub rule dec_byte() -> u8 = match_str:$(['0'..='9']*<,3>) {? let val: u64 = match_str.parse().unwrap(); // only let this rule match if the value is in range 0..255 if val <= 255 { Ok(val as u8) } else { // the message explains what the rule expected and is used in the parse error Err("decimal byte") } } rule tag() -> &'input str = $(['a'..='z']+) pub rule xml() = "<" open:tag() ">" xml()* "" {? if open == close { Ok(()) } else { // TODO this has to be a `&'static str`, so we can't use a dynamic string Err("matching close tag") } } }); fn main() { assert_eq!(parse::dec_byte("0"), Ok(0)); assert_eq!(parse::dec_byte("255"), Ok(255)); assert_eq!(parse::dec_byte("1"), Ok(1)); assert!(parse::dec_byte("256").is_err()); assert!(parse::dec_byte("1234").is_err()); assert!(parse::xml("").is_ok()); assert!(parse::xml("").is_ok()); assert!(parse::xml("").is_err()); assert!(parse::xml("").is_err()); }