pear/input/string.rs
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
pub use crate::input::{Input, ParserInfo};
impl<'a> Input for &'a str {
type Token = char;
type Slice = &'a str;
type Many = Self::Slice;
type Marker = &'a str;
type Context = &'a str;
/// Returns a copy of the current token, if there is one.
fn token(&mut self) -> Option<Self::Token> {
self.chars().next()
}
/// Returns a copy of the current slice of size `n`, if there is one.
fn slice(&mut self, n: usize) -> Option<Self::Slice> {
self.get(..n)
}
/// Checks if the current token fulfills `cond`.
fn peek<F>(&mut self, mut cond: F) -> bool
where F: FnMut(&Self::Token) -> bool
{
self.token().map(|t| cond(&t)).unwrap_or(false)
}
/// Checks if the current slice of size `n` (if any) fulfills `cond`.
fn peek_slice<F>(&mut self, n: usize, mut cond: F) -> bool
where F: FnMut(&Self::Slice) -> bool
{
self.slice(n).map(|s| cond(&s)).unwrap_or(false)
}
/// Checks if the current token fulfills `cond`. If so, the token is
/// consumed and returned. Otherwise, returns `None`.
fn eat<F>(&mut self, mut cond: F) -> Option<Self::Token>
where F: FnMut(&Self::Token) -> bool
{
if let Some(token) = self.token() {
if cond(&token) {
*self = &self[token.len_utf8()..];
return Some(token)
}
}
None
}
/// Checks if the current slice of size `n` (if any) fulfills `cond`. If so,
/// the slice is consumed and returned. Otherwise, returns `None`.
fn eat_slice<F>(&mut self, n: usize, mut cond: F) -> Option<Self::Slice>
where F: FnMut(&Self::Slice) -> bool
{
if let Some(slice) = self.slice(n) {
if cond(&slice) {
*self = &self[slice.len()..];
return Some(slice)
}
}
None
}
/// Takes tokens while `cond` returns true, collecting them into a
/// `Self::Many` and returning it.
fn take<F>(&mut self, mut cond: F) -> Self::Many
where F: FnMut(&Self::Token) -> bool
{
let mut consumed = 0;
for c in self.chars() {
if !cond(&c) { break; }
consumed += c.len_utf8();
}
let value = &self[..consumed];
*self = &self[consumed..];
value
}
/// Skips tokens while `cond` returns true. Returns the number of skipped
/// tokens.
fn skip<F>(&mut self, cond: F) -> usize
where F: FnMut(&Self::Token) -> bool
{
self.take(cond).len()
}
/// Returns `true` if there are at least `n` tokens remaining.
fn has(&mut self, n: usize) -> bool {
self.len() >= n
}
fn mark(&mut self, _info: &ParserInfo) -> Self::Marker {
*self
}
fn context(&mut self, mark: Self::Marker) -> Self::Context {
let consumed = mark.len() - self.len();
&mark[..consumed]
}
}