From 908cd899695ba07bfc47645c532337958ee208d7 Mon Sep 17 00:00:00 2001 From: Rory Dudley Date: Sun, 12 May 2024 23:53:57 -0600 Subject: Fix regression with aliases Fixed a regression that was introduced in: 1415c8f9b89699000ef8d864ff8f0e1bebca4a5f. Moving aliases to read() broke how pipes worked. This commit removes the troublesome append!() macro, and replaces it with some logic in the add() function (impl Appendable for Poem). --- src/poem/read.rs | 79 +++++++++++++++++++++++++++++++++++++++++--------- src/poem/read/parse.rs | 28 ------------------ 2 files changed, 65 insertions(+), 42 deletions(-) (limited to 'src/poem') 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 diff --git a/src/poem/read/parse.rs b/src/poem/read/parse.rs index 58c8fde..7b01d85 100644 --- a/src/poem/read/parse.rs +++ b/src/poem/read/parse.rs @@ -84,31 +84,3 @@ macro_rules! poem { $word.push('\x0b'); }; } - -/// Append a verse to the poem -/// -/// Append a verse to poem, first checking for aliases in the environment, and -/// processing the alias first, if necessary. -#[macro_export] -macro_rules! append { - ($poem:expr, $last:expr, $meter:expr, $verse:expr, $env:expr) => { - if !$verse.is_empty() { - match $env.aliases.get(&$verse.verb()) { - Some(alias) => { - let alias = alias.to_string(); - let mut poem = Poem::read(alias, $env)?; - let len = poem.len(); - for (i, verse) in poem.iter_mut().enumerate() { - if $verse.clause().is_some() && i + 1 == len { - verse.stanza.append(&mut $verse.clause().unwrap()); - } - $poem.push(verse.clone()); - } - } - None => { - $poem.add(&mut $verse, $last, $meter); - } - } - } - }; -} -- cgit v1.2.3