Stuff
This commit is contained in:
parent
3dcfcb88a0
commit
3803df7221
4 changed files with 131 additions and 2 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -1036,6 +1036,7 @@ dependencies = [
|
||||||
"notify",
|
"notify",
|
||||||
"pathdiff",
|
"pathdiff",
|
||||||
"redact",
|
"redact",
|
||||||
|
"regex",
|
||||||
"serde",
|
"serde",
|
||||||
"sled",
|
"sled",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -1512,9 +1513,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.10.4"
|
version = "1.10.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
|
@ -31,6 +31,7 @@ maud = "0.26.0"
|
||||||
notify = "6.1.1"
|
notify = "6.1.1"
|
||||||
pathdiff = "0.2.1"
|
pathdiff = "0.2.1"
|
||||||
redact = { version = "0.1.10", features = ["serde"] }
|
redact = { version = "0.1.10", features = ["serde"] }
|
||||||
|
regex = { version = "1.10.5" }
|
||||||
serde = "1.0.201"
|
serde = "1.0.201"
|
||||||
sled = { version = "0.34.7", features = [] }
|
sled = { version = "0.34.7", features = [] }
|
||||||
thiserror = "1.0.60"
|
thiserror = "1.0.60"
|
||||||
|
|
|
@ -2,6 +2,7 @@ mod auth;
|
||||||
mod cli;
|
mod cli;
|
||||||
mod db;
|
mod db;
|
||||||
mod file_watcher;
|
mod file_watcher;
|
||||||
|
mod model;
|
||||||
mod observe;
|
mod observe;
|
||||||
mod partials;
|
mod partials;
|
||||||
mod prelude;
|
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