diff --git a/flake.nix b/flake.nix index 2de116c..ce67021 100644 --- a/flake.nix +++ b/flake.nix @@ -8,101 +8,107 @@ 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 + bi = with pkgs; [ + gcc + stdenv + gnumake + gdb + lldb + cmake + clang + libclang + makeWrapper + vulkan-headers + vulkan-loader + vulkan-tools + libGL + cargo-flamegraph + bacon - 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 { + 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 = ./.; }; - packages = { - default = naersk'.buildPackage { - src = ./.; - }; - }; - } - ); + }; + } + ); } diff --git a/src/core/images.rs b/src/core/images.rs index beba760..eca52c4 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, Serialize, Deserialize, + Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, )] pub struct Image { pub id: i32, @@ -52,8 +52,9 @@ impl Content for Image { if self.path.exists() { self.path .file_name() - .map(|f| f.to_string_lossy().to_string()) - .unwrap_or("Missing image".into()) + .map_or("Missing image".into(), |f| { + f.to_string_lossy().to_string() + }) } else { "Missing image".into() } @@ -85,7 +86,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 { @@ -154,14 +155,16 @@ impl Model { .await; match result { Ok(v) => { - for image in v.into_iter() { + for image in v { 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}" + ); } - }; + } } } @@ -172,7 +175,7 @@ pub async fn update_image_in_db( let path = image .path .to_str() - .map(|s| s.to_string()) + .map(std::string::ToString::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 b366997..6dafbd6 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(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(), + 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(), }; write!(f, "{s}") } @@ -50,7 +50,7 @@ impl std::fmt::Display for ServiceItemKind { // } impl From for String { - fn from(val: ServiceItemKind) -> String { + fn from(val: ServiceItemKind) -> Self { match val { ServiceItemKind::Song(_) => "song".to_owned(), ServiceItemKind::Video(_) => "video".to_owned(), @@ -76,7 +76,9 @@ 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 a0afcd0..13ddda8 100644 --- a/src/core/model.rs +++ b/src/core/model.rs @@ -1,7 +1,6 @@ use std::mem::replace; -use cosmic::iced::Executor; -use miette::{miette, Result}; +use miette::{Result, miette}; use sqlx::{Connection, SqliteConnection}; #[derive(Debug, Clone)] @@ -10,7 +9,7 @@ pub struct Model { pub kind: LibraryKind, } -#[derive(Debug, Clone, PartialEq, Copy)] +#[derive(Debug, Clone, PartialEq, Eq, Copy)] pub enum LibraryKind { Song, Video, @@ -46,6 +45,7 @@ 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 bf47b5b..1bae1bf 100644 --- a/src/core/presentations.rs +++ b/src/core/presentations.rs @@ -75,8 +75,9 @@ impl Content for Presentation { if self.path.exists() { self.path .file_name() - .map(|f| f.to_string_lossy().to_string()) - .unwrap_or("Missing presentation".into()) + .map_or("Missing presentation".into(), |f| { + f.to_string_lossy().to_string() + }) } else { "Missing presentation".into() } @@ -190,14 +191,16 @@ impl ServiceTrait for Presentation { } impl Presentation { + #[must_use] pub fn new() -> Self { Self { - title: "".to_string(), + title: String::new(), ..Default::default() } } - pub fn get_kind(&self) -> &PresKind { + #[must_use] + pub const fn get_kind(&self) -> &PresKind { &self.kind } } @@ -240,7 +243,7 @@ impl Model { .await; match result { Ok(v) => { - for presentation in v.into_iter() { + for presentation in v { let _ = self.add_item(Presentation { id: presentation.id, title: presentation.title, @@ -267,7 +270,7 @@ pub async fn update_presentation_in_db( let path = presentation .path .to_str() - .map(|s| s.to_string()) + .map(std::string::ToString::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 91a1e82..3912fa0 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) => Value::from(song), - ServiceItemKind::Video(video) => Value::from(video), - ServiceItemKind::Image(image) => Value::from(image), + ServiceItemKind::Song(song) => Self::from(song), + ServiceItemKind::Video(video) => Self::from(video), + ServiceItemKind::Image(image) => Self::from(image), ServiceItemKind::Presentation(presentation) => { - Value::from(presentation) + Self::from(presentation) } - ServiceItemKind::Content(slide) => Value::from(slide), + ServiceItemKind::Content(slide) => Self::from(slide), } } } @@ -172,8 +172,8 @@ impl From<&Value> for ServiceItem { } else if let Some(background) = list.get(background_pos) { - match background { - Value::List(item) => match &item[0] { + if let Value::List(item) = background { + match &item[0] { Value::Symbol(Symbol(s)) if s == "image" => { @@ -196,30 +196,29 @@ 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 ); - ServiceItem::default() + Self::default() } } Value::Symbol(Symbol(s)) if s == "song" => { let song = lisp_to_song(list.clone()); Self::from(&song) } - _ => ServiceItem::default(), + _ => Self::default(), }, - _ => ServiceItem::default(), + _ => Self::default(), } } } @@ -258,7 +257,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 { @@ -279,7 +278,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 { @@ -300,7 +299,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 { @@ -323,7 +322,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 b857afa..def56f7 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 { - Video::new( + Self::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 { - Video::new( + Self::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 { - Background::try_from(value.as_str()) + Self::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" { - BackgroundKind::Image + Self::Image } else { - BackgroundKind::Video + Self::Video } } } @@ -281,7 +281,7 @@ impl Slide { self } - pub fn set_font_size(mut self, font_size: i32) -> Self { + pub const fn set_font_size(mut self, font_size: i32) -> Self { self.font_size = font_size; self } @@ -291,12 +291,12 @@ impl Slide { self } - pub fn set_pdf_index(mut self, pdf_index: u32) -> Self { + pub const fn set_pdf_index(mut self, pdf_index: u32) -> Self { self.pdf_index = pdf_index; self } - pub fn background(&self) -> &Background { + pub const fn background(&self) -> &Background { &self.background } @@ -304,11 +304,11 @@ impl Slide { self.text.clone() } - pub fn text_alignment(&self) -> TextAlignment { + pub const fn text_alignment(&self) -> TextAlignment { self.text_alignment } - pub fn font_size(&self) -> i32 { + pub const fn font_size(&self) -> i32 { self.font_size } @@ -316,7 +316,7 @@ impl Slide { self.font.clone() } - pub fn video_loop(&self) -> bool { + pub const fn video_loop(&self) -> bool { self.video_loop } @@ -328,13 +328,13 @@ impl Slide { self.pdf_page.clone() } - pub fn pdf_index(&self) -> u32 { + pub const 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) fn set_index(&mut self, index: i32) { + pub(crate) const 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), - _ => Slide::default(), + _ => Self::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,9 +691,7 @@ impl SlideBuilder { impl Image { fn new() -> Self { - Self { - ..Default::default() - } + Default::default() } } diff --git a/src/core/songs.rs b/src/core/songs.rs index 20dbebb..e9d8b9d 100644 --- a/src/core/songs.rs +++ b/src/core/songs.rs @@ -1,16 +1,15 @@ use std::{collections::HashMap, option::Option, path::PathBuf}; -use cosmic::iced::Executor; use crisp::types::{Keyword, Symbol, Value}; -use miette::{miette, IntoDiagnostic, Result}; +use miette::{IntoDiagnostic, Result, miette}; use serde::{Deserialize, Serialize}; use sqlx::{ - pool::PoolConnection, query, sqlite::SqliteRow, FromRow, Row, - Sqlite, SqliteConnection, SqlitePool, + FromRow, Row, Sqlite, SqliteConnection, SqlitePool, + pool::PoolConnection, query, sqlite::SqliteRow, }; use tracing::error; -use crate::{core::slide, Slide, SlideBuilder}; +use crate::{Slide, SlideBuilder, core::slide}; use super::{ content::Content, @@ -128,7 +127,9 @@ impl FromRow<'_, SqliteRow> for Song { })), verse_order: Some({ let str: &str = row.try_get(0)?; - str.split(' ').map(|s| s.to_string()).collect() + str.split(' ') + .map(std::string::ToString::to_string) + .collect() }), background: { let string: String = row.try_get(7)?; @@ -250,9 +251,7 @@ 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(String::from) - .unwrap_or(String::from("song")) + list.get(pos).map_or(String::from("song"), String::from) } else { String::from("song") }; @@ -319,30 +318,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); } @@ -392,15 +391,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.into_iter() { + for song in s { 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) => { @@ -425,7 +424,7 @@ pub async fn update_song_in_db( }) .collect::() } else { - String::from("") + String::new() } }; @@ -488,13 +487,13 @@ impl Song { let verse_order = self.verse_order.clone(); let mut lyric_map = HashMap::new(); - let mut verse_title = String::from(""); - let mut lyric = String::from(""); + let mut verse_title = String::new(); + let mut lyric = String::new(); 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::from(""); + lyric = String::new(); verse_title = line.to_string(); } else { verse_title = line.to_string(); @@ -535,7 +534,7 @@ impl Song { lyric_list.push(lyric.to_string()); } else { // error!("NOT WORKING!"); - }; + } } // for lyric in lyric_list.iter() { // debug!(lyric = ?lyric) @@ -626,7 +625,27 @@ 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 dc100c5..2ff2f70 100644 --- a/src/core/thumbnail.rs +++ b/src/core/thumbnail.rs @@ -11,7 +11,9 @@ pub fn bg_from_video( video: &Path, screenshot: &Path, ) -> Result<(), Box> { - if !screenshot.exists() { + if screenshot.exists() { + debug!("Screenshot already exists"); + } else { let output_duration = Command::new("ffprobe") .args(["-i", &video.to_string_lossy()]) .output() @@ -26,9 +28,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::from(""); - let mut minutes = String::from(""); - let mut seconds = String::from(""); + let mut hours = String::new(); + let mut minutes = String::new(); + let mut seconds = String::new(); for (i, c) in duration.chars().enumerate() { if i <= 1 { hours.push(c); @@ -63,8 +65,6 @@ 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 c0c1dfb..f31aa20 100644 --- a/src/core/videos.rs +++ b/src/core/videos.rs @@ -7,13 +7,12 @@ 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::{ - pool::PoolConnection, query, query_as, Sqlite, SqliteConnection, - SqlitePool, + Sqlite, SqliteConnection, SqlitePool, pool::PoolConnection, + query, query_as, }; use std::path::PathBuf; use tracing::error; @@ -57,8 +56,9 @@ impl Content for Video { if self.path.exists() { self.path .file_name() - .map(|f| f.to_string_lossy().to_string()) - .unwrap_or("Missing video".into()) + .map_or("Missing video".into(), |f| { + f.to_string_lossy().to_string() + }) } 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,8 +124,7 @@ impl From<&Value> for Video { }) { let pos = loop_pos + 1; list.get(pos) - .map(|l| String::from(l) == *"true") - .unwrap_or_default() + .is_some_and(|l| String::from(l) == *"true") } else { false }; @@ -193,14 +192,16 @@ impl Model