updating the core for actual builds and working tests
This commit is contained in:
parent
e82a9c161b
commit
a94ad65914
|
@ -1,11 +1,13 @@
|
|||
use super::model::Model;
|
||||
use miette::{Result, miette, IntoDiagnostic};
|
||||
use miette::{miette, IntoDiagnostic, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{query_as, SqliteConnection};
|
||||
use std::path::PathBuf;
|
||||
use tracing::error;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, PartialEq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Image {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
|
@ -26,12 +28,17 @@ impl Model<Image> {
|
|||
let _ = self.add_item(image);
|
||||
}
|
||||
}
|
||||
Err(e) => error!("There was an error in converting images: {e}"),
|
||||
Err(e) => {
|
||||
error!("There was an error in converting images: {e}")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_image_from_db(database_id: i32, db: &mut SqliteConnection) -> Result<Image> {
|
||||
pub async fn get_image_from_db(
|
||||
database_id: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Image> {
|
||||
Ok(query_as!(Image, r#"SELECT title as "title!", file_path as "path!", id as "id: i32" from images where id = ?"#, database_id).fetch_one(db).await.into_diagnostic()?)
|
||||
}
|
||||
|
||||
|
@ -52,7 +59,7 @@ mod test {
|
|||
pub async fn test_db_and_model() {
|
||||
let mut image_model: Model<Image> = Model {
|
||||
items: vec![],
|
||||
db: crate::core::model::get_db().await
|
||||
db: crate::core::model::get_db().await,
|
||||
};
|
||||
image_model.load_from_db().await;
|
||||
dbg!(&image_model.items);
|
||||
|
@ -70,16 +77,26 @@ mod test {
|
|||
let image = test_image("A new image".into());
|
||||
let mut image_model: Model<Image> = Model {
|
||||
items: vec![],
|
||||
db: crate::core::model::get_db().await
|
||||
db: crate::core::model::get_db().await,
|
||||
};
|
||||
let result = image_model.add_item(image.clone());
|
||||
let new_image = test_image("A newer image".into());
|
||||
match result {
|
||||
Ok(_) => {
|
||||
assert_eq!(&image, image_model.find(|i| i.id == 0).unwrap());
|
||||
assert_ne!(&new_image, image_model.find(|i| i.id == 0).unwrap());
|
||||
assert_eq!(
|
||||
&image,
|
||||
image_model.find(|i| i.id == 0).unwrap()
|
||||
);
|
||||
assert_ne!(
|
||||
&new_image,
|
||||
image_model.find(|i| i.id == 0).unwrap()
|
||||
);
|
||||
}
|
||||
Err(e) => assert!(false, "There was an error adding the image: {:?}", e),
|
||||
Err(e) => assert!(
|
||||
false,
|
||||
"There was an error adding the image: {:?}",
|
||||
e
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use super::presentations::PresKind;
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub enum ServiceItemKind {
|
||||
#[default]
|
||||
Song,
|
||||
|
@ -22,7 +24,9 @@ impl std::fmt::Display for ServiceItemKind {
|
|||
Self::Video => "video".to_owned(),
|
||||
Self::Presentation(PresKind::Html) => "html".to_owned(),
|
||||
Self::Presentation(PresKind::Pdf) => "pdf".to_owned(),
|
||||
Self::Presentation(PresKind::Generic) => "presentation".to_owned(),
|
||||
Self::Presentation(PresKind::Generic) => {
|
||||
"presentation".to_owned()
|
||||
}
|
||||
Self::Content => "content".to_owned(),
|
||||
};
|
||||
write!(f, "{s}")
|
||||
|
@ -36,7 +40,9 @@ impl TryFrom<String> for ServiceItemKind {
|
|||
"song" => Ok(Self::Song),
|
||||
"image" => Ok(Self::Image),
|
||||
"video" => Ok(Self::Video),
|
||||
"presentation" => Ok(Self::Presentation(PresKind::Generic)),
|
||||
"presentation" => {
|
||||
Ok(Self::Presentation(PresKind::Generic))
|
||||
}
|
||||
"html" => Ok(Self::Presentation(PresKind::Html)),
|
||||
"pdf" => Ok(Self::Presentation(PresKind::Pdf)),
|
||||
"content" => Ok(Self::Content),
|
||||
|
@ -51,7 +57,9 @@ impl From<ServiceItemKind> for String {
|
|||
ServiceItemKind::Song => "song".to_owned(),
|
||||
ServiceItemKind::Video => "video".to_owned(),
|
||||
ServiceItemKind::Image => "image".to_owned(),
|
||||
ServiceItemKind::Presentation(_) => "presentation".to_owned(),
|
||||
ServiceItemKind::Presentation(_) => {
|
||||
"presentation".to_owned()
|
||||
}
|
||||
ServiceItemKind::Content => "content".to_owned(),
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +73,10 @@ pub enum ParseError {
|
|||
impl Error for ParseError {}
|
||||
|
||||
impl Display for ParseError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
fn fmt(
|
||||
&self,
|
||||
f: &mut std::fmt::Formatter<'_>,
|
||||
) -> std::fmt::Result {
|
||||
let message = match self {
|
||||
Self::UnknownType => "The type does not exist. It needs to be one of 'song', 'video', 'image', 'presentation', or 'content'",
|
||||
};
|
||||
|
|
|
@ -142,9 +142,11 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_list() {
|
||||
let lisp = read_to_string("./test_presentation.lisp").expect("oops");
|
||||
let lisp =
|
||||
read_to_string("./test_presentation.lisp").expect("oops");
|
||||
println!("{lisp}");
|
||||
let mut parser = Parser::from_str_custom(&lisp, Options::elisp());
|
||||
let mut parser =
|
||||
Parser::from_str_custom(&lisp, Options::elisp());
|
||||
for atom in parser.value_iter() {
|
||||
match atom {
|
||||
Ok(atom) => {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
pub mod images;
|
||||
pub mod kinds;
|
||||
pub mod lisp;
|
||||
pub mod model;
|
||||
pub mod presentations;
|
||||
pub mod service_items;
|
||||
pub mod slide;
|
||||
pub mod songs;
|
||||
pub mod videos;
|
||||
pub mod model;
|
||||
|
|
|
@ -71,9 +71,7 @@ pub async fn get_db() -> SqliteConnection {
|
|||
data.push("library-db.sqlite3");
|
||||
let mut db_url = String::from("sqlite://");
|
||||
db_url.push_str(data.to_str().unwrap());
|
||||
SqliteConnection::connect(&db_url)
|
||||
.await
|
||||
.expect("problems")
|
||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||
}
|
||||
|
||||
pub trait Modeling {
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
use miette::{miette, Result, IntoDiagnostic};
|
||||
use miette::{miette, IntoDiagnostic, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{prelude::FromRow, query, sqlite::SqliteRow, Row, SqliteConnection};
|
||||
use sqlx::{
|
||||
prelude::FromRow, query, sqlite::SqliteRow, Row, SqliteConnection,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
use tracing::error;
|
||||
|
||||
use super::model::Model;
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub enum PresKind {
|
||||
Html,
|
||||
#[default]
|
||||
|
@ -14,7 +18,9 @@ pub enum PresKind {
|
|||
Generic,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Presentation {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
|
@ -75,7 +81,9 @@ impl Model<Presentation> {
|
|||
});
|
||||
}
|
||||
}
|
||||
Err(e) => error!("There was an error in converting presentations: {e}"),
|
||||
Err(e) => error!(
|
||||
"There was an error in converting presentations: {e}"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,10 +122,12 @@ mod test {
|
|||
async fn test_db_and_model() {
|
||||
let mut presentation_model: Model<Presentation> = Model {
|
||||
items: vec![],
|
||||
db: crate::core::model::get_db().await
|
||||
db: crate::core::model::get_db().await,
|
||||
};
|
||||
presentation_model.load_from_db().await;
|
||||
if let Some(presentation) = presentation_model.find(|p| p.id == 54) {
|
||||
if let Some(presentation) =
|
||||
presentation_model.find(|p| p.id == 54)
|
||||
{
|
||||
let test_presentation = test_presentation();
|
||||
assert_eq!(&test_presentation, presentation);
|
||||
} else {
|
||||
|
|
|
@ -52,7 +52,9 @@ impl From<&Image> for ServiceItem {
|
|||
impl From<&Presentation> for ServiceItem {
|
||||
fn from(presentation: &Presentation) -> Self {
|
||||
Self {
|
||||
kind: ServiceItemKind::Presentation(presentation.kind.clone()),
|
||||
kind: ServiceItemKind::Presentation(
|
||||
presentation.kind.clone(),
|
||||
),
|
||||
database_id: presentation.id,
|
||||
..Default::default()
|
||||
}
|
||||
|
@ -60,7 +62,10 @@ impl From<&Presentation> for ServiceItem {
|
|||
}
|
||||
|
||||
impl ServiceItemModel {
|
||||
fn add_item(&mut self, item: impl Into<ServiceItem>) -> Result<()> {
|
||||
fn add_item(
|
||||
&mut self,
|
||||
item: impl Into<ServiceItem>,
|
||||
) -> Result<()> {
|
||||
let service_item: ServiceItem = item.into();
|
||||
self.items.push(service_item);
|
||||
Ok(())
|
||||
|
@ -103,7 +108,10 @@ mod test {
|
|||
let mut service_model = ServiceItemModel::default();
|
||||
match service_model.add_item(&song) {
|
||||
Ok(_) => {
|
||||
assert_eq!(ServiceItemKind::Song, service_model.items[0].kind);
|
||||
assert_eq!(
|
||||
ServiceItemKind::Song,
|
||||
service_model.items[0].kind
|
||||
);
|
||||
assert_eq!(
|
||||
ServiceItemKind::Presentation(PresKind::Html),
|
||||
pres_item.kind
|
||||
|
|
|
@ -15,7 +15,9 @@ use crate::core::lisp::Symbol;
|
|||
|
||||
use super::lisp::get_lists;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub enum TextAlignment {
|
||||
TopLeft,
|
||||
TopCenter,
|
||||
|
@ -39,7 +41,9 @@ impl From<Value> for TextAlignment {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Background {
|
||||
pub path: PathBuf,
|
||||
pub kind: BackgroundKind,
|
||||
|
@ -113,16 +117,23 @@ pub enum ParseError {
|
|||
impl std::error::Error for ParseError {}
|
||||
|
||||
impl Display for ParseError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
fn fmt(
|
||||
&self,
|
||||
f: &mut std::fmt::Formatter<'_>,
|
||||
) -> std::fmt::Result {
|
||||
let message = match self {
|
||||
Self::NonBackgroundFile => "The file is not a recognized image or video type",
|
||||
Self::NonBackgroundFile => {
|
||||
"The file is not a recognized image or video type"
|
||||
}
|
||||
Self::DoesNotExist => "This file doesn't exist",
|
||||
};
|
||||
write!(f, "Error: {message}")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub enum BackgroundKind {
|
||||
#[default]
|
||||
Image,
|
||||
|
@ -139,7 +150,9 @@ impl From<String> for BackgroundKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, PartialEq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Slide {
|
||||
id: i32,
|
||||
background: Background,
|
||||
|
@ -170,7 +183,9 @@ impl Slide {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, PartialEq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct SlideBuilder {
|
||||
background: Option<Background>,
|
||||
text: Option<String>,
|
||||
|
@ -187,7 +202,10 @@ impl SlideBuilder {
|
|||
Self::default()
|
||||
}
|
||||
|
||||
pub(crate) fn background(mut self, background: PathBuf) -> Result<Self, ParseError> {
|
||||
pub(crate) fn background(
|
||||
mut self,
|
||||
background: PathBuf,
|
||||
) -> Result<Self, ParseError> {
|
||||
let background = Background::try_from(background)?;
|
||||
let _ = self.background.insert(background);
|
||||
Ok(self)
|
||||
|
@ -208,7 +226,10 @@ impl SlideBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub(crate) fn text_alignment(mut self, text_alignment: TextAlignment) -> Self {
|
||||
pub(crate) fn text_alignment(
|
||||
mut self,
|
||||
text_alignment: TextAlignment,
|
||||
) -> Self {
|
||||
let _ = self.text_alignment.insert(text_alignment);
|
||||
self
|
||||
}
|
||||
|
@ -218,12 +239,18 @@ impl SlideBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
pub(crate) fn video_start_time(mut self, video_start_time: f32) -> Self {
|
||||
pub(crate) fn video_start_time(
|
||||
mut self,
|
||||
video_start_time: f32,
|
||||
) -> Self {
|
||||
let _ = self.video_start_time.insert(video_start_time);
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn video_end_time(mut self, video_end_time: f32) -> Self {
|
||||
pub(crate) fn video_end_time(
|
||||
mut self,
|
||||
video_end_time: f32,
|
||||
) -> Self {
|
||||
let _ = self.video_end_time.insert(video_end_time);
|
||||
self
|
||||
}
|
||||
|
@ -281,7 +308,11 @@ impl Image {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_image_bg(atom: &Value, image_map: &mut HashMap<String, String>, map_index: usize) {
|
||||
fn build_image_bg(
|
||||
atom: &Value,
|
||||
image_map: &mut HashMap<String, String>,
|
||||
map_index: usize,
|
||||
) {
|
||||
// This needs to be the cons that contains (image . ...)
|
||||
// the image is a symbol and the rest are keywords and other maps
|
||||
if atom.is_symbol() {
|
||||
|
@ -289,7 +320,9 @@ fn build_image_bg(atom: &Value, image_map: &mut HashMap<String, String>, map_ind
|
|||
return;
|
||||
}
|
||||
|
||||
for atom in atom.list_iter().unwrap().map(|a| a.as_cons().unwrap()) {
|
||||
for atom in
|
||||
atom.list_iter().unwrap().map(|a| a.as_cons().unwrap())
|
||||
{
|
||||
if atom.car() == &Value::Symbol("image".into()) {
|
||||
build_image_bg(atom.cdr(), image_map, map_index);
|
||||
} else {
|
||||
|
@ -345,7 +378,11 @@ fn build_slides(
|
|||
dbg!(¤t_symbol);
|
||||
match value {
|
||||
Value::Cons(v) => {
|
||||
slide_builder = build_slides(&v, current_symbol.clone(), slide_builder);
|
||||
slide_builder = build_slides(
|
||||
&v,
|
||||
current_symbol.clone(),
|
||||
slide_builder,
|
||||
);
|
||||
}
|
||||
Value::Nil => {
|
||||
dbg!(Value::Nil);
|
||||
|
@ -361,7 +398,8 @@ fn build_slides(
|
|||
}
|
||||
Value::Symbol(symbol) => {
|
||||
dbg!(symbol);
|
||||
current_symbol = Symbol::from_str(symbol).unwrap_or_default();
|
||||
current_symbol =
|
||||
Symbol::from_str(symbol).unwrap_or_default();
|
||||
}
|
||||
Value::Keyword(keyword) => {
|
||||
dbg!(keyword);
|
||||
|
@ -399,16 +437,19 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_lexp_serialize() {
|
||||
let lisp = read_to_string("./test_presentation.lisp").expect("oops");
|
||||
let lisp =
|
||||
read_to_string("./test_presentation.lisp").expect("oops");
|
||||
println!("{lisp}");
|
||||
let mut parser = Parser::from_str_custom(&lisp, Options::elisp());
|
||||
let mut parser =
|
||||
Parser::from_str_custom(&lisp, Options::elisp());
|
||||
for atom in parser.value_iter() {
|
||||
match atom {
|
||||
Ok(atom) => {
|
||||
let symbol = Symbol::None;
|
||||
let slide_builder = SlideBuilder::new();
|
||||
atom.as_cons()
|
||||
.map(|c| build_slides(c, symbol, slide_builder));
|
||||
atom.as_cons().map(|c| {
|
||||
build_slides(c, symbol, slide_builder)
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
dbg!(e);
|
||||
|
@ -432,7 +473,8 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_ron_deserialize() {
|
||||
let slide = read_to_string("./test_presentation.ron").expect("Problem getting file read");
|
||||
let slide = read_to_string("./test_presentation.ron")
|
||||
.expect("Problem getting file read");
|
||||
match ron::from_str::<Vec<Slide>>(&slide) {
|
||||
Ok(s) => {
|
||||
dbg!(s);
|
||||
|
|
|
@ -3,15 +3,20 @@ use std::{collections::HashMap, path::PathBuf};
|
|||
use cosmic::{executor, iced::Executor};
|
||||
use miette::{miette, IntoDiagnostic, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{query, query_as, sqlite::SqliteRow, FromRow, Row, SqliteConnection};
|
||||
use sqlx::{
|
||||
query, query_as, sqlite::SqliteRow, FromRow, Row,
|
||||
SqliteConnection,
|
||||
};
|
||||
use tracing::{debug, error};
|
||||
|
||||
use super::{
|
||||
model::{Model},
|
||||
model::Model,
|
||||
slide::{Background, TextAlignment},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Song {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
|
@ -27,9 +32,11 @@ pub struct Song {
|
|||
}
|
||||
|
||||
const VERSE_KEYWORDS: [&str; 24] = [
|
||||
"Verse 1", "Verse 2", "Verse 3", "Verse 4", "Verse 5", "Verse 6", "Verse 7", "Verse 8",
|
||||
"Chorus 1", "Chorus 2", "Chorus 3", "Chorus 4", "Bridge 1", "Bridge 2", "Bridge 3", "Bridge 4",
|
||||
"Intro 1", "Intro 2", "Ending 1", "Ending 2", "Other 1", "Other 2", "Other 3", "Other 4",
|
||||
"Verse 1", "Verse 2", "Verse 3", "Verse 4", "Verse 5", "Verse 6",
|
||||
"Verse 7", "Verse 8", "Chorus 1", "Chorus 2", "Chorus 3",
|
||||
"Chorus 4", "Bridge 1", "Bridge 2", "Bridge 3", "Bridge 4",
|
||||
"Intro 1", "Intro 2", "Ending 1", "Ending 2", "Other 1",
|
||||
"Other 2", "Other 3", "Other 4",
|
||||
];
|
||||
|
||||
impl FromRow<'_, SqliteRow> for Song {
|
||||
|
@ -54,7 +61,6 @@ impl FromRow<'_, SqliteRow> for Song {
|
|||
Ok(background) => Some(background),
|
||||
Err(_) => None,
|
||||
}
|
||||
|
||||
},
|
||||
text_alignment: Some({
|
||||
let horizontal_alignment: String = row.try_get(3)?;
|
||||
|
@ -67,8 +73,12 @@ impl FromRow<'_, SqliteRow> for Song {
|
|||
("left", "center") => TextAlignment::MiddleLeft,
|
||||
("left", "bottom") => TextAlignment::BottomLeft,
|
||||
("center", "top") => TextAlignment::TopCenter,
|
||||
("center", "center") => TextAlignment::MiddleCenter,
|
||||
("center", "bottom") => TextAlignment::BottomCenter,
|
||||
("center", "center") => {
|
||||
TextAlignment::MiddleCenter
|
||||
}
|
||||
("center", "bottom") => {
|
||||
TextAlignment::BottomCenter
|
||||
}
|
||||
("right", "top") => TextAlignment::TopRight,
|
||||
("right", "center") => TextAlignment::MiddleRight,
|
||||
("right", "bottom") => TextAlignment::BottomRight,
|
||||
|
@ -81,7 +91,10 @@ impl FromRow<'_, SqliteRow> for Song {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn get_song_from_db(index: i32, db: &mut SqliteConnection) -> Result<Song> {
|
||||
pub async fn get_song_from_db(
|
||||
index: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Song> {
|
||||
let row = query(r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs where id = $1"#).bind(index).fetch_one(db).await.into_diagnostic()?;
|
||||
Ok(Song::from_row(&row).into_diagnostic()?)
|
||||
}
|
||||
|
@ -96,14 +109,16 @@ impl Model<Song> {
|
|||
match Song::from_row(&song) {
|
||||
Ok(song) => {
|
||||
let _ = self.add_item(song);
|
||||
},
|
||||
Err(e) => error!("Could not convert song: {e}"),
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Could not convert song: {e}")
|
||||
}
|
||||
};
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error!("There was an error in converting songs: {e}");
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +130,11 @@ impl Song {
|
|||
return Err(miette!("There is no lyrics here"));
|
||||
} else if self.verse_order.is_none() {
|
||||
return Err(miette!("There is no verse_order here"));
|
||||
} else if self.verse_order.clone().is_some_and(|v| v.is_empty()) {
|
||||
} else if self
|
||||
.verse_order
|
||||
.clone()
|
||||
.is_some_and(|v| v.is_empty())
|
||||
{
|
||||
return Err(miette!("There is no verse_order here"));
|
||||
}
|
||||
if let Some(raw_lyrics) = self.lyrics.clone() {
|
||||
|
@ -145,16 +164,21 @@ impl Song {
|
|||
let mut verse_name = "";
|
||||
debug!(verse = verse);
|
||||
for word in VERSE_KEYWORDS {
|
||||
let end_verse = verse.get(1..2).unwrap_or_default();
|
||||
let beg_verse = verse.get(0..1).unwrap_or_default();
|
||||
if word.starts_with(beg_verse) && word.ends_with(end_verse) {
|
||||
let end_verse =
|
||||
verse.get(1..2).unwrap_or_default();
|
||||
let beg_verse =
|
||||
verse.get(0..1).unwrap_or_default();
|
||||
if word.starts_with(beg_verse)
|
||||
&& word.ends_with(end_verse)
|
||||
{
|
||||
verse_name = word;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Some(lyric) = lyric_map.get(verse_name) {
|
||||
if lyric.contains("\n\n") {
|
||||
let split_lyrics: Vec<&str> = lyric.split("\n\n").collect();
|
||||
let split_lyrics: Vec<&str> =
|
||||
lyric.split("\n\n").collect();
|
||||
for lyric in split_lyrics {
|
||||
if lyric.is_empty() {
|
||||
continue;
|
||||
|
@ -246,7 +270,8 @@ From the day
|
|||
You saved my soul"
|
||||
.to_string(),
|
||||
);
|
||||
song.verse_order = "O1 V1 C1 C2 O2 V2 C3 C2 O2 B1 C2 C2 E1 O2"
|
||||
song.verse_order =
|
||||
"O1 V1 C1 C2 O2 V2 C3 C2 O2 B1 C2 C2 E1 O2"
|
||||
.to_string()
|
||||
.split(' ')
|
||||
.map(|s| Some(s.to_string()))
|
||||
|
@ -265,7 +290,7 @@ You saved my soul"
|
|||
async fn model() -> Model<Song> {
|
||||
let song_model: Model<Song> = Model {
|
||||
items: vec![],
|
||||
db: crate::core::model::get_db().await
|
||||
db: crate::core::model::get_db().await,
|
||||
};
|
||||
song_model
|
||||
}
|
||||
|
@ -302,7 +327,10 @@ You saved my soul"
|
|||
song_model.load_from_db().await;
|
||||
|
||||
match song_model.update_item(song, 2) {
|
||||
Ok(()) => assert_eq!(&cloned_song, song_model.find(|s| s.id == 7).unwrap()),
|
||||
Ok(()) => assert_eq!(
|
||||
&cloned_song,
|
||||
song_model.find(|s| s.id == 7).unwrap()
|
||||
),
|
||||
Err(e) => assert!(false, "{e}"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use super::model::Model;
|
||||
use cosmic::{executor, iced::Executor};
|
||||
use miette::{Result, miette, IntoDiagnostic};
|
||||
use miette::{miette, IntoDiagnostic, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{query_as, SqliteConnection};
|
||||
use std::path::PathBuf;
|
||||
use tracing::error;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Clone, Debug, Default, PartialEq, Serialize, Deserialize,
|
||||
)]
|
||||
pub struct Video {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
|
@ -25,12 +27,17 @@ impl Model<Video> {
|
|||
let _ = self.add_item(video);
|
||||
}
|
||||
}
|
||||
Err(e) => error!("There was an error in converting videos: {e}"),
|
||||
Err(e) => {
|
||||
error!("There was an error in converting videos: {e}")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_video_from_db(database_id: i32, db: &mut SqliteConnection) -> Result<Video> {
|
||||
pub async fn get_video_from_db(
|
||||
database_id: i32,
|
||||
db: &mut SqliteConnection,
|
||||
) -> Result<Video> {
|
||||
Ok(query_as!(Video, r#"SELECT title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!", id as "id: i32" from videos where id = ?"#, database_id).fetch_one(db).await.into_diagnostic()?)
|
||||
}
|
||||
|
||||
|
@ -51,7 +58,7 @@ mod test {
|
|||
async fn test_db_and_model() {
|
||||
let mut video_model: Model<Video> = Model {
|
||||
items: vec![],
|
||||
db: crate::core::model::get_db().await
|
||||
db: crate::core::model::get_db().await,
|
||||
};
|
||||
video_model.load_from_db().await;
|
||||
if let Some(video) = video_model.find(|v| v.id == 73) {
|
||||
|
@ -70,16 +77,26 @@ mod test {
|
|||
let video = test_video("A new video".into());
|
||||
let mut video_model: Model<Video> = Model {
|
||||
items: vec![],
|
||||
db: crate::core::model::get_db().await
|
||||
db: crate::core::model::get_db().await,
|
||||
};
|
||||
let result = video_model.add_item(video.clone());
|
||||
let new_video = test_video("A newer video".into());
|
||||
match result {
|
||||
Ok(_) => {
|
||||
assert_eq!(&video, video_model.find(|v| v.id == 0).unwrap());
|
||||
assert_ne!(&new_video, video_model.find(|v| v.id == 0).unwrap());
|
||||
assert_eq!(
|
||||
&video,
|
||||
video_model.find(|v| v.id == 0).unwrap()
|
||||
);
|
||||
assert_ne!(
|
||||
&new_video,
|
||||
video_model.find(|v| v.id == 0).unwrap()
|
||||
);
|
||||
}
|
||||
Err(e) => assert!(false, "There was an error adding the video: {:?}", e),
|
||||
Err(e) => assert!(
|
||||
false,
|
||||
"There was an error adding the video: {:?}",
|
||||
e
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue