chore(clippy): thumbnailer.rs, two files in operation

Fixes Clippy lints for:
* src/thumbnailer.rs
* src/operation/mod.rs
* src/operation/recursive.rs

One of the Clippy lints also involved fixing a TODO to replace a
deprecated function that malfunctioned under Windows.
This commit is contained in:
Josh Megnauth 2025-01-17 22:29:57 -05:00 • committed by Jeremy Soller
parent 3460c2c106
commit df2d01e9ba
3 changed files with 35 additions and 23 deletions

View file

@ -683,7 +683,7 @@ impl Operation {
path.strip_prefix(relative_root).map_err(err_str)?.to_str() path.strip_prefix(relative_root).map_err(err_str)?.to_str()
{ {
if path.is_file() { if path.is_file() {
let mut file = fs::File::open(&path).map_err(err_str)?; let mut file = fs::File::open(path).map_err(err_str)?;
let metadata = file.metadata().map_err(err_str)?; let metadata = file.metadata().map_err(err_str)?;
let total = metadata.len(); let total = metadata.len();
if total >= 4 * 1024 * 1024 * 1024 { if total >= 4 * 1024 * 1024 * 1024 {
@ -800,7 +800,7 @@ impl Operation {
op_sel.selected.push(new_dir.clone()); op_sel.selected.push(new_dir.clone());
let controller = controller.clone(); let controller = controller.clone();
let mime = mime_for_path(&path); let mime = mime_for_path(path);
match mime.essence_str() { match mime.essence_str() {
"application/gzip" | "application/x-compressed-tar" => { "application/gzip" | "application/x-compressed-tar" => {
OpReader::new(path, controller) OpReader::new(path, controller)
@ -960,7 +960,7 @@ mod tests {
}; };
use cosmic::iced::futures::{channel::mpsc, StreamExt}; use cosmic::iced::futures::{channel::mpsc, StreamExt};
use log::{debug, trace}; use log::debug;
use test_log::test; use test_log::test;
use tokio::sync; use tokio::sync;
@ -968,8 +968,8 @@ mod tests {
use crate::{ use crate::{
app::{ app::{
test_utils::{ test_utils::{
empty_fs, filter_dirs, filter_files, read_dir_sorted, simple_fs, NAME_LEN, empty_fs, filter_dirs, filter_files, simple_fs, NAME_LEN, NUM_DIRS, NUM_FILES,
NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, NUM_HIDDEN, NUM_NESTED,
}, },
DialogPage, Message, DialogPage, Message,
}, },

View file

@ -12,12 +12,18 @@ use super::{copy_unique_path, Controller, OperationSelection, ReplaceResult};
pub struct Context { pub struct Context {
buf: Vec<u8>, buf: Vec<u8>,
controller: Controller, controller: Controller,
on_progress: Box<dyn Fn(&Op, &Progress) + 'static>, on_progress: Box<dyn OnProgress>,
on_replace: Box<dyn Fn(&Op) -> ReplaceResult + 'static>, on_replace: Box<dyn OnReplace>,
pub(crate) op_sel: OperationSelection, pub(crate) op_sel: OperationSelection,
replace_result_opt: Option<ReplaceResult>, replace_result_opt: Option<ReplaceResult>,
} }
pub trait OnProgress: Fn(&Op, &Progress) + 'static {}
impl<F> OnProgress for F where F: Fn(&Op, &Progress) + 'static {}
pub trait OnReplace: Fn(&Op) -> ReplaceResult + 'static {}
impl<F> OnReplace for F where F: Fn(&Op) -> ReplaceResult + 'static {}
impl Context { impl Context {
pub fn new(controller: Controller) -> Self { pub fn new(controller: Controller) -> Self {
Self { Self {
@ -67,7 +73,7 @@ impl Context {
OpKind::Symlink { target } OpKind::Symlink { target }
} else { } else {
//TODO: present dialog and allow continue //TODO: present dialog and allow continue
return Err(format!("{} is not a known file type", from.display()).into()); return Err(format!("{} is not a known file type", from.display()));
}; };
let to = if from == from_parent { let to = if from == from_parent {
// When copying a file, from matches from_parent, and to_parent must be used // When copying a file, from matches from_parent, and to_parent must be used
@ -130,12 +136,12 @@ impl Context {
Ok(true) Ok(true)
} }
pub fn on_progress<F: Fn(&Op, &Progress) + 'static>(mut self, f: F) -> Self { pub fn on_progress<F: OnProgress>(mut self, f: F) -> Self {
self.on_progress = Box::new(f); self.on_progress = Box::new(f);
self self
} }
pub fn on_replace<F: Fn(&Op) -> ReplaceResult + 'static>(mut self, f: F) -> Self { pub fn on_replace<F: OnReplace>(mut self, f: F) -> Self {
self.on_replace = Box::new(f); self.on_replace = Box::new(f);
self self
} }
@ -153,9 +159,7 @@ impl Context {
Ok(ControlFlow::Continue(op.to.clone())) Ok(ControlFlow::Continue(op.to.clone()))
} }
ReplaceResult::KeepBoth => match op.to.parent() { ReplaceResult::KeepBoth => match op.to.parent() {
Some(to_parent) => Ok(ControlFlow::Continue(copy_unique_path( Some(to_parent) => Ok(ControlFlow::Continue(copy_unique_path(&op.from, to_parent))),
&op.from, &to_parent,
))),
None => Err(format!("failed to get parent of {:?}", op.to).into()), None => Err(format!("failed to get parent of {:?}", op.to).into()),
}, },
ReplaceResult::Skip(apply_to_all) => { ReplaceResult::Skip(apply_to_all) => {
@ -216,7 +220,7 @@ impl Op {
let metadata = from_file.metadata()?; let metadata = from_file.metadata()?;
// Remove `to` if overwriting and it is an existing file // Remove `to` if overwriting and it is an existing file
if self.to.is_file() { if self.to.is_file() {
match ctx.replace(&self)? { match ctx.replace(self)? {
ControlFlow::Continue(to) => { ControlFlow::Continue(to) => {
self.to = to; self.to = to;
} }
@ -226,7 +230,7 @@ impl Op {
} }
} }
progress.total_bytes = Some(metadata.len()); progress.total_bytes = Some(metadata.len());
(ctx.on_progress)(&self, &progress); (ctx.on_progress)(self, &progress);
// This is atomic and ensures `to` is not created by any other process // This is atomic and ensures `to` is not created by any other process
let mut to_file = fs::OpenOptions::new() let mut to_file = fs::OpenOptions::new()
.create_new(true) .create_new(true)
@ -242,14 +246,14 @@ impl Op {
} }
to_file.write_all(&ctx.buf[..count])?; to_file.write_all(&ctx.buf[..count])?;
progress.current_bytes += count as u64; progress.current_bytes += count as u64;
(ctx.on_progress)(&self, &progress); (ctx.on_progress)(self, &progress);
} }
to_file.sync_all()?; to_file.sync_all()?;
} }
OpKind::Move => { OpKind::Move => {
// Remove `to` if overwriting and it is an existing file // Remove `to` if overwriting and it is an existing file
if self.to.is_file() { if self.to.is_file() {
match ctx.replace(&self)? { match ctx.replace(self)? {
ControlFlow::Continue(to) => { ControlFlow::Continue(to) => {
self.to = to; self.to = to;
} }
@ -289,7 +293,7 @@ impl Op {
OpKind::Symlink { ref target } => { OpKind::Symlink { ref target } => {
// Remove `to` if overwriting and it is an existing file // Remove `to` if overwriting and it is an existing file
if self.to.is_file() { if self.to.is_file() {
match ctx.replace(&self)? { match ctx.replace(self)? {
ControlFlow::Continue(to) => { ControlFlow::Continue(to) => {
self.to = to; self.to = to;
} }
@ -298,8 +302,18 @@ impl Op {
} }
} }
} }
//TODO: use OS-specific function #[cfg(unix)]
fs::soft_link(&target, &self.to)?; {
std::os::unix::fs::symlink(target, &self.to)?;
}
#[cfg(windows)]
{
if target.is_dir() {
std::os::windows::fs::symlink_dir(target, &self.to)?;
} else {
std::os::windows::fs::symlink_file(target, &self.to)?;
}
}
} }
} }
Ok(true) Ok(true)

View file

@ -144,9 +144,7 @@ impl ThumbnailerCache {
} }
pub fn get(&self, key: &Mime) -> Vec<Thumbnailer> { pub fn get(&self, key: &Mime) -> Vec<Thumbnailer> {
self.cache self.cache.get(key).map_or_else(Vec::new, |x| x.clone())
.get(&key)
.map_or_else(|| Vec::new(), |x| x.clone())
} }
} }