perf, pedantic, nursery, and unwrap_used clippy fixes

This commit is contained in:
Chris Cochrun 2025-09-15 11:19:27 -05:00
parent a186d3bec4
commit 3fe77c93e2
15 changed files with 195 additions and 207 deletions

View file

@ -17,7 +17,7 @@ use std::path::PathBuf;
use tracing::error; use tracing::error;
#[derive( #[derive(
Clone, Debug, Default, PartialEq, Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
)] )]
pub struct Image { pub struct Image {
pub id: i32, pub id: i32,
@ -52,8 +52,7 @@ impl Content for Image {
if self.path.exists() { if self.path.exists() {
self.path self.path
.file_name() .file_name()
.map(|f| f.to_string_lossy().to_string()) .map_or("Missing image".into(), |f| f.to_string_lossy().to_string())
.unwrap_or("Missing image".into())
} else { } else {
"Missing image".into() "Missing image".into()
} }
@ -85,7 +84,7 @@ impl From<&Value> for Image {
let path = let path =
p.to_str().unwrap_or_default().to_string(); p.to_str().unwrap_or_default().to_string();
let title = let title =
path.rsplit_once("/").unwrap_or_default().1; path.rsplit_once('/').unwrap_or_default().1;
title.to_string() title.to_string()
}); });
Self { Self {
@ -154,14 +153,14 @@ impl Model<Image> {
.await; .await;
match result { match result {
Ok(v) => { Ok(v) => {
for image in v.into_iter() { for image in v {
let _ = self.add_item(image); let _ = self.add_item(image);
} }
} }
Err(e) => { Err(e) => {
error!("There was an error in converting images: {e}") error!("There was an error in converting images: {e}");
} }
}; }
} }
} }
@ -172,7 +171,7 @@ pub async fn update_image_in_db(
let path = image let path = image
.path .path
.to_str() .to_str()
.map(|s| s.to_string()) .map(std::string::ToString::to_string)
.unwrap_or_default(); .unwrap_or_default();
query!( query!(
r#"UPDATE images SET title = $2, file_path = $3 WHERE id = $1"#, r#"UPDATE images SET title = $2, file_path = $3 WHERE id = $1"#,

View file

@ -50,7 +50,7 @@ impl std::fmt::Display for ServiceItemKind {
// } // }
impl From<ServiceItemKind> for String { impl From<ServiceItemKind> for String {
fn from(val: ServiceItemKind) -> String { fn from(val: ServiceItemKind) -> Self {
match val { match val {
ServiceItemKind::Song(_) => "song".to_owned(), ServiceItemKind::Song(_) => "song".to_owned(),
ServiceItemKind::Video(_) => "video".to_owned(), ServiceItemKind::Video(_) => "video".to_owned(),

View file

@ -10,7 +10,7 @@ pub struct Model<T> {
pub kind: LibraryKind, pub kind: LibraryKind,
} }
#[derive(Debug, Clone, PartialEq, Copy)] #[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub enum LibraryKind { pub enum LibraryKind {
Song, Song,
Video, Video,
@ -46,7 +46,7 @@ impl<T> Model<T> {
Ok(()) Ok(())
} }
pub fn get_item(&self, index: i32) -> Option<&T> { #[must_use] pub fn get_item(&self, index: i32) -> Option<&T> {
self.items.get(index as usize) self.items.get(index as usize)
} }

View file

@ -75,8 +75,7 @@ impl Content for Presentation {
if self.path.exists() { if self.path.exists() {
self.path self.path
.file_name() .file_name()
.map(|f| f.to_string_lossy().to_string()) .map_or("Missing presentation".into(), |f| f.to_string_lossy().to_string())
.unwrap_or("Missing presentation".into())
} else { } else {
"Missing presentation".into() "Missing presentation".into()
} }
@ -190,14 +189,14 @@ impl ServiceTrait for Presentation {
} }
impl Presentation { impl Presentation {
pub fn new() -> Self { #[must_use] pub fn new() -> Self {
Self { Self {
title: "".to_string(), title: String::new(),
..Default::default() ..Default::default()
} }
} }
pub fn get_kind(&self) -> &PresKind { #[must_use] pub const fn get_kind(&self) -> &PresKind {
&self.kind &self.kind
} }
} }
@ -240,7 +239,7 @@ impl Model<Presentation> {
.await; .await;
match result { match result {
Ok(v) => { Ok(v) => {
for presentation in v.into_iter() { for presentation in v {
let _ = self.add_item(Presentation { let _ = self.add_item(Presentation {
id: presentation.id, id: presentation.id,
title: presentation.title, title: presentation.title,
@ -267,7 +266,7 @@ pub async fn update_presentation_in_db(
let path = presentation let path = presentation
.path .path
.to_str() .to_str()
.map(|s| s.to_string()) .map(std::string::ToString::to_string)
.unwrap_or_default(); .unwrap_or_default();
let html = presentation.kind == PresKind::Html; let html = presentation.kind == PresKind::Html;
query!( query!(

View file

@ -79,13 +79,13 @@ impl AsMimeTypes for ServiceItem {
impl From<&ServiceItem> for Value { impl From<&ServiceItem> for Value {
fn from(value: &ServiceItem) -> Self { fn from(value: &ServiceItem) -> Self {
match &value.kind { match &value.kind {
ServiceItemKind::Song(song) => Value::from(song), ServiceItemKind::Song(song) => Self::from(song),
ServiceItemKind::Video(video) => Value::from(video), ServiceItemKind::Video(video) => Self::from(video),
ServiceItemKind::Image(image) => Value::from(image), ServiceItemKind::Image(image) => Self::from(image),
ServiceItemKind::Presentation(presentation) => { ServiceItemKind::Presentation(presentation) => {
Value::from(presentation) Self::from(presentation)
} }
ServiceItemKind::Content(slide) => Value::from(slide), ServiceItemKind::Content(slide) => Self::from(slide),
} }
} }
} }
@ -172,54 +172,51 @@ impl From<&Value> for ServiceItem {
} else if let Some(background) = } else if let Some(background) =
list.get(background_pos) list.get(background_pos)
{ {
match background { if let Value::List(item) = background { match &item[0] {
Value::List(item) => match &item[0] { Value::Symbol(Symbol(s))
Value::Symbol(Symbol(s)) if s == "image" =>
if s == "image" => {
{ Self::from(&Image::from(
Self::from(&Image::from( background,
background, ))
))
}
Value::Symbol(Symbol(s))
if s == "video" =>
{
Self::from(&Video::from(
background,
))
}
Value::Symbol(Symbol(s))
if s == "presentation" =>
{
Self::from(&Presentation::from(
background,
))
}
_ => todo!(),
},
_ => {
error!(
"There is no background here: {:?}",
background
);
ServiceItem::default()
} }
Value::Symbol(Symbol(s))
if s == "video" =>
{
Self::from(&Video::from(
background,
))
}
Value::Symbol(Symbol(s))
if s == "presentation" =>
{
Self::from(&Presentation::from(
background,
))
}
_ => todo!(),
} } else {
error!(
"There is no background here: {:?}",
background
);
Self::default()
} }
} else { } else {
error!( error!(
"There is no background here: {:?}", "There is no background here: {:?}",
background_pos background_pos
); );
ServiceItem::default() Self::default()
} }
} }
Value::Symbol(Symbol(s)) if s == "song" => { Value::Symbol(Symbol(s)) if s == "song" => {
let song = lisp_to_song(list.clone()); let song = lisp_to_song(list.clone());
Self::from(&song) Self::from(&song)
} }
_ => ServiceItem::default(), _ => Self::default(),
}, },
_ => ServiceItem::default(), _ => Self::default(),
} }
} }
} }

View file

@ -107,9 +107,9 @@ impl TryFrom<&Background> for Video {
fn try_from( fn try_from(
value: &Background, value: &Background,
) -> std::result::Result<Self, Self::Error> { ) -> std::result::Result<Self, Self::Error> {
Video::new( Self::new(
&url::Url::from_file_path(value.path.clone()) &url::Url::from_file_path(value.path.clone())
.map_err(|_| ParseError::BackgroundNotVideo)?, .map_err(|()| ParseError::BackgroundNotVideo)?,
) )
.map_err(|_| ParseError::BackgroundNotVideo) .map_err(|_| ParseError::BackgroundNotVideo)
} }
@ -121,9 +121,9 @@ impl TryFrom<Background> for Video {
fn try_from( fn try_from(
value: Background, value: Background,
) -> std::result::Result<Self, Self::Error> { ) -> std::result::Result<Self, Self::Error> {
Video::new( Self::new(
&url::Url::from_file_path(value.path) &url::Url::from_file_path(value.path)
.map_err(|_| ParseError::BackgroundNotVideo)?, .map_err(|()| ParseError::BackgroundNotVideo)?,
) )
.map_err(|_| ParseError::BackgroundNotVideo) .map_err(|_| ParseError::BackgroundNotVideo)
} }
@ -132,7 +132,7 @@ impl TryFrom<Background> for Video {
impl TryFrom<String> for Background { impl TryFrom<String> for Background {
type Error = ParseError; type Error = ParseError;
fn try_from(value: String) -> Result<Self, Self::Error> { fn try_from(value: String) -> Result<Self, Self::Error> {
Background::try_from(value.as_str()) Self::try_from(value.as_str())
} }
} }
@ -147,7 +147,7 @@ impl TryFrom<PathBuf> for Background {
.to_str() .to_str()
.unwrap() .unwrap()
.to_string(); .to_string();
let path = path.replace("~", &home); let path = path.replace('~', &home);
PathBuf::from(path) PathBuf::from(path)
} else { } else {
path path
@ -192,10 +192,10 @@ impl TryFrom<&str> for Background {
type Error = ParseError; type Error = ParseError;
fn try_from(value: &str) -> Result<Self, Self::Error> { fn try_from(value: &str) -> Result<Self, Self::Error> {
let value = value.trim_start_matches("file://"); 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) = dirs::home_dir() {
if let Some(home) = home.to_str() { if let Some(home) = home.to_str() {
let value = value.replace("~", home); let value = value.replace('~', home);
Self::try_from(PathBuf::from(value)) Self::try_from(PathBuf::from(value))
} else { } else {
Self::try_from(PathBuf::from(value)) Self::try_from(PathBuf::from(value))
@ -252,9 +252,9 @@ impl Display for ParseError {
impl From<String> for BackgroundKind { impl From<String> for BackgroundKind {
fn from(value: String) -> Self { fn from(value: String) -> Self {
if value == "image" { if value == "image" {
BackgroundKind::Image Self::Image
} else { } else {
BackgroundKind::Video Self::Video
} }
} }
} }
@ -281,7 +281,7 @@ impl Slide {
self 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.font_size = font_size;
self self
} }
@ -291,12 +291,12 @@ impl Slide {
self 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.pdf_index = pdf_index;
self self
} }
pub fn background(&self) -> &Background { pub const fn background(&self) -> &Background {
&self.background &self.background
} }
@ -304,11 +304,11 @@ impl Slide {
self.text.clone() self.text.clone()
} }
pub fn text_alignment(&self) -> TextAlignment { pub const fn text_alignment(&self) -> TextAlignment {
self.text_alignment self.text_alignment
} }
pub fn font_size(&self) -> i32 { pub const fn font_size(&self) -> i32 {
self.font_size self.font_size
} }
@ -316,7 +316,7 @@ impl Slide {
self.font.clone() self.font.clone()
} }
pub fn video_loop(&self) -> bool { pub const fn video_loop(&self) -> bool {
self.video_loop self.video_loop
} }
@ -328,13 +328,13 @@ impl Slide {
self.pdf_page.clone() self.pdf_page.clone()
} }
pub fn pdf_index(&self) -> u32 { pub const fn pdf_index(&self) -> u32 {
self.pdf_index self.pdf_index
} }
pub fn song_slides(song: &Song) -> Result<Vec<Self>> { pub fn song_slides(song: &Song) -> Result<Vec<Self>> {
let lyrics = song.get_lyrics()?; let lyrics = song.get_lyrics()?;
let slides: Vec<Slide> = lyrics let slides: Vec<Self> = lyrics
.iter() .iter()
.map(|l| { .map(|l| {
let song = song.clone(); let song = song.clone();
@ -358,7 +358,7 @@ impl Slide {
Ok(slides) Ok(slides)
} }
pub(crate) fn set_index(&mut self, index: i32) { pub(crate) const fn set_index(&mut self, index: i32) {
self.id = index; self.id = index;
} }
@ -381,7 +381,7 @@ impl From<&Value> for Slide {
fn from(value: &Value) -> Self { fn from(value: &Value) -> Self {
match value { match value {
Value::List(list) => lisp_to_slide(list), Value::List(list) => lisp_to_slide(list),
_ => Slide::default(), _ => Self::default(),
} }
} }
} }
@ -404,7 +404,7 @@ fn lisp_to_slide(lisp: &Vec<Value>) -> Slide {
slide = slide.background(lisp_to_background(background)); slide = slide.background(lisp_to_background(background));
} else { } else {
slide = slide.background(Background::default()); slide = slide.background(Background::default());
}; }
let text_position = lisp.iter().position(|v| match v { let text_position = lisp.iter().position(|v| match v {
Value::List(vec) => { Value::List(vec) => {
@ -691,9 +691,7 @@ impl SlideBuilder {
impl Image { impl Image {
fn new() -> Self { fn new() -> Self {
Self { Default::default()
..Default::default()
}
} }
} }

View file

@ -128,7 +128,7 @@ impl FromRow<'_, SqliteRow> for Song {
})), })),
verse_order: Some({ verse_order: Some({
let str: &str = row.try_get(0)?; 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: { background: {
let string: String = row.try_get(7)?; let string: String = row.try_get(7)?;
@ -251,8 +251,7 @@ pub fn lisp_to_song(list: Vec<Value>) -> Song {
{ {
let pos = key_pos + 1; let pos = key_pos + 1;
list.get(pos) list.get(pos)
.map(String::from) .map_or(String::from("song"), String::from)
.unwrap_or(String::from("song"))
} else { } else {
String::from("song") String::from("song")
}; };
@ -319,30 +318,30 @@ pub fn lisp_to_song(list: Vec<Value>) -> Song {
let lyric = String::from(&lyric[1]); let lyric = String::from(&lyric[1]);
let verse_title = match lyric_verse.as_str() { let verse_title = match lyric_verse.as_str() {
"i1" => r#"\n\nIntro 1\n"#, "i1" => r"\n\nIntro 1\n",
"i2" => r#"\n\nIntro 1\n"#, "i2" => r"\n\nIntro 1\n",
"v1" => r#"\n\nVerse 1\n"#, "v1" => r"\n\nVerse 1\n",
"v2" => r#"\n\nVerse 2\n"#, "v2" => r"\n\nVerse 2\n",
"v3" => r#"\n\nVerse 3\n"#, "v3" => r"\n\nVerse 3\n",
"v4" => r#"\n\nVerse 4\n"#, "v4" => r"\n\nVerse 4\n",
"v5" => r#"\n\nVerse 5\n"#, "v5" => r"\n\nVerse 5\n",
"c1" => r#"\n\nChorus 1\n"#, "c1" => r"\n\nChorus 1\n",
"c2" => r#"\n\nChorus 2\n"#, "c2" => r"\n\nChorus 2\n",
"c3" => r#"\n\nChorus 3\n"#, "c3" => r"\n\nChorus 3\n",
"c4" => r#"\n\nChorus 4\n"#, "c4" => r"\n\nChorus 4\n",
"b1" => r#"\n\nBridge 1\n"#, "b1" => r"\n\nBridge 1\n",
"b2" => r#"\n\nBridge 2\n"#, "b2" => r"\n\nBridge 2\n",
"e1" => r#"\n\nEnding 1\n"#, "e1" => r"\n\nEnding 1\n",
"e2" => r#"\n\nEnding 2\n"#, "e2" => r"\n\nEnding 2\n",
"o1" => r#"\n\nOther 1\n"#, "o1" => r"\n\nOther 1\n",
"o2" => r#"\n\nOther 2\n"#, "o2" => r"\n\nOther 2\n",
_ => "", _ => "",
}; };
let lyric = format!("{verse_title}{lyric}"); let lyric = format!("{verse_title}{lyric}");
let lyric = lyric.replace( let lyric = lyric.replace(
"\\n", r#" "\\n", r"
"#, ",
); );
lyrics.push(lyric); lyrics.push(lyric);
} }
@ -392,15 +391,15 @@ impl Model<Song> {
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; 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 { match result {
Ok(s) => { Ok(s) => {
for song in s.into_iter() { for song in s {
match Song::from_row(&song) { match Song::from_row(&song) {
Ok(song) => { Ok(song) => {
let _ = self.add_item(song); let _ = self.add_item(song);
} }
Err(e) => { Err(e) => {
error!("Could not convert song: {e}") error!("Could not convert song: {e}");
} }
}; }
} }
} }
Err(e) => { Err(e) => {
@ -425,7 +424,7 @@ pub async fn update_song_in_db(
}) })
.collect::<String>() .collect::<String>()
} else { } else {
String::from("") String::new()
} }
}; };
@ -488,13 +487,13 @@ impl Song {
let verse_order = self.verse_order.clone(); let verse_order = self.verse_order.clone();
let mut lyric_map = HashMap::new(); let mut lyric_map = HashMap::new();
let mut verse_title = String::from(""); let mut verse_title = String::new();
let mut lyric = String::from(""); let mut lyric = String::new();
for (i, line) in raw_lyrics.split('\n').enumerate() { for (i, line) in raw_lyrics.split('\n').enumerate() {
if VERSE_KEYWORDS.contains(&line) { if VERSE_KEYWORDS.contains(&line) {
if i != 0 { if i != 0 {
lyric_map.insert(verse_title, lyric); lyric_map.insert(verse_title, lyric);
lyric = String::from(""); lyric = String::new();
verse_title = line.to_string(); verse_title = line.to_string();
} else { } else {
verse_title = line.to_string(); verse_title = line.to_string();
@ -535,7 +534,7 @@ impl Song {
lyric_list.push(lyric.to_string()); lyric_list.push(lyric.to_string());
} else { } else {
// error!("NOT WORKING!"); // error!("NOT WORKING!");
}; }
} }
// for lyric in lyric_list.iter() { // for lyric in lyric_list.iter() {
// debug!(lyric = ?lyric) // debug!(lyric = ?lyric)

View file

@ -11,7 +11,9 @@ pub fn bg_from_video(
video: &Path, video: &Path,
screenshot: &Path, screenshot: &Path,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
if !screenshot.exists() { if screenshot.exists() {
debug!("Screenshot already exists");
} else {
let output_duration = Command::new("ffprobe") let output_duration = Command::new("ffprobe")
.args(["-i", &video.to_string_lossy()]) .args(["-i", &video.to_string_lossy()])
.output() .output()
@ -26,9 +28,9 @@ pub fn bg_from_video(
let mut duration = log.split_off(duration_index + 10); let mut duration = log.split_off(duration_index + 10);
duration.truncate(11); duration.truncate(11);
// debug!("rust-duration-is: {duration}"); // debug!("rust-duration-is: {duration}");
let mut hours = String::from(""); let mut hours = String::new();
let mut minutes = String::from(""); let mut minutes = String::new();
let mut seconds = String::from(""); let mut seconds = String::new();
for (i, c) in duration.chars().enumerate() { for (i, c) in duration.chars().enumerate() {
if i <= 1 { if i <= 1 {
hours.push(c); hours.push(c);
@ -63,8 +65,6 @@ pub fn bg_from_video(
.expect("failed to execute ffmpeg"); .expect("failed to execute ffmpeg");
// io::stdout().write_all(&output.stdout).unwrap(); // io::stdout().write_all(&output.stdout).unwrap();
// io::stderr().write_all(&output.stderr).unwrap(); // io::stderr().write_all(&output.stderr).unwrap();
} else {
debug!("Screenshot already exists");
} }
Ok(()) Ok(())
} }

View file

@ -57,8 +57,7 @@ impl Content for Video {
if self.path.exists() { if self.path.exists() {
self.path self.path
.file_name() .file_name()
.map(|f| f.to_string_lossy().to_string()) .map_or("Missing video".into(), |f| f.to_string_lossy().to_string())
.unwrap_or("Missing video".into())
} else { } else {
"Missing video".into() "Missing video".into()
} }
@ -90,7 +89,7 @@ impl From<&Value> for Video {
let path = let path =
p.to_str().unwrap_or_default().to_string(); p.to_str().unwrap_or_default().to_string();
let title = let title =
path.rsplit_once("/").unwrap_or_default().1; path.rsplit_once('/').unwrap_or_default().1;
title.to_string() title.to_string()
}); });
@ -124,8 +123,7 @@ impl From<&Value> for Video {
}) { }) {
let pos = loop_pos + 1; let pos = loop_pos + 1;
list.get(pos) list.get(pos)
.map(|l| String::from(l) == *"true") .is_some_and(|l| String::from(l) == *"true")
.unwrap_or_default()
} else { } else {
false false
}; };
@ -193,14 +191,14 @@ impl Model<Video> {
let result = 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"#).fetch_all(db).await; let result = 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"#).fetch_all(db).await;
match result { match result {
Ok(v) => { Ok(v) => {
for video in v.into_iter() { for video in v {
let _ = self.add_item(video); let _ = self.add_item(video);
} }
} }
Err(e) => { Err(e) => {
error!("There was an error in converting videos: {e}") error!("There was an error in converting videos: {e}");
} }
}; }
} }
} }
@ -211,7 +209,7 @@ pub async fn update_video_in_db(
let path = video let path = video
.path .path
.to_str() .to_str()
.map(|s| s.to_string()) .map(std::string::ToString::to_string)
.unwrap_or_default(); .unwrap_or_default();
query!( query!(
r#"UPDATE videos SET title = $2, file_path = $3, start_time = $4, end_time = $5, loop = $6 WHERE id = $1"#, r#"UPDATE videos SET title = $2, file_path = $3, start_time = $4, end_time = $5, loop = $6 WHERE id = $1"#,

View file

@ -1,6 +1,6 @@
use clap::{command, Parser}; use clap::{command, Parser};
use core::service_items::ServiceItem; use core::service_items::ServiceItem;
use core::slide::*; use core::slide::{Background, Slide, SlideBuilder, TextAlignment, BackgroundKind};
use core::songs::Song; use core::songs::Song;
use cosmic::app::context_drawer::ContextDrawer; use cosmic::app::context_drawer::ContextDrawer;
use cosmic::app::{Core, Settings, Task}; use cosmic::app::{Core, Settings, Task};
@ -233,11 +233,11 @@ impl cosmic::Application for App {
// } // }
// nav_model.activate_position(0); // nav_model.activate_position(0);
let mut app = App { let mut app = Self {
presenter, presenter,
core, core,
nav_model, nav_model,
service: items.clone(), service: items,
file: PathBuf::default(), file: PathBuf::default(),
windows, windows,
presentation_open: false, presentation_open: false,
@ -248,7 +248,7 @@ impl cosmic::Application for App {
song_editor, song_editor,
searching: false, searching: false,
search_results: vec![], search_results: vec![],
search_query: "".into(), search_query: String::new(),
search_id: cosmic::widget::Id::unique(), search_id: cosmic::widget::Id::unique(),
current_item: (0, 0), current_item: (0, 0),
library_dragged_item: None, library_dragged_item: None,
@ -259,11 +259,11 @@ impl cosmic::Application for App {
if input.ui { if input.ui {
debug!("main view"); debug!("main view");
batch.push(app.update_title()) batch.push(app.update_title());
} else { } else {
debug!("window view"); debug!("window view");
batch.push(app.show_window()) batch.push(app.show_window());
}; }
batch.push(app.add_library()); batch.push(app.add_library());
// batch.push(app.add_service(items, Arc::clone(&fontdb))); // batch.push(app.add_service(items, Arc::clone(&fontdb)));
@ -403,7 +403,7 @@ impl cosmic::Application for App {
.fold(0, |a, item| a + item.slides.len()); .fold(0, |a, item| a + item.slides.len());
let total_slides_text = let total_slides_text =
format!("Total Slides: {}", total_slides); format!("Total Slides: {total_slides}");
let row = row![ let row = row![
text::body(total_items_text), text::body(total_items_text),
text::body(total_slides_text) text::body(total_slides_text)
@ -635,7 +635,7 @@ impl cosmic::Application for App {
cosmic::Action::App( cosmic::Action::App(
Message::Present(m), Message::Present(m),
) )
})) }));
} }
_ => todo!(), _ => todo!(),
} }
@ -661,7 +661,7 @@ impl cosmic::Application for App {
m, m,
), ),
) )
})) }));
} }
_ => todo!(), _ => todo!(),
} }
@ -694,7 +694,7 @@ impl cosmic::Application for App {
cosmic::Action::App( cosmic::Action::App(
Message::Present(m), Message::Present(m),
) )
})) }));
} }
_ => todo!(), _ => todo!(),
} }
@ -735,7 +735,7 @@ impl cosmic::Application for App {
m, m,
), ),
) )
})) }));
} }
_ => todo!(), _ => todo!(),
} }
@ -817,7 +817,7 @@ impl cosmic::Application for App {
self.windows.push(id); self.windows.push(id);
_ = self.set_window_title( _ = self.set_window_title(
format!("window_{}", count), format!("window_{count}"),
id, id,
); );
@ -992,7 +992,7 @@ impl cosmic::Application for App {
Task::none() Task::none()
} }
Message::CloseSearch => { Message::CloseSearch => {
self.search_query = "".into(); self.search_query = String::new();
self.search_results = vec![]; self.search_results = vec![];
self.searching = false; self.searching = false;
Task::none() Task::none()

View file

@ -133,13 +133,13 @@ impl<'a> Library {
if kind != LibraryKind::Song { if kind != LibraryKind::Song {
error!("Not editing a song item"); error!("Not editing a song item");
return Action::None; return Action::None;
}; }
match self match self
.song_library .song_library
.update_item(song.clone(), index) .update_item(song.clone(), index)
{ {
Ok(_) => { Ok(()) => {
return Action::Task( return Action::Task(
Task::future(self.db.acquire()).and_then( Task::future(self.db.acquire()).and_then(
move |conn| update_in_db(&song, conn), move |conn| update_in_db(&song, conn),
@ -162,13 +162,13 @@ impl<'a> Library {
if kind != LibraryKind::Image { if kind != LibraryKind::Image {
error!("Not editing a image item"); error!("Not editing a image item");
return Action::None; return Action::None;
}; }
match self match self
.image_library .image_library
.update_item(image.clone(), index) .update_item(image.clone(), index)
{ {
Ok(_) => { Ok(()) => {
return Action::Task( return Action::Task(
Task::future(self.db.acquire()).and_then( Task::future(self.db.acquire()).and_then(
move |conn| { move |conn| {
@ -196,13 +196,13 @@ impl<'a> Library {
if kind != LibraryKind::Video { if kind != LibraryKind::Video {
error!("Not editing a video item"); error!("Not editing a video item");
return Action::None; return Action::None;
}; }
match self match self
.video_library .video_library
.update_item(video.clone(), index) .update_item(video.clone(), index)
{ {
Ok(_) => { Ok(()) => {
return Action::Task( return Action::Task(
Task::future(self.db.acquire()).and_then( Task::future(self.db.acquire()).and_then(
move |conn| { move |conn| {
@ -230,13 +230,13 @@ impl<'a> Library {
if kind != LibraryKind::Presentation { if kind != LibraryKind::Presentation {
error!("Not editing a presentation item"); error!("Not editing a presentation item");
return Action::None; return Action::None;
}; }
match self match self
.presentation_library .presentation_library
.update_item(presentation.clone(), index) .update_item(presentation.clone(), index)
{ {
Ok(_) => return Action::Task( Ok(()) => return Action::Task(
Task::future(self.db.acquire()).and_then( Task::future(self.db.acquire()).and_then(
move |conn| { move |conn| {
Task::perform( Task::perform(
@ -254,7 +254,7 @@ impl<'a> Library {
} }
Message::PresentationChanged => (), Message::PresentationChanged => (),
Message::Error(_) => (), Message::Error(_) => (),
}; }
Action::None Action::None
} }
@ -315,7 +315,7 @@ impl<'a> Library {
textm!("Presentations").align_y(Vertical::Center), textm!("Presentations").align_y(Vertical::Center),
); );
} }
}; }
let item_count = model.items.len(); let item_count = model.items.len();
row = row.push(horizontal_space()); row = row.push(horizontal_space());
row = row row = row
@ -373,7 +373,7 @@ impl<'a> Library {
let service_item = item.to_service_item(); let service_item = item.to_service_item();
let visual_item = self let visual_item = self
.single_item(index, item, model) .single_item(index, item, model)
.map(|_| Message::None); .map(|()| Message::None);
DndSource::<Message, ServiceItem>::new( DndSource::<Message, ServiceItem>::new(
mouse_area(visual_item) mouse_area(visual_item)
.on_drag(Message::DragItem(service_item.clone())) .on_drag(Message::DragItem(service_item.clone()))
@ -418,7 +418,7 @@ impl<'a> Library {
) )
}}) }})
.drag_content(move || { .drag_content(move || {
service_item.to_owned() service_item.clone()
}) })
.into() .into()
}, },
@ -573,14 +573,14 @@ impl<'a> Library {
.items .items
.iter() .iter()
.filter(|song| song.title.to_lowercase().contains(&query)) .filter(|song| song.title.to_lowercase().contains(&query))
.map(|song| song.to_service_item()) .map(super::super::core::content::Content::to_service_item)
.collect(); .collect();
let videos: Vec<ServiceItem> = self let videos: Vec<ServiceItem> = self
.video_library .video_library
.items .items
.iter() .iter()
.filter(|vid| vid.title.to_lowercase().contains(&query)) .filter(|vid| vid.title.to_lowercase().contains(&query))
.map(|vid| vid.to_service_item()) .map(super::super::core::content::Content::to_service_item)
.collect(); .collect();
let images: Vec<ServiceItem> = self let images: Vec<ServiceItem> = self
.image_library .image_library
@ -589,14 +589,14 @@ impl<'a> Library {
.filter(|image| { .filter(|image| {
image.title.to_lowercase().contains(&query) image.title.to_lowercase().contains(&query)
}) })
.map(|image| image.to_service_item()) .map(super::super::core::content::Content::to_service_item)
.collect(); .collect();
let presentations: Vec<ServiceItem> = self let presentations: Vec<ServiceItem> = self
.presentation_library .presentation_library
.items .items
.iter() .iter()
.filter(|pres| pres.title.to_lowercase().contains(&query)) .filter(|pres| pres.title.to_lowercase().contains(&query))
.map(|pres| pres.to_service_item()) .map(super::super::core::content::Content::to_service_item)
.collect(); .collect();
items.extend(videos); items.extend(videos);
items.extend(images); items.extend(images);
@ -656,7 +656,7 @@ fn update_in_db(
Task::perform( Task::perform(
update_song_in_db(song.to_owned(), conn).map( update_song_in_db(song.to_owned(), conn).map(
move |r| match r { move |r| match r {
Ok(_) => { Ok(()) => {
warn!( warn!(
"Should have updated song: {:?}", "Should have updated song: {:?}",
song_title song_title
@ -667,7 +667,7 @@ fn update_in_db(
} }
}, },
), ),
|_| Message::SongChanged, |()| Message::SongChanged,
) )
} }

View file

@ -154,7 +154,7 @@ impl Presenter {
absolute_slide_index: 0, absolute_slide_index: 0,
total_slides, total_slides,
video, video,
audio: items[0].slides[0].audio().clone(), audio: items[0].slides[0].audio(),
service: items, service: items,
video_position: 0.0, video_position: 0.0,
hovered_slide: None, hovered_slide: None,
@ -221,8 +221,7 @@ impl Presenter {
let offset = AbsoluteOffset { let offset = AbsoluteOffset {
x: { x: {
if self.current_slide_index > 2 { if self.current_slide_index > 2 {
self.current_slide_index as f32 * 187.5 (self.current_slide_index as f32).mul_add(187.5, -187.5)
- 187.5
} else { } else {
0.0 0.0
} }
@ -256,7 +255,7 @@ impl Presenter {
?current_audio, ?current_audio,
"audio needs to change" "audio needs to change"
); );
self.audio = Some(new_audio.clone()); self.audio = Some(new_audio);
tasks.push(self.start_audio()); tasks.push(self.start_audio());
} }
Some(current_audio) => { Some(current_audio) => {
@ -271,10 +270,10 @@ impl Presenter {
?new_audio, ?new_audio,
"could not find audio, need to change" "could not find audio, need to change"
); );
self.audio = Some(new_audio.clone()); self.audio = Some(new_audio);
tasks.push(self.start_audio()); tasks.push(self.start_audio());
} }
}; }
} else { } else {
self.audio = None; self.audio = None;
self.update(Message::EndAudio); self.update(Message::EndAudio);
@ -326,7 +325,7 @@ impl Presenter {
std::time::Duration::from_secs_f32(position), std::time::Duration::from_secs_f32(position),
); );
match video.seek(position, false) { match video.seek(position, false) {
Ok(_) => debug!( Ok(()) => debug!(
"Video position changed: {:?}", "Video position changed: {:?}",
position position
), ),
@ -355,7 +354,7 @@ impl Presenter {
install_ctx install_ctx
.set_desktop_id(&format!("{}.desktop", "org.chriscochrun.lumina")); .set_desktop_id(&format!("{}.desktop", "org.chriscochrun.lumina"));
let install_detail = missing_plugin.installer_detail(); let install_detail = missing_plugin.installer_detail();
println!("installing plugins: {}", install_detail); println!("installing plugins: {install_detail}");
let status = gst_pbutils::missing_plugins::install_plugins_sync( let status = gst_pbutils::missing_plugins::install_plugins_sync(
&[&install_detail], &[&install_detail],
Some(&install_ctx), Some(&install_ctx),
@ -391,7 +390,7 @@ impl Presenter {
Message::Error(error) => { Message::Error(error) => {
error!(error); error!(error);
} }
}; }
Action::None Action::None
} }
@ -641,7 +640,7 @@ impl Presenter {
v.set_looping( v.set_looping(
self.current_slide.video_loop(), self.current_slide.video_loop(),
); );
self.video = Some(v) self.video = Some(v);
} }
Err(e) => { Err(e) => {
error!( error!(
@ -664,7 +663,7 @@ impl Presenter {
let audio = audio.clone(); let audio = audio.clone();
Task::perform( Task::perform(
start_audio(Arc::clone(&self.sink.1), audio), start_audio(Arc::clone(&self.sink.1), audio),
|_| Message::None, |()| Message::None,
) )
} else { } else {
debug!(?self.audio, "Apparently this doesn't exist"); debug!(?self.audio, "Apparently this doesn't exist");

View file

@ -54,10 +54,10 @@ struct EditorProgram {
} }
impl SlideEditor { impl SlideEditor {
pub fn view<'a>( pub fn view(
&'a self, &self,
font: Font, font: Font,
) -> cosmic::Element<'a, SlideWidget> { ) -> cosmic::Element<'_, SlideWidget> {
container( container(
widget::canvas(&self.program) widget::canvas(&self.program)
.height(Length::Fill) .height(Length::Fill)
@ -122,10 +122,10 @@ impl<'a> Program<SlideWidget, cosmic::Theme, cosmic::Renderer>
match event { match event {
canvas::Event::Mouse(event) => match event { canvas::Event::Mouse(event) => match event {
cosmic::iced::mouse::Event::CursorEntered => { cosmic::iced::mouse::Event::CursorEntered => {
debug!("cursor entered") debug!("cursor entered");
} }
cosmic::iced::mouse::Event::CursorLeft => { cosmic::iced::mouse::Event::CursorLeft => {
debug!("cursor left") debug!("cursor left");
} }
cosmic::iced::mouse::Event::CursorMoved { cosmic::iced::mouse::Event::CursorMoved {
position, position,
@ -140,7 +140,7 @@ impl<'a> Program<SlideWidget, cosmic::Theme, cosmic::Renderer>
} }
cosmic::iced::mouse::Event::ButtonPressed(button) => { cosmic::iced::mouse::Event::ButtonPressed(button) => {
// self.mouse_button_pressed = Some(button); // self.mouse_button_pressed = Some(button);
debug!(?button, "mouse button pressed") debug!(?button, "mouse button pressed");
} }
cosmic::iced::mouse::Event::ButtonReleased( cosmic::iced::mouse::Event::ButtonReleased(
button, button,

View file

@ -140,11 +140,11 @@ impl SongEditor {
self.song = Some(song.clone()); self.song = Some(song.clone());
self.title = song.title; self.title = song.title;
if let Some(font) = song.font { if let Some(font) = song.font {
self.font = font self.font = font;
}; }
if let Some(font_size) = song.font_size { if let Some(font_size) = song.font_size {
self.font_size = font_size as usize self.font_size = font_size as usize;
}; }
if let Some(verse_order) = song.verse_order { if let Some(verse_order) = song.verse_order {
self.verse_order = verse_order self.verse_order = verse_order
.into_iter() .into_iter()
@ -155,18 +155,18 @@ impl SongEditor {
.collect(); .collect();
} }
if let Some(author) = song.author { if let Some(author) = song.author {
self.author = author self.author = author;
}; }
if let Some(audio) = song.audio { if let Some(audio) = song.audio {
self.audio = audio self.audio = audio;
}; }
if let Some(ccli) = song.ccli { if let Some(ccli) = song.ccli {
self.ccli = ccli self.ccli = ccli;
}; }
if let Some(lyrics) = song.lyrics { if let Some(lyrics) = song.lyrics {
self.lyrics = self.lyrics =
text_editor::Content::with_text(&lyrics) text_editor::Content::with_text(&lyrics);
}; }
self.background_video(&song.background); self.background_video(&song.background);
self.background = song.background; self.background = song.background;
} }
@ -212,8 +212,8 @@ impl SongEditor {
self.verse_order = verse_order.clone(); self.verse_order = verse_order.clone();
if let Some(mut song) = self.song.clone() { if let Some(mut song) = self.song.clone() {
let verse_order = verse_order let verse_order = verse_order
.split(" ") .split(' ')
.map(|s| s.to_owned()) .map(std::borrow::ToOwned::to_owned)
.collect(); .collect();
song.verse_order = Some(verse_order); song.verse_order = Some(verse_order);
return self.update_song(song); return self.update_song(song);
@ -245,7 +245,7 @@ impl SongEditor {
debug!(?path); debug!(?path);
if let Some(mut song) = self.song.clone() { if let Some(mut song) = self.song.clone() {
let background = let background =
Background::try_from(path.clone()).ok(); Background::try_from(path).ok();
self.background_video(&background); self.background_video(&background);
song.background = background; song.background = background;
return self.update_song(song); return self.update_song(song);
@ -416,7 +416,7 @@ order",
.into() .into()
} }
pub fn editing(&self) -> bool { pub const fn editing(&self) -> bool {
self.editing self.editing
} }

View file

@ -121,15 +121,15 @@ impl From<&str> for Font {
} }
impl Font { impl Font {
pub fn get_name(&self) -> String { #[must_use] pub fn get_name(&self) -> String {
self.name.clone() self.name.clone()
} }
pub fn get_weight(&self) -> Weight { #[must_use] pub const fn get_weight(&self) -> Weight {
self.weight self.weight
} }
pub fn get_style(&self) -> Style { #[must_use] pub const fn get_style(&self) -> Style {
self.style self.style
} }
@ -148,7 +148,7 @@ impl Font {
self self
} }
pub fn size(mut self, size: u8) -> Self { #[must_use] pub const fn size(mut self, size: u8) -> Self {
self.size = size; self.size = size;
self self
} }
@ -161,12 +161,12 @@ impl Hash for Color {
} }
impl Color { impl Color {
pub fn from_hex_str(color: impl AsRef<str>) -> Color { pub fn from_hex_str(color: impl AsRef<str>) -> Self {
match Rgb::from_hex_str(color.as_ref()) { match Rgb::from_hex_str(color.as_ref()) {
Ok(rgb) => Color(rgb), Ok(rgb) => Self(rgb),
Err(e) => { Err(e) => {
error!("error in making color from hex_str: {:?}", e); error!("error in making color from hex_str: {:?}", e);
Color::default() Self::default()
} }
} }
} }
@ -236,7 +236,7 @@ impl TextSvg {
self self
} }
pub fn alignment(mut self, alignment: TextAlignment) -> Self { pub const fn alignment(mut self, alignment: TextAlignment) -> Self {
self.alignment = alignment; self.alignment = alignment;
self self
} }
@ -255,7 +255,7 @@ impl TextSvg {
shadow.spread, shadow.spread,
shadow.color) shadow.color)
} else { } else {
"".into() String::new()
}; };
let stroke = if let Some(stroke) = &self.stroke { let stroke = if let Some(stroke) = &self.stroke {
format!( format!(
@ -263,17 +263,17 @@ impl TextSvg {
stroke.color, stroke.size stroke.color, stroke.size
) )
} else { } else {
"".into() String::new()
}; };
let size = Size::new(1920.0, 1080.0); let size = Size::new(1920.0, 1080.0);
let font_size = self.font.size as f32; let font_size = f32::from(self.font.size);
let total_lines = self.text.lines().count(); let total_lines = self.text.lines().count();
let half_lines = (total_lines / 2) as f32; let half_lines = (total_lines / 2) as f32;
let middle_position = size.height / 2.0; let middle_position = size.height / 2.0;
let line_spacing = 10.0; let line_spacing = 10.0;
let text_and_line_spacing = font_size + line_spacing; let text_and_line_spacing = font_size + line_spacing;
let starting_y_position = let starting_y_position =
middle_position - (half_lines * text_and_line_spacing); half_lines.mul_add(-text_and_line_spacing, middle_position);
let text_pieces: Vec<String> = self let text_pieces: Vec<String> = self
.text .text
@ -282,8 +282,7 @@ impl TextSvg {
.map(|(index, text)| { .map(|(index, text)| {
format!( format!(
"<tspan x=\"50%\" y=\"{}\">{}</tspan>", "<tspan x=\"50%\" y=\"{}\">{}</tspan>",
starting_y_position (index as f32).mul_add(text_and_line_spacing, starting_y_position),
+ (index as f32 * text_and_line_spacing),
text text
) )
}) })
@ -350,7 +349,7 @@ impl TextSvg {
self.text self.text
.lines() .lines()
.enumerate() .enumerate()
.map(|(i, t)| format!("<tspan x=\"50%\">{}</tspan>", t)) .map(|(i, t)| format!("<tspan x=\"50%\">{t}</tspan>"))
.collect() .collect()
} }
} }
@ -391,7 +390,7 @@ pub fn text_svg_generator(
.shadow(shadow(2, 2, 5, "#000000")) .shadow(shadow(2, 2, 5, "#000000"))
.stroke(stroke(3, "#000")) .stroke(stroke(3, "#000"))
.font( .font(
Font::from(slide.font().clone()) Font::from(slide.font())
.size(slide.font_size().try_into().unwrap()), .size(slide.font_size().try_into().unwrap()),
) )
.fontdb(Arc::clone(&fontdb)) .fontdb(Arc::clone(&fontdb))