/// 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, } }; } /// Keep pushing to the [Word][super::super::elements::word::Word] stack /// /// If a [Rune::String][super::super::elements::rune::Rune] character is found, /// stop interpreting special characters, and push all characters to the /// [Word][super::super::elements::word::Word] stack, until the corresponding /// [Rune::String][super::super::elements::rune::Rune] character is found. #[macro_export] macro_rules! string { ($chars:expr, $j:expr, $i:expr, $c:expr, $word:expr) => { let token = $c; loop { match $chars.next() { None => return Err(Mishap::PartialMishap($j, $i, $c)), Some(c) if c == token => break, Some(c) => { $word.push(c); $i += 1; } } } continue; }; } /// Same as the [string!] macro, but don't `continue` #[macro_export] macro_rules! poem { ($chars:expr, $j:expr, $i:expr, $c:expr, $verse:expr, $word:expr) => { let token = $c; let mut poetry = Word::new(); loop { match $chars.next() { None => return Err(Mishap::PartialMishap($j, $i, $c)), Some(c) if c == token => break, Some(c) => { poetry.push(c); $i += 1; } } } let sp = Poem::read(poetry.iter().collect()); let sp = match sp { Ok(sp) => sp, Err(e) => return Err(e), }; $verse.poems.push(sp); $word.push('\x0b'); }; }