diff --git a/Cargo.lock b/Cargo.lock index d3ee537..db0ed9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1250,8 +1250,8 @@ dependencies = [ [[package]] name = "crisp" -version = "0.1.0" -source = "git+https://git.tfcconnection.org/chris/crisp#c3abe2fe48dc891322548d4fa900062772486bd3" +version = "0.1.1" +source = "git+https://git.tfcconnection.org/chris/crisp#fa078e8d3fa9c0916f5da950eee896d4fa67a4eb" dependencies = [ "lazy_static", "miette", diff --git a/Cargo.toml b/Cargo.toml index 1468239..a64b5f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,5 +23,5 @@ ron = "0.8.1" sqlx = { version = "0.8.2", features = ["sqlite"] } dirs = "5.0.1" tokio = "1.41.1" -crisp = { git = "https://git.tfcconnection.org/chris/crisp" } +crisp = { git = "https://git.tfcconnection.org/chris/crisp", version = "0.1.1" } diff --git a/src/core/slide.rs b/src/core/slide.rs index 10f3cb7..c35b93f 100644 --- a/src/core/slide.rs +++ b/src/core/slide.rs @@ -53,25 +53,31 @@ impl TryFrom for Background { impl TryFrom for Background { type Error = ParseError; fn try_from(value: PathBuf) -> Result { - if let Ok(value) = value.canonicalize() { - let extension = value - .extension() - .unwrap_or_default() - .to_str() - .unwrap_or_default(); - match extension { - "jpg" | "png" | "webp" | "html" => Ok(Self { - path: value, - kind: BackgroundKind::Image, - }), - "mp4" | "mkv" | "webm" => Ok(Self { - path: value, - kind: BackgroundKind::Video, - }), - _ => Err(ParseError::NonBackgroundFile), + match value.canonicalize() { + Ok(value) => { + let extension = value + .extension() + .unwrap_or_default() + .to_str() + .unwrap_or_default(); + match extension { + "jpeg" | "jpg" | "png" | "webp" | "html" => { + Ok(Self { + path: value, + kind: BackgroundKind::Image, + }) + } + "mp4" | "mkv" | "webm" => Ok(Self { + path: value, + kind: BackgroundKind::Video, + }), + _ => Err(ParseError::NonBackgroundFile), + } + } + Err(e) => { + error!("Couldn't canonicalize: {e}"); + Err(ParseError::CannotCanonicalize) } - } else { - Err(ParseError::CannotCanonicalize) } } } @@ -80,7 +86,7 @@ impl TryFrom<&str> for Background { type Error = ParseError; fn try_from(value: &str) -> Result { let value = value.trim_start_matches("file://"); - if value.contains("~") { + if value.starts_with("~") { if let Some(home) = dirs::home_dir() { if let Some(home) = home.to_str() { let value = value.replace("~", home); @@ -91,6 +97,8 @@ impl TryFrom<&str> for Background { } else { Self::try_from(PathBuf::from(value)) } + } else if value.starts_with("./") { + Err(ParseError::CannotCanonicalize) } else { Self::try_from(PathBuf::from(value)) } @@ -290,22 +298,49 @@ fn lisp_to_text(lisp: &Value) -> impl Into { } } +// Need to return a Result here so that we can propogate +// errors and then handle them appropriately pub fn lisp_to_background(lisp: &Value) -> Background { match lisp { Value::List(list) => { + let kind = list[0].clone(); if let Some(source) = list.iter().position(|v| { v == &Value::Keyword(Keyword::from("source")) }) { let source = &list[source + 1]; match source { Value::String(s) => { - match Background::try_from(s.as_str()) { - Ok(background) => background, - Err(e) => { - error!( - "Couldn't load background: {e}" - ); - Background::default() + if s.starts_with("./") { + let Some(home) = dirs::home_dir() else { + panic!("Should always be there"); + }; + let Some(home) = home.to_str() else { + panic!("Should always be there"); + }; + let mut home = home.to_string(); + home.push_str("/"); + + let s = s.replace("./", &home); + dbg!(&s); + match Background::try_from(s.as_str()) { + Ok(background) => background, + Err(e) => { + dbg!(&e); + error!( + "Couldn't load background: {e}" + ); + Background::default() + } + } + } else { + match Background::try_from(s.as_str()) { + Ok(background) => background, + Err(e) => { + error!( + "Couldn't load background: {e}" + ); + Background::default() + } } } } diff --git a/src/core/songs.rs b/src/core/songs.rs index fa5367e..4c62f79 100644 --- a/src/core/songs.rs +++ b/src/core/songs.rs @@ -124,6 +124,7 @@ fn lisp_to_song(list: Vec) -> Song { let background = if let Some(background) = list.get(background_position) { + dbg!(&background); Some(slide::lisp_to_background(background)) } else { None @@ -156,7 +157,7 @@ fn lisp_to_song(list: Vec) -> Song { }; let ccli = if let Some(ccli) = list.get(ccli_position) { - Some(i32::from(ccli)) + Some(i32::from(ccli).to_string()) } else { None }; @@ -236,14 +237,19 @@ fn lisp_to_song(list: Vec) -> Song { let first_text_postiion = if let Some(pos) = list.iter().position(|v| match v { - Value::List(inner) => match &inner[0] { - Value::Symbol(Symbol(text)) => { - text.contains("v1") - || text.contains("text") - || text.contains("c1") - } - _ => false, - }, + Value::List(inner) => { + (match &inner[0] { + Value::Symbol(Symbol(text)) => { + text.contains("v1") + || text.contains("text") + || text.contains("c1") + } + _ => false, + } && match &inner[1] { + Value::String(_) => true, + _ => false, + }) + } _ => false, }) { pos @@ -253,11 +259,7 @@ fn lisp_to_song(list: Vec) -> Song { let lyric_elements = &list[first_text_postiion..]; - let mut lyric_list = if let Some(ref verse_order) = verse_order { - Vec::with_capacity(verse_order.capacity()) - } else { - vec![] - }; + let mut lyrics = vec![]; for element in lyric_elements { let Value::List(lyric) = element else { @@ -267,9 +269,9 @@ fn lisp_to_song(list: Vec) -> Song { continue; }; - let lyric = String::from(&lyric[1]); + let lyric = format!("{}{}", String::from(&lyric[1]), "\n"); let Some(ref verse_order) = verse_order else { - lyric_list.push(lyric); + lyrics.push(lyric); continue; }; @@ -280,10 +282,23 @@ fn lisp_to_song(list: Vec) -> Song { continue; }; - lyric_list.insert(verse_pos, lyric); + lyrics.insert(verse_pos, lyric); } - todo!() + let lyrics = lyrics.iter().flat_map(|s| s.chars()).collect(); + + Song { + id: 0, + title, + lyrics: Some(lyrics), + author, + ccli, + verse_order, + background, + font, + font_size, + ..Default::default() + } } pub async fn get_song_from_db( @@ -399,6 +414,8 @@ impl Song { #[cfg(test)] mod test { + use std::fs::read_to_string; + use super::*; use pretty_assertions::{assert_eq, assert_ne}; @@ -560,4 +577,20 @@ You saved my soul" font_size: Some(60) } } + + fn test_lisp_song() -> Value { + let lisp = read_to_string("./test_song.lisp").expect("oops"); + let lisp_value = crisp::reader::read(&lisp); + match lisp_value { + Value::List(v) => v.get(0).unwrap().clone(), + _ => Value::Nil, + } + } + + #[test] + pub fn test_lisp_conversion() { + let value = test_lisp_song(); + let song = Song::from(value); + assert!(false, "{:?}", song); + } } diff --git a/test_song.lisp b/test_song.lisp new file mode 100644 index 0000000..d99e1ba --- /dev/null +++ b/test_song.lisp @@ -0,0 +1,8 @@ +(song :author "Jordan Feliz" :ccli 97987 + :font "Quicksand" :font-size 80 + :title "The River" + :background (image :source "~/pics/wallpapers/nixorange.jpeg" :fit cover) + :verse-order (v1 c1 v2 c1) + (v1 "I'm going down to the river") + (c1 "Down to the river") + (v2 "Down to the river to pray ay ay!"))