diff --git a/flake.nix b/flake.nix index ce67021..2de116c 100644 --- a/flake.nix +++ b/flake.nix @@ -8,107 +8,101 @@ fenix.url = "github:nix-community/fenix"; }; - outputs = - inputs: - with inputs; - flake-utils.lib.eachDefaultSystem ( - system: - let - pkgs = import nixpkgs { - inherit system; - overlays = [ fenix.overlays.default ]; - # overlays = [cargo2nix.overlays.default]; - }; - naersk' = pkgs.callPackage naersk { }; - nbi = with pkgs; [ - # Rust tools - alejandra - (pkgs.fenix.stable.withComponents [ - "cargo" - "clippy" - "rust-src" - "rustc" - "rustfmt" - ]) - rust-analyzer - vulkan-loader - wayland - wayland-protocols - libxkbcommon - pkg-config - sccache - ]; + outputs = inputs: with inputs; + flake-utils.lib.eachDefaultSystem + (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [fenix.overlays.default]; + # overlays = [cargo2nix.overlays.default]; + }; + naersk' = pkgs.callPackage naersk {}; + nbi = with pkgs; [ + # Rust tools + alejandra + (pkgs.fenix.stable.withComponents [ + "cargo" + "clippy" + "rust-src" + "rustc" + "rustfmt" + ]) + rust-analyzer + vulkan-loader + wayland + wayland-protocols + libxkbcommon + pkg-config + sccache + ]; - bi = with pkgs; [ - gcc - stdenv - gnumake - gdb - lldb - cmake - clang - libclang - makeWrapper - vulkan-headers - vulkan-loader - vulkan-tools - libGL - cargo-flamegraph - bacon + bi = with pkgs; [ + gcc + stdenv + gnumake + gdb + lldb + cmake + clang + libclang + makeWrapper + vulkan-headers + vulkan-loader + vulkan-tools + libGL + cargo-flamegraph - fontconfig - glib - alsa-lib - gst_all_1.gst-libav - gst_all_1.gst-plugins-bad - gst_all_1.gst-plugins-good - gst_all_1.gst-plugins-ugly - gst_all_1.gst-plugins-base - gst_all_1.gst-plugins-rs - gst_all_1.gst-vaapi - gst_all_1.gstreamer - # podofo - # mpv - ffmpeg-full - mupdf - # yt-dlp + fontconfig + glib + alsa-lib + gst_all_1.gst-libav + gst_all_1.gst-plugins-bad + gst_all_1.gst-plugins-good + gst_all_1.gst-plugins-ugly + gst_all_1.gst-plugins-base + gst_all_1.gst-plugins-rs + gst_all_1.gst-vaapi + gst_all_1.gstreamer + # podofo + # mpv + ffmpeg-full + mupdf + # yt-dlp - just - sqlx-cli - cargo-watch - ]; - in - rec { - devShell = - pkgs.mkShell.override - { - # stdenv = pkgs.stdenvAdapters.useMoldLinker pkgs.clangStdenv; - } - { - nativeBuildInputs = nbi; - buildInputs = bi; - LD_LIBRARY_PATH = "$LD_LIBRARY_PATH:${ - with pkgs; - pkgs.lib.makeLibraryPath [ - pkgs.vulkan-loader - pkgs.wayland - pkgs.wayland-protocols - pkgs.libxkbcommon - pkgs.mupdf - pkgs.libclang - ] - }"; - # LIBCLANG_PATH = "${pkgs.clang}"; - DATABASE_URL = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3"; - }; - defaultPackage = naersk'.buildPackage { - src = ./.; - }; - packages = { - default = naersk'.buildPackage { + just + sqlx-cli + cargo-watch + ]; + in rec + { + devShell = pkgs.mkShell.override { + # stdenv = pkgs.stdenvAdapters.useMoldLinker pkgs.clangStdenv; + } { + nativeBuildInputs = nbi; + buildInputs = bi; + LD_LIBRARY_PATH = "$LD_LIBRARY_PATH:${ + with pkgs; + pkgs.lib.makeLibraryPath [ + pkgs.vulkan-loader + pkgs.wayland + pkgs.wayland-protocols + pkgs.libxkbcommon + pkgs.mupdf + pkgs.libclang + ] + }"; + # LIBCLANG_PATH = "${pkgs.clang}"; + DATABASE_URL = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3"; + }; + defaultPackage = naersk'.buildPackage { src = ./.; }; - }; - } - ); + packages = { + default = naersk'.buildPackage { + src = ./.; + }; + }; + } + ); } diff --git a/src/core/images.rs b/src/core/images.rs index eca52c4..beba760 100644 --- a/src/core/images.rs +++ b/src/core/images.rs @@ -17,7 +17,7 @@ use std::path::PathBuf; use tracing::error; #[derive( - Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, + Clone, Debug, Default, PartialEq, Serialize, Deserialize, )] pub struct Image { pub id: i32, @@ -52,9 +52,8 @@ impl Content for Image { if self.path.exists() { self.path .file_name() - .map_or("Missing image".into(), |f| { - f.to_string_lossy().to_string() - }) + .map(|f| f.to_string_lossy().to_string()) + .unwrap_or("Missing image".into()) } else { "Missing image".into() } @@ -86,7 +85,7 @@ impl From<&Value> for Image { let path = p.to_str().unwrap_or_default().to_string(); let title = - path.rsplit_once('/').unwrap_or_default().1; + path.rsplit_once("/").unwrap_or_default().1; title.to_string() }); Self { @@ -155,16 +154,14 @@ impl Model { .await; match result { Ok(v) => { - for image in v { + for image in v.into_iter() { let _ = self.add_item(image); } } Err(e) => { - error!( - "There was an error in converting images: {e}" - ); + error!("There was an error in converting images: {e}") } - } + }; } } @@ -175,7 +172,7 @@ pub async fn update_image_in_db( let path = image .path .to_str() - .map(std::string::ToString::to_string) + .map(|s| s.to_string()) .unwrap_or_default(); query!( r#"UPDATE images SET title = $2, file_path = $3 WHERE id = $1"#, diff --git a/src/core/kinds.rs b/src/core/kinds.rs index 6dafbd6..b366997 100644 --- a/src/core/kinds.rs +++ b/src/core/kinds.rs @@ -21,11 +21,11 @@ pub enum ServiceItemKind { impl std::fmt::Display for ServiceItemKind { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let s = match self { - Self::Song(_) => "song".to_owned(), - Self::Image(_) => "image".to_owned(), - Self::Video(_) => "video".to_owned(), - Self::Presentation(_) => "html".to_owned(), - Self::Content(_) => "content".to_owned(), + Self::Song(s) => "song".to_owned(), + Self::Image(i) => "image".to_owned(), + Self::Video(v) => "video".to_owned(), + Self::Presentation(p) => "html".to_owned(), + Self::Content(s) => "content".to_owned(), }; write!(f, "{s}") } @@ -50,7 +50,7 @@ impl std::fmt::Display for ServiceItemKind { // } impl From for String { - fn from(val: ServiceItemKind) -> Self { + fn from(val: ServiceItemKind) -> String { match val { ServiceItemKind::Song(_) => "song".to_owned(), ServiceItemKind::Video(_) => "video".to_owned(), @@ -76,9 +76,7 @@ impl Display for ParseError { 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'" - } + Self::UnknownType => "The type does not exist. It needs to be one of 'song', 'video', 'image', 'presentation', or 'content'", }; write!(f, "Error: {message}") } diff --git a/src/core/model.rs b/src/core/model.rs index 13ddda8..a0afcd0 100644 --- a/src/core/model.rs +++ b/src/core/model.rs @@ -1,6 +1,7 @@ use std::mem::replace; -use miette::{Result, miette}; +use cosmic::iced::Executor; +use miette::{miette, Result}; use sqlx::{Connection, SqliteConnection}; #[derive(Debug, Clone)] @@ -9,7 +10,7 @@ pub struct Model { pub kind: LibraryKind, } -#[derive(Debug, Clone, PartialEq, Eq, Copy)] +#[derive(Debug, Clone, PartialEq, Copy)] pub enum LibraryKind { Song, Video, @@ -45,7 +46,6 @@ impl Model { Ok(()) } - #[must_use] pub fn get_item(&self, index: i32) -> Option<&T> { self.items.get(index as usize) } diff --git a/src/core/presentations.rs b/src/core/presentations.rs index 1bae1bf..bf47b5b 100644 --- a/src/core/presentations.rs +++ b/src/core/presentations.rs @@ -75,9 +75,8 @@ impl Content for Presentation { if self.path.exists() { self.path .file_name() - .map_or("Missing presentation".into(), |f| { - f.to_string_lossy().to_string() - }) + .map(|f| f.to_string_lossy().to_string()) + .unwrap_or("Missing presentation".into()) } else { "Missing presentation".into() } @@ -191,16 +190,14 @@ impl ServiceTrait for Presentation { } impl Presentation { - #[must_use] pub fn new() -> Self { Self { - title: String::new(), + title: "".to_string(), ..Default::default() } } - #[must_use] - pub const fn get_kind(&self) -> &PresKind { + pub fn get_kind(&self) -> &PresKind { &self.kind } } @@ -243,7 +240,7 @@ impl Model { .await; match result { Ok(v) => { - for presentation in v { + for presentation in v.into_iter() { let _ = self.add_item(Presentation { id: presentation.id, title: presentation.title, @@ -270,7 +267,7 @@ pub async fn update_presentation_in_db( let path = presentation .path .to_str() - .map(std::string::ToString::to_string) + .map(|s| s.to_string()) .unwrap_or_default(); let html = presentation.kind == PresKind::Html; query!( diff --git a/src/core/service_items.rs b/src/core/service_items.rs index 3912fa0..91a1e82 100644 --- a/src/core/service_items.rs +++ b/src/core/service_items.rs @@ -79,13 +79,13 @@ impl AsMimeTypes for ServiceItem { impl From<&ServiceItem> for Value { fn from(value: &ServiceItem) -> Self { match &value.kind { - ServiceItemKind::Song(song) => Self::from(song), - ServiceItemKind::Video(video) => Self::from(video), - ServiceItemKind::Image(image) => Self::from(image), + ServiceItemKind::Song(song) => Value::from(song), + ServiceItemKind::Video(video) => Value::from(video), + ServiceItemKind::Image(image) => Value::from(image), ServiceItemKind::Presentation(presentation) => { - Self::from(presentation) + Value::from(presentation) } - ServiceItemKind::Content(slide) => Self::from(slide), + ServiceItemKind::Content(slide) => Value::from(slide), } } } @@ -172,8 +172,8 @@ impl From<&Value> for ServiceItem { } else if let Some(background) = list.get(background_pos) { - if let Value::List(item) = background { - match &item[0] { + match background { + Value::List(item) => match &item[0] { Value::Symbol(Symbol(s)) if s == "image" => { @@ -196,29 +196,30 @@ impl From<&Value> for ServiceItem { )) } _ => todo!(), + }, + _ => { + error!( + "There is no background here: {:?}", + background + ); + ServiceItem::default() } - } else { - error!( - "There is no background here: {:?}", - background - ); - Self::default() } } else { error!( "There is no background here: {:?}", background_pos ); - Self::default() + ServiceItem::default() } } Value::Symbol(Symbol(s)) if s == "song" => { let song = lisp_to_song(list.clone()); Self::from(&song) } - _ => Self::default(), + _ => ServiceItem::default(), }, - _ => Self::default(), + _ => ServiceItem::default(), } } } @@ -257,7 +258,7 @@ impl From<&Song> for ServiceItem { kind: ServiceItemKind::Song(song.clone()), database_id: song.id, title: song.title.clone(), - slides, + slides: slides, ..Default::default() } } else { @@ -278,7 +279,7 @@ impl From<&Video> for ServiceItem { kind: ServiceItemKind::Video(video.clone()), database_id: video.id, title: video.title.clone(), - slides, + slides: slides, ..Default::default() } } else { @@ -299,7 +300,7 @@ impl From<&Image> for ServiceItem { kind: ServiceItemKind::Image(image.clone()), database_id: image.id, title: image.title.clone(), - slides, + slides: slides, ..Default::default() } } else { @@ -322,7 +323,7 @@ impl From<&Presentation> for ServiceItem { ), database_id: presentation.id, title: presentation.title.clone(), - slides, + slides: slides, ..Default::default() }, Err(e) => { diff --git a/src/core/slide.rs b/src/core/slide.rs index def56f7..b857afa 100644 --- a/src/core/slide.rs +++ b/src/core/slide.rs @@ -107,9 +107,9 @@ impl TryFrom<&Background> for Video { fn try_from( value: &Background, ) -> std::result::Result { - Self::new( + Video::new( &url::Url::from_file_path(value.path.clone()) - .map_err(|()| ParseError::BackgroundNotVideo)?, + .map_err(|_| ParseError::BackgroundNotVideo)?, ) .map_err(|_| ParseError::BackgroundNotVideo) } @@ -121,9 +121,9 @@ impl TryFrom for Video { fn try_from( value: Background, ) -> std::result::Result { - Self::new( + Video::new( &url::Url::from_file_path(value.path) - .map_err(|()| ParseError::BackgroundNotVideo)?, + .map_err(|_| ParseError::BackgroundNotVideo)?, ) .map_err(|_| ParseError::BackgroundNotVideo) } @@ -132,7 +132,7 @@ impl TryFrom for Video { impl TryFrom for Background { type Error = ParseError; fn try_from(value: String) -> Result { - Self::try_from(value.as_str()) + Background::try_from(value.as_str()) } } @@ -147,7 +147,7 @@ impl TryFrom for Background { .to_str() .unwrap() .to_string(); - let path = path.replace('~', &home); + let path = path.replace("~", &home); PathBuf::from(path) } else { path @@ -192,10 +192,10 @@ impl TryFrom<&str> for Background { type Error = ParseError; fn try_from(value: &str) -> Result { let value = value.trim_start_matches("file://"); - if value.starts_with('~') { + if value.starts_with("~") { if let Some(home) = dirs::home_dir() { if let Some(home) = home.to_str() { - let value = value.replace('~', home); + let value = value.replace("~", home); Self::try_from(PathBuf::from(value)) } else { Self::try_from(PathBuf::from(value)) @@ -252,9 +252,9 @@ impl Display for ParseError { impl From for BackgroundKind { fn from(value: String) -> Self { if value == "image" { - Self::Image + BackgroundKind::Image } else { - Self::Video + BackgroundKind::Video } } } @@ -281,7 +281,7 @@ impl Slide { self } - pub const fn set_font_size(mut self, font_size: i32) -> Self { + pub fn set_font_size(mut self, font_size: i32) -> Self { self.font_size = font_size; self } @@ -291,12 +291,12 @@ impl Slide { self } - pub const fn set_pdf_index(mut self, pdf_index: u32) -> Self { + pub fn set_pdf_index(mut self, pdf_index: u32) -> Self { self.pdf_index = pdf_index; self } - pub const fn background(&self) -> &Background { + pub fn background(&self) -> &Background { &self.background } @@ -304,11 +304,11 @@ impl Slide { self.text.clone() } - pub const fn text_alignment(&self) -> TextAlignment { + pub fn text_alignment(&self) -> TextAlignment { self.text_alignment } - pub const fn font_size(&self) -> i32 { + pub fn font_size(&self) -> i32 { self.font_size } @@ -316,7 +316,7 @@ impl Slide { self.font.clone() } - pub const fn video_loop(&self) -> bool { + pub fn video_loop(&self) -> bool { self.video_loop } @@ -328,13 +328,13 @@ impl Slide { self.pdf_page.clone() } - pub const fn pdf_index(&self) -> u32 { + pub fn pdf_index(&self) -> u32 { self.pdf_index } pub fn song_slides(song: &Song) -> Result> { let lyrics = song.get_lyrics()?; - let slides: Vec = lyrics + let slides: Vec = lyrics .iter() .map(|l| { let song = song.clone(); @@ -358,7 +358,7 @@ impl Slide { Ok(slides) } - pub(crate) const fn set_index(&mut self, index: i32) { + pub(crate) fn set_index(&mut self, index: i32) { self.id = index; } @@ -381,7 +381,7 @@ impl From<&Value> for Slide { fn from(value: &Value) -> Self { match value { Value::List(list) => lisp_to_slide(list), - _ => Self::default(), + _ => Slide::default(), } } } @@ -404,7 +404,7 @@ fn lisp_to_slide(lisp: &Vec) -> Slide { slide = slide.background(lisp_to_background(background)); } else { slide = slide.background(Background::default()); - } + }; let text_position = lisp.iter().position(|v| match v { Value::List(vec) => { @@ -691,7 +691,9 @@ impl SlideBuilder { impl Image { fn new() -> Self { - Default::default() + Self { + ..Default::default() + } } } diff --git a/src/core/songs.rs b/src/core/songs.rs index e9d8b9d..20dbebb 100644 --- a/src/core/songs.rs +++ b/src/core/songs.rs @@ -1,15 +1,16 @@ use std::{collections::HashMap, option::Option, path::PathBuf}; +use cosmic::iced::Executor; use crisp::types::{Keyword, Symbol, Value}; -use miette::{IntoDiagnostic, Result, miette}; +use miette::{miette, IntoDiagnostic, Result}; use serde::{Deserialize, Serialize}; use sqlx::{ - FromRow, Row, Sqlite, SqliteConnection, SqlitePool, - pool::PoolConnection, query, sqlite::SqliteRow, + pool::PoolConnection, query, sqlite::SqliteRow, FromRow, Row, + Sqlite, SqliteConnection, SqlitePool, }; use tracing::error; -use crate::{Slide, SlideBuilder, core::slide}; +use crate::{core::slide, Slide, SlideBuilder}; use super::{ content::Content, @@ -127,9 +128,7 @@ impl FromRow<'_, SqliteRow> for Song { })), verse_order: Some({ let str: &str = row.try_get(0)?; - str.split(' ') - .map(std::string::ToString::to_string) - .collect() + str.split(' ').map(|s| s.to_string()).collect() }), background: { let string: String = row.try_get(7)?; @@ -251,7 +250,9 @@ pub fn lisp_to_song(list: Vec) -> Song { .position(|v| v == &Value::Keyword(Keyword::from("title"))) { let pos = key_pos + 1; - list.get(pos).map_or(String::from("song"), String::from) + list.get(pos) + .map(String::from) + .unwrap_or(String::from("song")) } else { String::from("song") }; @@ -318,30 +319,30 @@ pub fn lisp_to_song(list: Vec) -> Song { let lyric = String::from(&lyric[1]); let verse_title = match lyric_verse.as_str() { - "i1" => r"\n\nIntro 1\n", - "i2" => r"\n\nIntro 1\n", - "v1" => r"\n\nVerse 1\n", - "v2" => r"\n\nVerse 2\n", - "v3" => r"\n\nVerse 3\n", - "v4" => r"\n\nVerse 4\n", - "v5" => r"\n\nVerse 5\n", - "c1" => r"\n\nChorus 1\n", - "c2" => r"\n\nChorus 2\n", - "c3" => r"\n\nChorus 3\n", - "c4" => r"\n\nChorus 4\n", - "b1" => r"\n\nBridge 1\n", - "b2" => r"\n\nBridge 2\n", - "e1" => r"\n\nEnding 1\n", - "e2" => r"\n\nEnding 2\n", - "o1" => r"\n\nOther 1\n", - "o2" => r"\n\nOther 2\n", + "i1" => r#"\n\nIntro 1\n"#, + "i2" => r#"\n\nIntro 1\n"#, + "v1" => r#"\n\nVerse 1\n"#, + "v2" => r#"\n\nVerse 2\n"#, + "v3" => r#"\n\nVerse 3\n"#, + "v4" => r#"\n\nVerse 4\n"#, + "v5" => r#"\n\nVerse 5\n"#, + "c1" => r#"\n\nChorus 1\n"#, + "c2" => r#"\n\nChorus 2\n"#, + "c3" => r#"\n\nChorus 3\n"#, + "c4" => r#"\n\nChorus 4\n"#, + "b1" => r#"\n\nBridge 1\n"#, + "b2" => r#"\n\nBridge 2\n"#, + "e1" => r#"\n\nEnding 1\n"#, + "e2" => r#"\n\nEnding 2\n"#, + "o1" => r#"\n\nOther 1\n"#, + "o2" => r#"\n\nOther 2\n"#, _ => "", }; let lyric = format!("{verse_title}{lyric}"); let lyric = lyric.replace( - "\\n", r" -", + "\\n", r#" +"#, ); lyrics.push(lyric); } @@ -391,15 +392,15 @@ impl Model { let result = 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"#).fetch_all(db).await; match result { Ok(s) => { - for song in s { + for song in s.into_iter() { match Song::from_row(&song) { Ok(song) => { let _ = self.add_item(song); } Err(e) => { - error!("Could not convert song: {e}"); + error!("Could not convert song: {e}") } - } + }; } } Err(e) => { @@ -424,7 +425,7 @@ pub async fn update_song_in_db( }) .collect::() } else { - String::new() + String::from("") } }; @@ -487,13 +488,13 @@ impl Song { let verse_order = self.verse_order.clone(); let mut lyric_map = HashMap::new(); - let mut verse_title = String::new(); - let mut lyric = String::new(); + let mut verse_title = String::from(""); + let mut lyric = String::from(""); for (i, line) in raw_lyrics.split('\n').enumerate() { if VERSE_KEYWORDS.contains(&line) { if i != 0 { lyric_map.insert(verse_title, lyric); - lyric = String::new(); + lyric = String::from(""); verse_title = line.to_string(); } else { verse_title = line.to_string(); @@ -534,7 +535,7 @@ impl Song { lyric_list.push(lyric.to_string()); } else { // error!("NOT WORKING!"); - } + }; } // for lyric in lyric_list.iter() { // debug!(lyric = ?lyric) @@ -625,27 +626,7 @@ You saved my soul" let lyrics = song.get_lyrics(); match lyrics { Ok(lyrics) => { - assert_eq!( - vec![ - "From the Day\nI Am They", - "When You found me,\nI was so blind\nMy sin was before me,\nI was swallowed by pride", - "But out of the darkness,\nYou brought me to Your light\nYou showed me new mercy\nAnd opened up my eyes", - "From the day\nYou saved my soul\n'Til the very moment\nWhen I come home", - "I'll sing, I'll dance,\nMy heart will overflow\nFrom the day\nYou saved my soul", - "Where brilliant light\nIs all around\nAnd endless joy\nIs the only sound", - "Oh, rest my heart\nForever now\nOh, in Your arms\nI'll always be found", - "From the day\nYou saved my soul\n'Til the very moment\nWhen I come home", - "I'll sing, I'll dance,\nMy heart will overflow\nFrom the day\nYou saved my soul", - "My love is Yours\nMy heart is Yours\nMy life is Yours\nForever", - "My love is Yours\nMy heart is Yours\nMy life is Yours\nForever", - "From the day\nYou saved my soul\n'Til the very moment\nWhen I come home", - "I'll sing, I'll dance,\nMy heart will overflow\nFrom the day\nYou saved my soul", - "From the day\nYou saved my soul\n'Til the very moment\nWhen I come home", - "I'll sing, I'll dance,\nMy heart will overflow\nFrom the day\nYou saved my soul", - "Oh Oh Oh\nFrom the day\nYou saved my soul\n" - ], - lyrics - ); + assert_eq!(vec!["From the Day\nI Am They", "When You found me,\nI was so blind\nMy sin was before me,\nI was swallowed by pride", "But out of the darkness,\nYou brought me to Your light\nYou showed me new mercy\nAnd opened up my eyes", "From the day\nYou saved my soul\n'Til the very moment\nWhen I come home", "I'll sing, I'll dance,\nMy heart will overflow\nFrom the day\nYou saved my soul", "Where brilliant light\nIs all around\nAnd endless joy\nIs the only sound", "Oh, rest my heart\nForever now\nOh, in Your arms\nI'll always be found", "From the day\nYou saved my soul\n'Til the very moment\nWhen I come home", "I'll sing, I'll dance,\nMy heart will overflow\nFrom the day\nYou saved my soul", "My love is Yours\nMy heart is Yours\nMy life is Yours\nForever", "My love is Yours\nMy heart is Yours\nMy life is Yours\nForever", "From the day\nYou saved my soul\n'Til the very moment\nWhen I come home", "I'll sing, I'll dance,\nMy heart will overflow\nFrom the day\nYou saved my soul", "From the day\nYou saved my soul\n'Til the very moment\nWhen I come home", "I'll sing, I'll dance,\nMy heart will overflow\nFrom the day\nYou saved my soul", "Oh Oh Oh\nFrom the day\nYou saved my soul\n"], lyrics); } Err(e) => { assert!(false, "{:?}", e) diff --git a/src/core/thumbnail.rs b/src/core/thumbnail.rs index 2ff2f70..dc100c5 100644 --- a/src/core/thumbnail.rs +++ b/src/core/thumbnail.rs @@ -11,9 +11,7 @@ pub fn bg_from_video( video: &Path, screenshot: &Path, ) -> Result<(), Box> { - if screenshot.exists() { - debug!("Screenshot already exists"); - } else { + if !screenshot.exists() { let output_duration = Command::new("ffprobe") .args(["-i", &video.to_string_lossy()]) .output() @@ -28,9 +26,9 @@ pub fn bg_from_video( let mut duration = log.split_off(duration_index + 10); duration.truncate(11); // debug!("rust-duration-is: {duration}"); - let mut hours = String::new(); - let mut minutes = String::new(); - let mut seconds = String::new(); + let mut hours = String::from(""); + let mut minutes = String::from(""); + let mut seconds = String::from(""); for (i, c) in duration.chars().enumerate() { if i <= 1 { hours.push(c); @@ -65,6 +63,8 @@ pub fn bg_from_video( .expect("failed to execute ffmpeg"); // io::stdout().write_all(&output.stdout).unwrap(); // io::stderr().write_all(&output.stderr).unwrap(); + } else { + debug!("Screenshot already exists"); } Ok(()) } diff --git a/src/core/videos.rs b/src/core/videos.rs index f31aa20..c0c1dfb 100644 --- a/src/core/videos.rs +++ b/src/core/videos.rs @@ -7,12 +7,13 @@ use super::{ service_items::ServiceTrait, slide::Slide, }; +use cosmic::iced::Executor; use crisp::types::{Keyword, Symbol, Value}; use miette::{IntoDiagnostic, Result}; use serde::{Deserialize, Serialize}; use sqlx::{ - Sqlite, SqliteConnection, SqlitePool, pool::PoolConnection, - query, query_as, + pool::PoolConnection, query, query_as, Sqlite, SqliteConnection, + SqlitePool, }; use std::path::PathBuf; use tracing::error; @@ -56,9 +57,8 @@ impl Content for Video { if self.path.exists() { self.path .file_name() - .map_or("Missing video".into(), |f| { - f.to_string_lossy().to_string() - }) + .map(|f| f.to_string_lossy().to_string()) + .unwrap_or("Missing video".into()) } else { "Missing video".into() } @@ -90,7 +90,7 @@ impl From<&Value> for Video { let path = p.to_str().unwrap_or_default().to_string(); let title = - path.rsplit_once('/').unwrap_or_default().1; + path.rsplit_once("/").unwrap_or_default().1; title.to_string() }); @@ -124,7 +124,8 @@ impl From<&Value> for Video { }) { let pos = loop_pos + 1; list.get(pos) - .is_some_and(|l| String::from(l) == *"true") + .map(|l| String::from(l) == *"true") + .unwrap_or_default() } else { false }; @@ -192,16 +193,14 @@ impl Model