pear/input/
string.rs

1pub use crate::input::{Input, ParserInfo};
2
3impl<'a> Input for &'a str {
4    type Token = char;
5    type Slice = &'a str;
6    type Many = Self::Slice;
7
8    type Marker = &'a str;
9    type Context = &'a str;
10
11    /// Returns a copy of the current token, if there is one.
12    fn token(&mut self) -> Option<Self::Token> {
13        self.chars().next()
14    }
15
16    /// Returns a copy of the current slice of size `n`, if there is one.
17    fn slice(&mut self, n: usize) -> Option<Self::Slice> {
18        self.get(..n)
19    }
20
21    /// Checks if the current token fulfills `cond`.
22    fn peek<F>(&mut self, mut cond: F) -> bool
23        where F: FnMut(&Self::Token) -> bool
24    {
25        self.token().map(|t| cond(&t)).unwrap_or(false)
26    }
27
28    /// Checks if the current slice of size `n` (if any) fulfills `cond`.
29    fn peek_slice<F>(&mut self, n: usize, mut cond: F) -> bool
30        where F: FnMut(&Self::Slice) -> bool
31    {
32        self.slice(n).map(|s| cond(&s)).unwrap_or(false)
33    }
34
35    /// Checks if the current token fulfills `cond`. If so, the token is
36    /// consumed and returned. Otherwise, returns `None`.
37    fn eat<F>(&mut self, mut cond: F) -> Option<Self::Token>
38        where F: FnMut(&Self::Token) -> bool
39    {
40        if let Some(token) = self.token() {
41            if cond(&token) {
42                *self = &self[token.len_utf8()..];
43                return Some(token)
44            }
45        }
46
47        None
48    }
49
50    /// Checks if the current slice of size `n` (if any) fulfills `cond`. If so,
51    /// the slice is consumed and returned. Otherwise, returns `None`.
52    fn eat_slice<F>(&mut self, n: usize, mut cond: F) -> Option<Self::Slice>
53        where F: FnMut(&Self::Slice) -> bool
54    {
55        if let Some(slice) = self.slice(n) {
56            if cond(&slice) {
57                *self = &self[slice.len()..];
58                return Some(slice)
59            }
60        }
61
62        None
63    }
64
65    /// Takes tokens while `cond` returns true, collecting them into a
66    /// `Self::Many` and returning it.
67    fn take<F>(&mut self, mut cond: F) -> Self::Many
68        where F: FnMut(&Self::Token) -> bool
69    {
70        let mut consumed = 0;
71        for c in self.chars() {
72            if !cond(&c) { break; }
73            consumed += c.len_utf8();
74        }
75
76        let value = &self[..consumed];
77        *self = &self[consumed..];
78        value
79    }
80
81    /// Skips tokens while `cond` returns true. Returns the number of skipped
82    /// tokens.
83    fn skip<F>(&mut self, cond: F) -> usize
84        where F: FnMut(&Self::Token) -> bool
85    {
86        self.take(cond).len()
87    }
88
89    /// Returns `true` if there are at least `n` tokens remaining.
90    fn has(&mut self, n: usize) -> bool {
91        self.len() >= n
92    }
93
94    fn mark(&mut self, _info: &ParserInfo) -> Self::Marker {
95        *self
96    }
97
98    fn context(&mut self, mark: Self::Marker) -> Self::Context {
99        let consumed = mark.len() - self.len();
100        &mark[..consumed]
101    }
102}