pub enum ParseResult<'a, T> { Success(T, &'a str), Failure(String), } pub trait Parse<'a> { type Res; fn parse(self, input: &'a str) -> ParseResult<'a, Self::Res>; } pub struct Text(String); impl<'a> Parse<'a> for Text { type Res = Text; fn parse(self, input: &'a str) -> ParseResult<'a, Text> { let mut value = String::new(); let mut it = input.chars(); let mut escape_next = false; while let Some(c) = it.next() { if c == '\\' && !escape_next { escape_next = true; continue; } else if c == ';' { break; } value.push(c); escape_next = false; } ParseResult::Success(Text(value), it.as_str()) } } pub struct Branch { choices: Vec<(&'static str, Option, T)>, } impl<'a, T> Parse<'a> for Branch { type Res = T; fn parse(self, input: &'a str) -> ParseResult<'a, T> { let choices: Vec<&'static str> = self.choices.iter().map(|x| x.0).collect(); for (long, short_op, res) in self.choices { let rest = if input.starts_with(long) { Some(&input[long.len()..]) } else if let Some(short) = short_op { if input.starts_with(short) { Some(&input[1..]) } else { None } } else { None }; if let Some(rest) = rest { return ParseResult::Success(res, rest); } } return ParseResult::Failure(format!("Expected one of [{}]", choices.join(", "))); } } impl Branch { pub fn new() -> Branch { Branch { choices: Vec::new() } } pub fn add(&mut self, long: &'static str, short: Option, res: T) { self.choices.push((long, short, res)); } }