working song translation from lisp

This commit is contained in:
Chris Cochrun 2024-12-05 22:27:37 -06:00
parent f69d465596
commit 8c29e7900a
5 changed files with 123 additions and 47 deletions

4
Cargo.lock generated
View file

@ -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",

View file

@ -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" }

View file

@ -53,25 +53,31 @@ impl TryFrom<String> for Background {
impl TryFrom<PathBuf> for Background {
type Error = ParseError;
fn try_from(value: PathBuf) -> Result<Self, Self::Error> {
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<Self, Self::Error> {
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<String> {
}
}
// 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()
}
}
}
}

View file

@ -124,6 +124,7 @@ fn lisp_to_song(list: Vec<Value>) -> 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<Value>) -> 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<Value>) -> 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<Value>) -> 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<Value>) -> 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<Value>) -> 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);
}
}

8
test_song.lisp Normal file
View file

@ -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!"))