From 9bf90e32b1d6edb4777cf845b1f964b778fd7fb8 Mon Sep 17 00:00:00 2001 From: Daniel Flanagan Date: Sat, 6 Jul 2024 18:10:00 -0500 Subject: [PATCH] Parses plans --- src/model.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/src/model.rs b/src/model.rs index f9e9106..1f81562 100644 --- a/src/model.rs +++ b/src/model.rs @@ -72,16 +72,28 @@ mod song { hunks.push_back(&s[last_end..s.len()]); // process header - let mut header_lines = hunks.pop_front().unwrap().lines(); + let mut header_lines = hunks.pop_front().unwrap().lines().map(|s| s.trim()); let name = header_lines.next().unwrap().trim().to_owned(); let mut other_plans = BTreeMap::new(); for (line_number, line) in header_lines.enumerate() { - if line.starts_with("map(") { - match line.find(":") { - Some(i) => {} - None => { - return Err(SongParseError::InvalidMetadata(SourceRef { line_number })) + if line.starts_with("plan(") { + if let Some(end) = line.find(")") { + match line[end..].find(":") { + Some(i) => { + let plan_name = &line[5..end]; + let entries: VecDeque = line[(end + i + 1)..] + .trim() + .split(',') + .map(|s| s.trim().to_owned()) + .collect(); + other_plans.insert(plan_name.to_owned(), entries); + } + None => { + return Err(SongParseError::InvalidMetadata(SourceRef { + line_number, + })); + } } } } @@ -117,6 +129,8 @@ mod song { } mod test { + use std::collections::VecDeque; + use super::{Song, Verse}; #[test] @@ -138,6 +152,36 @@ mod song { assert_eq!(song.default_plan[0], "Generated Verse 1"); assert_eq!(song.default_plan.len(), 1); } + + #[test] + fn parses_song_with_plan() { + let song: Song = r#"Song Title + plan(another_plan): Generated Verse 1, Generated Verse 1, Generated Verse 1 + + A verse"# + .parse() + .unwrap(); + + assert_eq!(song.name, "Song Title"); + assert_eq!( + song.verses.get("Generated Verse 1"), + Some(&Verse { + content: "A verse".to_owned() + }) + ); + assert_eq!(song.verses.len(), 1); + assert_eq!(song.default_plan[0], "Generated Verse 1"); + assert_eq!(song.default_plan.len(), 1); + dbg!(&song.other_plans); + assert_eq!( + song.other_plans.get("another_plan"), + Some(&VecDeque::from(vec![ + "Generated Verse 1".to_owned(), + "Generated Verse 1".to_owned(), + "Generated Verse 1".to_owned() + ])) + ); + } } }