diff --git a/examples/copy.rs b/examples/copy.rs index 2015848..bc117bc 100644 --- a/examples/copy.rs +++ b/examples/copy.rs @@ -2,7 +2,7 @@ use cosmic_files::operation::{recursive::Context, Controller, ReplaceResult}; use std::{error::Error, io, path::PathBuf}; fn main() -> Result<(), Box> { - let mut context = Context::new(Controller::new()) + let mut context = Context::new(Controller::default()) .on_progress(|op, progress| { println!("{:?}: {:?}", op.to, progress); }) diff --git a/src/app.rs b/src/app.rs index 88f35d9..d9e667b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -798,7 +798,7 @@ impl App { self.progress_operations.insert(id); } self.pending_operations - .insert(id, (operation, Controller::new())); + .insert(id, (operation, Controller::default())); } fn remove_window(&mut self, id: &window::Id) { diff --git a/src/config.rs b/src/config.rs index 36153da..50dfcba 100644 --- a/src/config.rs +++ b/src/config.rs @@ -68,7 +68,7 @@ impl Favorite { Self::Videos, ] { if let Some(favorite_path) = favorite.path_opt() { - if &favorite_path == &path { + if favorite_path == path { return favorite.clone(); } } diff --git a/src/dialog.rs b/src/dialog.rs index a5a792a..586a0c0 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -157,13 +157,15 @@ impl Dialog { let (config_handler, config) = Config::load(); - let mut settings = window::Settings::default(); - settings.decorations = false; - settings.exit_on_close_request = false; - settings.min_size = Some(Size::new(360.0, 180.0)); - settings.resizable = true; - settings.size = Size::new(1024.0, 640.0); - settings.transparent = true; + let mut settings = window::Settings { + decorations: false, + exit_on_close_request: false, + min_size: Some(Size::new(360.0, 180.0)), + resizable: true, + size: Size::new(1024.0, 640.0), + transparent: true, + ..Default::default() + }; #[cfg(target_os = "linux")] { @@ -296,6 +298,7 @@ struct Flags { kind: DialogKind, path_opt: Option, window_id: window::Id, + #[expect(dead_code)] config_handler: Option, config: Config, } @@ -324,6 +327,7 @@ enum Message { SearchActivate, SearchClear, SearchInput(String), + #[allow(clippy::enum_variant_names)] TabMessage(tab::Message), TabRescan(Location, Option, Vec), TabView(tab::View), @@ -598,7 +602,7 @@ impl App { .data(Location::Recents) }); - for (_favorite_i, favorite) in self.flags.config.favorites.iter().enumerate() { + for favorite in self.flags.config.favorites.iter() { if let Some(path) = favorite.path_opt() { let name = if matches!(favorite, Favorite::Home) { fl!("home") @@ -974,11 +978,8 @@ impl Application for App { ContextPage::Preview(..) => self.core.window.show_context, _ => false, }; - elements.push( - menu::dialog_menu(&self.tab, &self.key_binds, show_details) - .map(Message::from) - .into(), - ); + elements + .push(menu::dialog_menu(&self.tab, &self.key_binds, show_details).map(Message::from)); elements } @@ -1027,7 +1028,7 @@ impl Application for App { return self.update(message); } - if let Some(data) = self.nav_model.data::(entity).clone() { + if let Some(data) = self.nav_model.data::(entity) { if let Some(mounter) = MOUNTERS.get(&data.0) { return mounter.mount(data.1.clone()).map(|_| message::none()); } @@ -1169,11 +1170,9 @@ impl Application for App { let mut still_mounted = false; for item in mounter_items.iter() { if let Some(path) = item.path() { - if path == old_path { - if item.is_mounted() { - still_mounted = true; - break; - } + if path == old_path && item.is_mounted() { + still_mounted = true; + break; } } } @@ -1221,7 +1220,7 @@ impl Application for App { let mut contains_change = false; for event in events.iter() { for event_path in event.paths.iter() { - if event_path.starts_with(&path) { + if event_path.starts_with(path) { match event.kind { notify::EventKind::Modify( notify::event::ModifyKind::Metadata(_), @@ -1235,14 +1234,14 @@ impl Application for App { for item in items.iter_mut() { if item.path_opt() == Some(event_path) { //TODO: reload more, like mime types? - match fs::metadata(&event_path) { + match fs::metadata(event_path) { Ok(new_metadata) => { - match &mut item.metadata { - ItemMetadata::Path { - metadata, - .. - } => *metadata = new_metadata, - _ => {} + if let ItemMetadata::Path { + metadata, + .. + } = &mut item.metadata + { + *metadata = new_metadata; } } Err(err) => { @@ -1322,12 +1321,9 @@ impl Application for App { // If we are in directory mode, return the current directory if self.flags.kind.is_dir() { - match &self.tab.location { - Location::Path(tab_path) => { - self.result_opt = Some(DialogResult::Open(vec![tab_path.clone()])); - return window::close(self.flags.window_id); - } - _ => {} + if let Location::Path(tab_path) = &self.tab.location { + self.result_opt = Some(DialogResult::Open(vec![tab_path.clone()])); + return window::close(self.flags.window_id); } } } @@ -1344,7 +1340,7 @@ impl Application for App { if let DialogKind::SaveFile { filename } = &self.flags.kind { if !filename.is_empty() { if let Some(tab_path) = self.tab.location.path_opt() { - let path = tab_path.join(&filename); + let path = tab_path.join(filename); if path.is_dir() { // cd to directory let message = Message::TabMessage(tab::Message::Location( @@ -1592,11 +1588,7 @@ impl Application for App { } } - col = col.push( - self.tab - .view(&self.key_binds) - .map(move |message| Message::TabMessage(message)), - ); + col = col.push(self.tab.view(&self.key_binds).map(Message::TabMessage)); col.into() } diff --git a/src/menu.rs b/src/menu.rs index abd602a..219a463 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -89,7 +89,7 @@ pub fn context_menu<'a>( let mut selected_trash_only = false; let mut selected_desktop_entry = None; let mut selected_types: Vec = vec![]; - tab.items_opt().map(|items| { + if let Some(items) = tab.items_opt() { for item in items.iter() { if item.selected { selected += 1; @@ -110,7 +110,7 @@ pub fn context_menu<'a>( selected_types.push(item.mime.clone()); } } - }); + }; selected_types.sort_unstable(); selected_types.dedup(); selected_trash_only = selected_trash_only && selected == 1; @@ -342,7 +342,7 @@ pub fn context_menu<'a>( .into() } -pub fn dialog_menu<'a>( +pub fn dialog_menu( tab: &Tab, key_binds: &HashMap, show_details: bool, @@ -359,15 +359,13 @@ pub fn dialog_menu<'a>( let in_trash = tab.location == Location::Trash; let mut selected_gallery = 0; - tab.items_opt().map(|items| { + if let Some(items) = tab.items_opt() { for item in items.iter() { - if item.selected { - if item.can_gallery() { - selected_gallery += 1; - } + if item.selected && item.can_gallery() { + selected_gallery += 1; } } - }); + }; MenuBar::new(vec![ menu::Tree::with_children( @@ -504,7 +502,7 @@ pub fn menu_bar<'a>( let mut selected_dir = 0; let mut selected = 0; let mut selected_gallery = 0; - tab_opt.and_then(|tab| tab.items_opt()).map(|items| { + if let Some(items) = tab_opt.and_then(|tab| tab.items_opt()) { for item in items.iter() { if item.selected { selected += 1; @@ -516,7 +514,7 @@ pub fn menu_bar<'a>( } } } - }); + }; MenuBar::new(vec![ menu::Tree::with_children( diff --git a/src/mime_app.rs b/src/mime_app.rs index 9e11011..3dfa1c3 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -120,7 +120,7 @@ impl MimeAppCache { .cache .entry(mime.clone()) .or_insert_with(|| Vec::with_capacity(1)); - if apps.iter().find(|x| x.id == app.id).is_none() { + if !apps.iter().any(|x| x.id == app.id) { apps.push(MimeApp::from(app)); } } @@ -191,11 +191,7 @@ impl MimeAppCache { .cache .entry(mime.clone()) .or_insert_with(|| Vec::with_capacity(1)); - if apps - .iter() - .find(|x| filename_eq(&x.path, filename)) - .is_none() - { + if !apps.iter().any(|x| filename_eq(&x.path, filename)) { if let Some(app) = all_apps.iter().find(|x| filename_eq(&x.path, filename)) { @@ -263,9 +259,7 @@ impl MimeAppCache { } pub fn get(&self, key: &Mime) -> Vec { - self.cache - .get(&key) - .map_or_else(|| Vec::new(), |x| x.clone()) + self.cache.get(key).map_or_else(Vec::new, |x| x.clone()) } } @@ -292,5 +286,5 @@ pub fn terminal() -> Option { } // Return whatever was the first terminal found - mime_app_cache.terminals.first().map(|x| x.clone()) + mime_app_cache.terminals.first().cloned() } diff --git a/src/mounter/gvfs.rs b/src/mounter/gvfs.rs index e5b046c..c24fd92 100644 --- a/src/mounter/gvfs.rs +++ b/src/mounter/gvfs.rs @@ -97,7 +97,7 @@ fn network_scan(uri: &str, sizes: IconSizes) -> Result, String> { info.icon() .as_ref() .and_then(|icon| gio_icon_to_path(icon, size)) - .map(|path| widget::icon::from_path(path)) + .map(widget::icon::from_path) .unwrap_or( widget::icon::from_name(if metadata.is_dir() { "folder" @@ -388,10 +388,7 @@ impl Gvfs { let file = gio::File::for_uri(&uri); let needs_mount = match file.find_enclosing_mount(gio::Cancellable::NONE) { Ok(_) => false, - Err(err) => match err.kind::() { - Some(gio::IOErrorEnum::NotMounted) => true, - _ => false - } + Err(err) => matches!(err.kind::(), Some(gio::IOErrorEnum::NotMounted)) }; if needs_mount { let mount_op = mount_op(uri.clone(), event_tx.clone()); @@ -468,7 +465,6 @@ impl Mounter for Gvfs { Task::perform( async move { command_tx.send(Cmd::Mount(item)).unwrap(); - () }, |x| x, ) @@ -479,7 +475,6 @@ impl Mounter for Gvfs { Task::perform( async move { command_tx.send(Cmd::NetworkDrive(uri)).unwrap(); - () }, |x| x, ) @@ -498,7 +493,6 @@ impl Mounter for Gvfs { Task::perform( async move { command_tx.send(Cmd::Unmount(item)).unwrap(); - () }, |x| x, ) diff --git a/src/mounter/mod.rs b/src/mounter/mod.rs index 7258df7..8b13392 100644 --- a/src/mounter/mod.rs +++ b/src/mounter/mod.rs @@ -117,4 +117,4 @@ pub fn mounters() -> Mounters { Mounters::new(mounters) } -pub static MOUNTERS: Lazy = Lazy::new(|| mounters()); +pub static MOUNTERS: Lazy = Lazy::new(mounters); diff --git a/src/mouse_area.rs b/src/mouse_area.rs index 33291eb..164cac7 100644 --- a/src/mouse_area.rs +++ b/src/mouse_area.rs @@ -31,156 +31,150 @@ use crate::tab::DOUBLE_CLICK_DURATION; pub struct MouseArea<'a, Message> { id: Id, content: Element<'a, Message>, - on_drag: Option) -> Message + 'a>>, - on_double_click: Option) -> Message + 'a>>, - on_press: Option) -> Message + 'a>>, - on_drag_end: Option) -> Message + 'a>>, - on_release: Option) -> Message + 'a>>, - on_resize: Option Message + 'a>>, - on_right_press: Option) -> Message + 'a>>, - on_right_press_no_capture: Option) -> Message + 'a>>, - on_right_release: Option) -> Message + 'a>>, - on_middle_press: Option) -> Message + 'a>>, - on_middle_release: Option) -> Message + 'a>>, - on_back_press: Option) -> Message + 'a>>, - on_back_release: Option) -> Message + 'a>>, - on_forward_press: Option) -> Message + 'a>>, - on_forward_release: Option) -> Message + 'a>>, - on_scroll: Option Option + 'a>>, - on_enter: Option Message + 'a>>, - on_exit: Option Message + 'a>>, + on_drag: Option>>, + on_double_click: Option>>, + on_press: Option>>, + on_drag_end: Option>>, + on_release: Option>>, + on_resize: Option>>, + on_right_press: Option>>, + on_right_press_no_capture: Option>>, + on_right_release: Option>>, + on_middle_press: Option>>, + on_middle_release: Option>>, + on_back_press: Option>>, + on_back_release: Option>>, + on_forward_press: Option>>, + on_forward_release: Option>>, + on_scroll: Option>>, + on_enter: Option>>, + on_exit: Option>>, show_drag_rect: bool, } impl<'a, Message> MouseArea<'a, Message> { /// The message to emit when a drag is initiated. #[must_use] - pub fn on_drag(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_drag(mut self, message: impl OnDrag<'a, Message>) -> Self { self.on_drag = Some(Box::new(message)); self } /// The message to emit when a drag ends. #[must_use] - pub fn on_drag_end(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_drag_end(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_drag_end = Some(Box::new(message)); self } /// The message to emit on a double click. #[must_use] - pub fn on_double_click(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_double_click(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_double_click = Some(Box::new(message)); self } /// The message to emit on a left button press. #[must_use] - pub fn on_press(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_press(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_press = Some(Box::new(message)); self } /// The message to emit on a left button release. #[must_use] - pub fn on_release(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_release(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_release = Some(Box::new(message)); self } /// The message to emit on resizing. #[must_use] - pub fn on_resize(mut self, message: impl Fn(Size) -> Message + 'a) -> Self { + pub fn on_resize(mut self, message: impl OnResize<'a, Message>) -> Self { self.on_resize = Some(Box::new(message)); self } /// The message to emit on a right button press. #[must_use] - pub fn on_right_press(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_right_press(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_right_press = Some(Box::new(message)); self } /// The message to emit on a right button press without capturing. #[must_use] - pub fn on_right_press_no_capture( - mut self, - message: impl Fn(Option) -> Message + 'a, - ) -> Self { + pub fn on_right_press_no_capture(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_right_press_no_capture = Some(Box::new(message)); self } /// The message to emit on a right button release. #[must_use] - pub fn on_right_release(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_right_release(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_right_release = Some(Box::new(message)); self } /// The message to emit on a middle button press. #[must_use] - pub fn on_middle_press(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_middle_press(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_middle_press = Some(Box::new(message)); self } /// The message to emit on a middle button release. #[must_use] - pub fn on_middle_release(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_middle_release(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_middle_release = Some(Box::new(message)); self } /// The message to emit on a back button press. #[must_use] - pub fn on_back_press(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_back_press(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_back_press = Some(Box::new(message)); self } /// The message to emit on a back button release. #[must_use] - pub fn on_back_release(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_back_release(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_back_release = Some(Box::new(message)); self } /// The message to emit on a forward button press. #[must_use] - pub fn on_forward_press(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_forward_press(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_forward_press = Some(Box::new(message)); self } /// The message to emit on a forward button release. #[must_use] - pub fn on_forward_release(mut self, message: impl Fn(Option) -> Message + 'a) -> Self { + pub fn on_forward_release(mut self, message: impl OnMouseButton<'a, Message>) -> Self { self.on_forward_release = Some(Box::new(message)); self } /// The message to emit on a scroll. #[must_use] - pub fn on_scroll( - mut self, - message: impl Fn(mouse::ScrollDelta, Modifiers) -> Option + 'a, - ) -> Self { + pub fn on_scroll(mut self, message: impl OnScroll<'a, Message>) -> Self { self.on_scroll = Some(Box::new(message)); self } /// The message to emit when a mouse enters the area. #[must_use] - pub fn on_enter(mut self, message: impl Fn() -> Message + 'a) -> Self { + pub fn on_enter(mut self, message: impl OnEnterExit<'a, Message>) -> Self { self.on_enter = Some(Box::new(message)); self } /// The message to emit when a mouse exits the area. #[must_use] - pub fn on_exit(mut self, message: impl Fn() -> Message + 'a) -> Self { + pub fn on_exit(mut self, message: impl OnEnterExit<'a, Message>) -> Self { self.on_exit = Some(Box::new(message)); self } @@ -199,6 +193,24 @@ impl<'a, Message> MouseArea<'a, Message> { } } +pub trait OnMouseButton<'a, Message>: Fn(Option) -> Message + 'a {} +impl<'a, Message, F> OnMouseButton<'a, Message> for F where F: Fn(Option) -> Message + 'a {} + +pub trait OnDrag<'a, Message>: Fn(Option) -> Message + 'a {} +impl<'a, Message, F> OnDrag<'a, Message> for F where F: Fn(Option) -> Message + 'a {} + +pub trait OnResize<'a, Message>: Fn(Size) -> Message + 'a {} +impl<'a, Message, F> OnResize<'a, Message> for F where F: Fn(Size) -> Message + 'a {} + +pub trait OnScroll<'a, Message>: Fn(mouse::ScrollDelta, Modifiers) -> Option + 'a {} +impl<'a, Message, F> OnScroll<'a, Message> for F where + F: Fn(mouse::ScrollDelta, Modifiers) -> Option + 'a +{ +} + +pub trait OnEnterExit<'a, Message>: Fn() -> Message + 'a {} +impl<'a, Message, F> OnEnterExit<'a, Message> for F where F: Fn() -> Message + 'a {} + /// Local state of the [`MouseArea`]. #[derive(Default)] struct State { @@ -250,7 +262,7 @@ impl State { } else { mouse::Click::new(pos, mouse::Button::Left, None) }; - self.prev_click = Some((new.clone(), now)); + self.prev_click = Some((new, now)); new } } @@ -284,7 +296,7 @@ impl<'a, Message> MouseArea<'a, Message> { } } -impl<'a, Message> Widget for MouseArea<'a, Message> +impl Widget for MouseArea<'_, Message> where Message: Clone, { @@ -659,7 +671,7 @@ fn update( if let Some(on_scroll) = widget.on_scroll.as_ref() { if let Event::Mouse(mouse::Event::WheelScrolled { delta }) = event { - if let Some(message) = on_scroll(delta.clone(), state.modifiers) { + if let Some(message) = on_scroll(*delta, state.modifiers) { shell.publish(message); return event::Status::Captured; } diff --git a/src/operation/controller.rs b/src/operation/controller.rs index 4b33b42..1154b32 100644 --- a/src/operation/controller.rs +++ b/src/operation/controller.rs @@ -22,8 +22,8 @@ pub struct Controller { inner: Arc, } -impl Controller { - pub fn new() -> Self { +impl Default for Controller { + fn default() -> Self { Self { primary: true, inner: Arc::new(ControllerInner { @@ -33,7 +33,9 @@ impl Controller { }), } } +} +impl Controller { pub fn check(&self) -> Result<(), String> { let mut state = self.inner.state.lock().unwrap(); loop { diff --git a/src/operation/mod.rs b/src/operation/mod.rs index 7bbc54c..0fe2d39 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -683,7 +683,7 @@ impl Operation { path.strip_prefix(relative_root).map_err(err_str)?.to_str() { 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 total = metadata.len(); if total >= 4 * 1024 * 1024 * 1024 { @@ -800,7 +800,7 @@ impl Operation { op_sel.selected.push(new_dir.clone()); let controller = controller.clone(); - let mime = mime_for_path(&path); + let mime = mime_for_path(path); match mime.essence_str() { "application/gzip" | "application/x-compressed-tar" => { OpReader::new(path, controller) @@ -960,7 +960,7 @@ mod tests { }; use cosmic::iced::futures::{channel::mpsc, StreamExt}; - use log::{debug, trace}; + use log::debug; use test_log::test; use tokio::sync; @@ -968,8 +968,8 @@ mod tests { use crate::{ app::{ test_utils::{ - empty_fs, filter_dirs, filter_files, read_dir_sorted, simple_fs, NAME_LEN, - NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, + empty_fs, filter_dirs, filter_files, simple_fs, NAME_LEN, NUM_DIRS, NUM_FILES, + NUM_HIDDEN, NUM_NESTED, }, DialogPage, Message, }, @@ -993,7 +993,7 @@ mod tests { paths: paths_clone, to: to_clone, } - .perform(&sync::Mutex::new(tx).into(), Controller::new()) + .perform(&sync::Mutex::new(tx).into(), Controller::default()) .await }); diff --git a/src/operation/recursive.rs b/src/operation/recursive.rs index b6f64a4..4a1a28e 100644 --- a/src/operation/recursive.rs +++ b/src/operation/recursive.rs @@ -12,12 +12,18 @@ use super::{copy_unique_path, Controller, OperationSelection, ReplaceResult}; pub struct Context { buf: Vec, controller: Controller, - on_progress: Box, - on_replace: Box ReplaceResult + 'static>, + on_progress: Box, + on_replace: Box, pub(crate) op_sel: OperationSelection, replace_result_opt: Option, } +pub trait OnProgress: Fn(&Op, &Progress) + 'static {} +impl OnProgress for F where F: Fn(&Op, &Progress) + 'static {} + +pub trait OnReplace: Fn(&Op) -> ReplaceResult + 'static {} +impl OnReplace for F where F: Fn(&Op) -> ReplaceResult + 'static {} + impl Context { pub fn new(controller: Controller) -> Self { Self { @@ -67,7 +73,7 @@ impl Context { OpKind::Symlink { target } } else { //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 { // When copying a file, from matches from_parent, and to_parent must be used @@ -130,12 +136,12 @@ impl Context { Ok(true) } - pub fn on_progress(mut self, f: F) -> Self { + pub fn on_progress(mut self, f: F) -> Self { self.on_progress = Box::new(f); self } - pub fn on_replace ReplaceResult + 'static>(mut self, f: F) -> Self { + pub fn on_replace(mut self, f: F) -> Self { self.on_replace = Box::new(f); self } @@ -153,9 +159,7 @@ impl Context { Ok(ControlFlow::Continue(op.to.clone())) } ReplaceResult::KeepBoth => match op.to.parent() { - Some(to_parent) => Ok(ControlFlow::Continue(copy_unique_path( - &op.from, &to_parent, - ))), + Some(to_parent) => Ok(ControlFlow::Continue(copy_unique_path(&op.from, to_parent))), None => Err(format!("failed to get parent of {:?}", op.to).into()), }, ReplaceResult::Skip(apply_to_all) => { @@ -216,7 +220,7 @@ impl Op { let metadata = from_file.metadata()?; // Remove `to` if overwriting and it is an existing file if self.to.is_file() { - match ctx.replace(&self)? { + match ctx.replace(self)? { ControlFlow::Continue(to) => { self.to = to; } @@ -226,7 +230,7 @@ impl Op { } } 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 let mut to_file = fs::OpenOptions::new() .create_new(true) @@ -242,14 +246,14 @@ impl Op { } to_file.write_all(&ctx.buf[..count])?; progress.current_bytes += count as u64; - (ctx.on_progress)(&self, &progress); + (ctx.on_progress)(self, &progress); } to_file.sync_all()?; } OpKind::Move => { // Remove `to` if overwriting and it is an existing file if self.to.is_file() { - match ctx.replace(&self)? { + match ctx.replace(self)? { ControlFlow::Continue(to) => { self.to = to; } @@ -289,7 +293,7 @@ impl Op { OpKind::Symlink { ref target } => { // Remove `to` if overwriting and it is an existing file if self.to.is_file() { - match ctx.replace(&self)? { + match ctx.replace(self)? { ControlFlow::Continue(to) => { self.to = to; } @@ -298,8 +302,18 @@ impl Op { } } } - //TODO: use OS-specific function - fs::soft_link(&target, &self.to)?; + #[cfg(unix)] + { + 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) diff --git a/src/tab.rs b/src/tab.rs index 459f8e9..d4fadb3 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -475,7 +475,7 @@ pub fn item_from_entry( }; let dir_size = if metadata.is_dir() { - DirSize::Calculating(Controller::new()) + DirSize::Calculating(Controller::default()) } else { DirSize::NotDirectory }; diff --git a/src/thumbnailer.rs b/src/thumbnailer.rs index ac2df57..36dbd0a 100644 --- a/src/thumbnailer.rs +++ b/src/thumbnailer.rs @@ -144,9 +144,7 @@ impl ThumbnailerCache { } pub fn get(&self, key: &Mime) -> Vec { - self.cache - .get(&key) - .map_or_else(|| Vec::new(), |x| x.clone()) + self.cache.get(key).map_or_else(Vec::new, |x| x.clone()) } }