1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
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<T> {
choices: Vec<(&'static str, Option<char>, T)>,
}
impl<'a, T> Parse<'a> for Branch<T> {
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<T> Branch<T> {
pub fn new() -> Branch<T> {
Branch { choices: Vec::new() }
}
pub fn add(&mut self, long: &'static str, short: Option<char>, res: T) {
self.choices.push((long, short, res));
}
}
|