Plan parsing
This commit is contained in:
parent
00944b5db9
commit
df4cd420ad
1 changed files with 29 additions and 11 deletions
40
src/model.rs
40
src/model.rs
|
@ -2,6 +2,7 @@ mod song {
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, VecDeque},
|
collections::{BTreeMap, VecDeque},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
|
sync::OnceLock,
|
||||||
};
|
};
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
@ -19,7 +20,7 @@ mod song {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sequence of verse names.
|
/// Sequence of verse names.
|
||||||
pub type Plan = Vec<String>;
|
pub type Plan = VecDeque<String>;
|
||||||
|
|
||||||
pub struct Song {
|
pub struct Song {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -29,7 +30,7 @@ mod song {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Song {
|
impl Song {
|
||||||
pub fn plan(&self, plan_name: Option<String>) -> &Vec<String> {
|
pub fn plan(&self, plan_name: Option<String>) -> &VecDeque<String> {
|
||||||
plan_name
|
plan_name
|
||||||
.map(|plan_name| {
|
.map(|plan_name| {
|
||||||
self.other_plans
|
self.other_plans
|
||||||
|
@ -41,11 +42,15 @@ mod song {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SongParseError {
|
pub struct SourceRef {
|
||||||
EmptyString,
|
line_number: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
const REGEX_TWO_NEWLINES_WITH_ARBITRARY_SURROUNDING_WHITESPACE: &str = r"\s*[\n\r]\s*[\n\r]\s*";
|
#[derive(Debug)]
|
||||||
|
pub enum SongParseError {
|
||||||
|
EmptyString,
|
||||||
|
InvalidMetadata(SourceRef),
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for Song {
|
impl FromStr for Song {
|
||||||
type Err = SongParseError;
|
type Err = SongParseError;
|
||||||
|
@ -55,7 +60,8 @@ mod song {
|
||||||
return Err(SongParseError::EmptyString);
|
return Err(SongParseError::EmptyString);
|
||||||
}
|
}
|
||||||
|
|
||||||
let re = Regex::new(REGEX_TWO_NEWLINES_WITH_ARBITRARY_SURROUNDING_WHITESPACE).unwrap();
|
static HUNK_REGEX: OnceLock<Regex> = OnceLock::new();
|
||||||
|
let re = HUNK_REGEX.get_or_init(|| Regex::new(r"\s*[\n\r]\s*[\n\r]\s*").unwrap());
|
||||||
let mut hunks = VecDeque::new();
|
let mut hunks = VecDeque::new();
|
||||||
let mut last_end: usize = 0;
|
let mut last_end: usize = 0;
|
||||||
|
|
||||||
|
@ -68,14 +74,25 @@ mod song {
|
||||||
// process header
|
// process header
|
||||||
let mut header_lines = hunks.pop_front().unwrap().lines();
|
let mut header_lines = hunks.pop_front().unwrap().lines();
|
||||||
let name = header_lines.next().unwrap().trim().to_owned();
|
let name = header_lines.next().unwrap().trim().to_owned();
|
||||||
|
let mut other_plans = BTreeMap::new();
|
||||||
|
|
||||||
for line in header_lines {
|
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 }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// map(band2): slide1, slide2
|
// map(band2): slide1, slide2
|
||||||
// band2: slide1, slide2
|
// band2: slide1, slide2
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut verses = BTreeMap::new();
|
let mut verses = BTreeMap::new();
|
||||||
|
|
||||||
|
let mut default_plan = Plan::new();
|
||||||
|
|
||||||
// process verses
|
// process verses
|
||||||
for hunk in hunks {
|
for hunk in hunks {
|
||||||
let mut verse_contents = hunk;
|
let mut verse_contents = hunk;
|
||||||
|
@ -86,14 +103,15 @@ mod song {
|
||||||
} else {
|
} else {
|
||||||
format!("Generated Verse {}", verses.len() + 1).to_owned()
|
format!("Generated Verse {}", verses.len() + 1).to_owned()
|
||||||
};
|
};
|
||||||
verses.insert(verse_name, Verse::new(verse_contents.to_owned()));
|
verses.insert(verse_name.clone(), Verse::new(verse_contents.to_owned()));
|
||||||
|
default_plan.push_back(verse_name.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
name,
|
name,
|
||||||
verses,
|
verses,
|
||||||
other_plans: BTreeMap::new(),
|
other_plans,
|
||||||
default_plan: vec![],
|
default_plan,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,8 +135,8 @@ mod song {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
assert_eq!(song.verses.len(), 1);
|
assert_eq!(song.verses.len(), 1);
|
||||||
assert_eq!(song.default_plan.len(), 1);
|
|
||||||
assert_eq!(song.default_plan[0], "Generated Verse 1");
|
assert_eq!(song.default_plan[0], "Generated Verse 1");
|
||||||
|
assert_eq!(song.default_plan.len(), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue