Stuff
This commit is contained in:
parent
3dcfcb88a0
commit
3803df7221
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -1036,6 +1036,7 @@ dependencies = [
|
|||
"notify",
|
||||
"pathdiff",
|
||||
"redact",
|
||||
"regex",
|
||||
"serde",
|
||||
"sled",
|
||||
"thiserror",
|
||||
|
@ -1512,9 +1513,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.4"
|
||||
version = "1.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
||||
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
|
|
@ -31,6 +31,7 @@ maud = "0.26.0"
|
|||
notify = "6.1.1"
|
||||
pathdiff = "0.2.1"
|
||||
redact = { version = "0.1.10", features = ["serde"] }
|
||||
regex = { version = "1.10.5" }
|
||||
serde = "1.0.201"
|
||||
sled = { version = "0.34.7", features = [] }
|
||||
thiserror = "1.0.60"
|
||||
|
|
|
@ -2,6 +2,7 @@ mod auth;
|
|||
mod cli;
|
||||
mod db;
|
||||
mod file_watcher;
|
||||
mod model;
|
||||
mod observe;
|
||||
mod partials;
|
||||
mod prelude;
|
||||
|
|
126
src/model.rs
Normal file
126
src/model.rs
Normal file
|
@ -0,0 +1,126 @@
|
|||
mod song {
|
||||
use std::{
|
||||
collections::{BTreeMap, VecDeque},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
pub struct Verse {
|
||||
// pub background: String, // url
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
/// Sequence of verse names.
|
||||
pub type SongMap = Vec<String>;
|
||||
|
||||
pub struct Song {
|
||||
pub name: String,
|
||||
pub verses: BTreeMap<String, Verse>,
|
||||
pub other_maps: BTreeMap<String, SongMap>,
|
||||
pub default_map: SongMap,
|
||||
}
|
||||
|
||||
impl Song {
|
||||
pub fn song_map(&self, map_name: Option<String>) -> &Vec<String> {
|
||||
map_name
|
||||
.map(|map_name| self.other_maps.get(&map_name).unwrap_or(&self.default_map))
|
||||
.unwrap_or(&self.default_map)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SongParseError {
|
||||
EmptyString,
|
||||
}
|
||||
|
||||
const REGEX_TWO_NEWLINES_WITH_ARBITRARY_SURROUNDING_WHITESPACE: &str = r"\s*[\n\r]\s*[\n\r]\s*";
|
||||
|
||||
impl FromStr for Song {
|
||||
type Err = SongParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s == "" {
|
||||
return Err(SongParseError::EmptyString);
|
||||
}
|
||||
|
||||
let re = Regex::new(REGEX_TWO_NEWLINES_WITH_ARBITRARY_SURROUNDING_WHITESPACE).unwrap();
|
||||
let mut hunks = VecDeque::new();
|
||||
let mut last_end: usize = 0;
|
||||
|
||||
for m in re.find_iter(s) {
|
||||
hunks.push_back(&s[last_end..m.start()]);
|
||||
last_end = m.end();
|
||||
}
|
||||
hunks.push_back(&s[last_end..s.len() - 1]);
|
||||
|
||||
// process header
|
||||
let mut header_lines = hunks.pop_front().unwrap().lines();
|
||||
let name = header_lines.next().unwrap().trim().to_owned();
|
||||
|
||||
for line in header_lines {
|
||||
// map(band2): slide1, slide2
|
||||
// band2: slide1, slide2
|
||||
}
|
||||
|
||||
let mut verses = BTreeMap::new();
|
||||
|
||||
// process verses
|
||||
for hunk in hunks {
|
||||
let mut verse_contents = hunk;
|
||||
let first_line = &hunk[0..hunk.find('\n').unwrap_or(hunk.len())];
|
||||
let verse_name: String = if let Some(i) = first_line.find(':') {
|
||||
String::from(&first_line[0..i])
|
||||
} else {
|
||||
format!("Generated Verse {}", verses.len()).to_owned()
|
||||
};
|
||||
verses.insert(verse_name, verse_content);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
name,
|
||||
verses,
|
||||
other_maps: BTreeMap::new(),
|
||||
default_map: vec![],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
mod test {
|
||||
use super::Song;
|
||||
|
||||
#[test]
|
||||
fn parses_simple_song() {
|
||||
let song: Song = r#"Song Title
|
||||
|
||||
A verse"#
|
||||
.parse()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(song.name, "Song Title");
|
||||
assert_eq!(song.verses.len(), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod display {
|
||||
use super::song::{Song, SongMap};
|
||||
|
||||
pub struct PlaylistEntry {
|
||||
pub song: Song,
|
||||
pub map: SongMap,
|
||||
}
|
||||
|
||||
pub struct PlaylistVerseRef {
|
||||
pub song_index: usize,
|
||||
pub song_map: String,
|
||||
pub map_verse_index: usize,
|
||||
}
|
||||
|
||||
pub struct Display {
|
||||
pub playlist: Vec<(Song, Option<String>)>,
|
||||
pub current: PlaylistVerseRef,
|
||||
pub frozen_at: Option<PlaylistVerseRef>,
|
||||
pub blanked: bool,
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue