summaryrefslogtreecommitdiffstats
path: root/src/poem/read
diff options
context:
space:
mode:
Diffstat (limited to 'src/poem/read')
-rw-r--r--src/poem/read/parse.rs45
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