Skip to main content

marks/
parser.rs

1use std::vec::IntoIter;
2use std::iter::Peekable;
3
4pub trait GentleIterator<I: Iterator> {
5    fn take_until<F>(&mut self, predicate: F) -> IntoIter<I::Item>
6        where F: Fn(&I::Item) -> bool;
7}
8
9impl<I: Iterator> GentleIterator<I> for Peekable<I> {
10    fn take_until<F>(&mut self, predicate: F) -> IntoIter<I::Item>
11        where F: Fn(&I::Item) -> bool {
12
13        let mut v: Vec<I::Item> = vec![];
14        while self.peek().map_or(false, &predicate) {
15            v.push(self.next().unwrap());
16        }
17
18        v.into_iter()
19    }
20}
21
22pub fn check<F,I>(iter: &mut Peekable<I>, fun: F) -> bool
23where F: Fn(char) -> bool,
24      I: Iterator<Item = char> {
25    if let Some(&x) = iter.peek() {
26        fun(x)
27    } else {
28        false
29    }
30}
31
32pub fn check_chr<I>(iter: &mut Peekable<I>, chr: char) -> bool
33where I: Iterator<Item = char> {
34    check(iter, |x| x == chr)
35}
36
37pub fn parse_around<I>(iter: &mut Peekable<I>, beg: char, end: char) -> Option<String>
38where I: Iterator<Item = char> {
39    if !check_chr(iter, beg) {
40        return None
41    }
42
43    iter.next(); // Consume beg
44    let value = iter.take_until(|c| *c != end).collect();
45    iter.next(); // Consume end
46    parse_whitespace(iter);
47
48    Some(value)
49}
50
51pub fn parse_prefixed<I>(iter: &mut Peekable<I>, chr: char) -> Option<String>
52where I: Iterator<Item = char> {
53    if !check_chr(iter, chr) {
54        return None
55    }
56
57    iter.next(); // Consume the opening chr
58    let value = iter.take_until(|c| *c != ' ').collect();
59    parse_whitespace(iter);
60
61    Some(value)
62}
63
64pub fn parse_plain<I>(iter: &mut Peekable<I>) -> Option<String>
65where I: Iterator<Item = char> {
66    if let Some(&_x) = iter.peek() {
67        let value = iter.take_until(|c| *c != ' ').collect();
68        parse_whitespace(iter);
69
70        return Some(value)
71    }
72
73    None
74}
75
76pub fn parse_whitespace<I>(iter: &mut Peekable<I>) -> bool
77where I: Iterator<Item = char> {
78    if check_chr(iter, ' ') || check_chr(iter, '\n') || check_chr(iter, '\t') {
79        iter.next();
80        true
81    } else {
82        false
83    }
84}