diff options
Diffstat (limited to 'src/poem/read/parse.rs')
-rw-r--r-- | src/poem/read/parse.rs | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/src/poem/read/parse.rs b/src/poem/read/parse.rs index 7b01d85..0dbdf0f 100644 --- a/src/poem/read/parse.rs +++ b/src/poem/read/parse.rs @@ -1,20 +1,43 @@ +use crate::poem::elements::rune::Rune; +use std::str::Chars; + /// Look ahead one character in the input /// /// May need to look ahead one character in the input string to determine the /// proper rune. For instance `&`, vs `&&`. -#[macro_export] -macro_rules! next { - ($chars:expr, $i:expr, $otherwise:expr, $rune:expr, $ahead:expr) => { - match $chars.clone().peekable().peek() { - Some(c) if *c == $ahead => { - $chars.next(); - $i += 1; - $rune - } - Some(_) => $otherwise, - None => $otherwise, +/// +/// # Arguments: +/// `chars` - An iterator over the characters in the poem +/// `i` - A counter to keep track of the current column +/// `otherwise` - The rune to return if there are no matches +/// `ahead` - A list of tuples, containing characters to look ahead for, +/// alongside which rune they correspond to +/// +/// # Examples: +/// ``` +/// next(&mut chars, &mut i, Rune::Write, vec![('>', Rune::Addendum)]) +/// next(&mut chars, &mut i, Rune::Quiet, vec![('&', Rune::And)]) +/// ``` +pub fn next(chars: &mut Chars, i: &mut usize, otherwise: Rune, ahead: Vec<(char, Rune)>) -> Rune { + // Try to get the next character in the poem + let next = match chars.peekable().peek() { + Some(c) => *c, + None => { + return otherwise; } }; + + // Check if that next character matches any characters in ahead + for (c, rune) in ahead.iter() { + if next == *c { + chars.into_iter().next(); + *i += 1; + return *rune; + } + } + + // If it doesn't match, return the default + otherwise } /// Keep pushing to the [Word][super::super::elements::word::Word] stack |