diff options
Diffstat (limited to 'src/poem/read.rs')
-rw-r--r-- | src/poem/read.rs | 79 |
1 files changed, 65 insertions, 14 deletions
diff --git a/src/poem/read.rs b/src/poem/read.rs index 3578a92..875bf76 100644 --- a/src/poem/read.rs +++ b/src/poem/read.rs @@ -5,7 +5,7 @@ use super::{ use core::fmt; mod parse; use crate::compose::Environment; -use crate::{append, next, poem, remark, string}; +use crate::{next, poem, remark, string}; #[derive(Debug, PartialEq, Eq)] pub enum Mishap { @@ -41,7 +41,13 @@ impl fmt::Display for Mishap { /// A [Poem] can add more [Verse]s to itself trait Appendable { type Type; - fn add(&mut self, verse: &mut Self::Type, meter: Rune, last: Rune); + fn add( + &mut self, + verse: &mut Self::Type, + meter: Rune, + last: Rune, + env: &Environment, + ) -> Result<(), Mishap>; } impl Appendable for Poem { @@ -51,20 +57,65 @@ impl Appendable for Poem { /// /// Push a [Verse] to the [Poem] after checking that the [Verse] is not /// empty. Also sets the meter of the [Verse]. - fn add(&mut self, verse: &mut Self::Type, last: Rune, meter: Rune) { + fn add( + &mut self, + verse: &mut Self::Type, + last: Rune, + meter: Rune, + env: &Environment, + ) -> Result<(), Mishap> { if verse.is_empty() { - return; + return Ok(()); } - // Check the meter - verse.meter = meter; - if last == Rune::Couplet || meter == Rune::Couplet { - verse.couplet = true; + // Check for aliases + match env.aliases.get(&verse.verb()) { + Some(alias) => { + // Interpret the alias (could be a complex poem) + let mut poem = Poem::read(alias.to_string(), env)?; + + // Try and get the last verse + let lv = match poem.last_mut() { + Some(lv) => lv, + None => unreachable!(), // Should be caught by a Mishap above + }; + + // If the verse has a clause, add it to the last verse in + // the poem from the alias + if verse.clause().is_some() { + for word in verse.clause().unwrap().iter() { + lv.stanza.push(word.to_string()); + } + } + + // Check the meter + lv.meter = meter; + if last == Rune::Couplet || meter == Rune::Couplet { + verse.couplet = true; + } + + // Push verse(s) + for v in poem.iter() { + self.push(v.clone()); + } + } + None => { + // Check the meter + verse.meter = meter; + if last == Rune::Couplet || meter == Rune::Couplet { + verse.couplet = true; + } + + // Push verse(s) + self.push(verse.clone()); + } } - // Push verse(s) and clear the current verse stack - self.push(verse.clone()); + // Clear the current verse stack verse.clear(); + + // Unit + Ok(()) } } @@ -127,8 +178,8 @@ impl Readable for Poem { } // Push the verse and break - // poem.add(&mut verse, last, Rune::None); - append!(poem, last, Rune::None, verse, env); + poem.add(&mut verse, last, Rune::None, env)?; + // append!(poem, last, Rune::None, verse, env); break; } }; @@ -232,8 +283,8 @@ impl Readable for Poem { // These meters indicate the end of a verse Rune::Couplet | Rune::Quiet | Rune::And | Rune::Continue => { verse.add(&mut word); - // poem.add(&mut verse, last, rune); - append!(poem, last, rune, verse, env); + poem.add(&mut verse, last, rune, env)?; + // append!(poem, last, rune, verse, env); } // Interpret ~ as $HOME |