chore: migrate to Rust 2024 edition

This commit is contained in:
Vukašin Vojinović 2025-09-03 23:24:38 +02:00 committed by Jeremy Soller
parent 6ed7bdb45f
commit f95869a631
16 changed files with 194 additions and 161 deletions

View file

@ -2,9 +2,9 @@
name = "cosmic-files"
version = "0.1.0"
authors = ["Jeremy Soller <jeremy@system76.com>"]
edition = "2021"
edition = "2024"
license = "GPL-3.0-only"
rust-version = "1.85.0"
rust-version = "1.85"
[build-dependencies]
vergen = { version = "8", features = ["git", "gitcl"] }
@ -88,7 +88,7 @@ optional = true
git = "https://github.com/pop-os/libcosmic.git"
default-features = false
#TODO: a11y feature crashes
features = ["autosize","multi-window", "tokio", "winit", "surface-message"]
features = ["autosize", "multi-window", "tokio", "winit", "surface-message"]
[features]
default = [

View file

@ -1,7 +1,7 @@
[package]
name = "cosmic-files-applet"
version = "0.1.0"
edition = "2021"
edition = "2024"
[dependencies]
log = "0.4"
@ -11,4 +11,3 @@ zbus = "5"
path = ".."
default-features = false
features = ["desktop", "gvfs", "wayland", "wgpu", "desktop-applet"]

View file

@ -1,5 +1,5 @@
use cosmic_files::operation::recursive::Method;
use cosmic_files::operation::{recursive::Context, Controller, ReplaceResult};
use cosmic_files::operation::{Controller, ReplaceResult, recursive::Context};
use std::{error::Error, io, path::PathBuf};
#[compio::main]

View file

@ -1,8 +1,9 @@
use cosmic::{
Application, Element,
app::{self, Core, Settings, Task},
executor,
iced::{window, Subscription},
widget, Application, Element,
iced::{Subscription, window},
widget,
};
use cosmic_files::dialog::{
Dialog, DialogChoice, DialogChoiceOption, DialogFilter, DialogFilterPattern, DialogKind,

View file

@ -3,23 +3,24 @@
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
use cosmic::iced::{
Limits,
event::wayland::{Event as WaylandEvent, OutputEvent, OverlapNotifyEvent},
platform_specific::runtime::wayland::layer_surface::{
IcedMargin, IcedOutput, SctkLayerSurfaceSettings,
},
platform_specific::shell::wayland::commands::layer_surface::{
destroy_layer_surface, get_layer_surface, Anchor, KeyboardInteractivity, Layer,
Anchor, KeyboardInteractivity, Layer, destroy_layer_surface, get_layer_surface,
},
Limits,
};
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
use cosmic::iced_winit::commands::overlap_notify::overlap_notify;
use cosmic::{
app::{self, context_drawer, Core, Task},
Application, ApplicationExt, Element,
app::{self, Core, Task, context_drawer},
cosmic_config::{self, ConfigSet},
cosmic_theme, executor,
iced::{
self,
self, Alignment, Event, Length, Point, Rectangle, Size, Subscription,
clipboard::dnd::DndAction,
core::SmolStr,
event,
@ -28,7 +29,6 @@ use cosmic::{
stream,
widget::scrollable,
window::{self, Event as WindowEvent, Id as WindowId},
Alignment, Event, Length, Point, Rectangle, Size, Subscription,
},
iced_runtime::clipboard,
style, surface, theme,
@ -40,13 +40,11 @@ use cosmic::{
segmented_button::{self, Entity},
vertical_space,
},
Application, ApplicationExt, Element,
};
use mime_guess::Mime;
use notify_debouncer_full::{
new_debouncer,
DebouncedEvent, Debouncer, FileIdMap, new_debouncer,
notify::{self, RecommendedWatcher, Watcher},
DebouncedEvent, Debouncer, FileIdMap,
};
use slotmap::Key as SlotMapKey;
use std::{
@ -65,13 +63,13 @@ use std::{
use tokio::sync::mpsc;
use trash::TrashItem;
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
use wayland_client::{protocol::wl_output::WlOutput, Proxy};
use wayland_client::{Proxy, protocol::wl_output::WlOutput};
use crate::{
clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste},
config::{
AppTheme, Config, DesktopConfig, Favorite, IconSizes, TabConfig, TimeConfig, TypeToSearch,
TIME_CONFIG_ID,
AppTheme, Config, DesktopConfig, Favorite, IconSizes, TIME_CONFIG_ID, TabConfig,
TimeConfig, TypeToSearch,
},
dialog::{Dialog, DialogKind, DialogMessage, DialogResult},
fl, home_dir,
@ -80,14 +78,14 @@ use crate::{
menu,
mime_app::{self, MimeApp, MimeAppCache},
mime_icon,
mounter::{MounterAuth, MounterItem, MounterItems, MounterKey, MounterMessage, MOUNTERS},
mounter::{MOUNTERS, MounterAuth, MounterItem, MounterItems, MounterKey, MounterMessage},
operation::{
Controller, Operation, OperationError, OperationErrorType, OperationSelection,
ReplaceResult,
},
spawn_detached::spawn_detached,
tab::{
self, HeadingOptions, ItemMetadata, Location, Tab, HOVER_DURATION, SORT_OPTION_FALLBACK,
self, HOVER_DURATION, HeadingOptions, ItemMetadata, Location, SORT_OPTION_FALLBACK, Tab,
},
};
use crate::{config::State, dialog::DialogSettings};
@ -2195,7 +2193,7 @@ impl Application for App {
for location in flags.uris {
if let Some(e) = app.nav_model.iter().find(|e| {
app.nav_model.data::<Location>(*e).is_some_and(
|l| matches!(l, Location::Network(ref uri, ..) if *uri == location.to_string()),
|l| matches!(l, Location::Network(uri, ..) if *uri == location.to_string()),
)
}) {
commands.push(cosmic::task::message(cosmic::Action::App(
@ -3194,7 +3192,11 @@ impl Application for App {
}
Err(err) => {
log::warn!("failed to reload metadata for {:?}: {}", path, err);
log::warn!(
"failed to reload metadata for {:?}: {}",
path,
err
);
}
}
//TODO item.thumbnail_opt =
@ -3283,7 +3285,7 @@ impl Application for App {
None
}
},
))
));
}
Message::OpenInNewWindow(entity_opt) => match env::current_exe() {
Ok(exe) => self
@ -3307,7 +3309,7 @@ impl Application for App {
self.open_tab(Location::Path(parent), true, Some(vec![path]))
})
},
))
));
}
Message::OpenWithBrowse => match self.dialog_pages.pop_front() {
Some((
@ -4428,14 +4430,14 @@ impl Application for App {
}
NavMenuAction::OpenInNewTab(entity) => {
match self.nav_model.data::<Location>(entity) {
Some(Location::Network(ref uri, ref display_name, path)) => {
Some(Location::Network(uri, display_name, path)) => {
return self.open_tab(
Location::Network(uri.clone(), display_name.clone(), path.clone()),
false,
None,
);
}
Some(Location::Path(ref path)) => {
Some(Location::Path(path)) => {
return self.open_tab(Location::Path(path.clone()), false, None);
}
Some(Location::Recents) => {
@ -5721,7 +5723,7 @@ impl Application for App {
.map(|x| Message::TabMessage(Some(*entity), x)),
id.clone(),
)
.into()
.into();
}
None => widget::text("Unknown tab ID").into(),
}
@ -5977,7 +5979,9 @@ impl Application for App {
if let Err(e) = futures::executor::block_on(async {
output.send(Message::RescanTrash).await
}) {
log::warn!("trash needs to be rescanned but sending message failed: {e:?}");
log::warn!(
"trash needs to be rescanned but sending message failed: {e:?}"
);
}
}
}
@ -6062,7 +6066,9 @@ impl Application for App {
if let Err(e) = futures::executor::block_on(async {
output.send(Message::RescanRecents).await
}) {
log::warn!("open recents tabs need to be updated but sending message failed: {e:?}");
log::warn!(
"open recents tabs need to be updated but sending message failed: {e:?}"
);
}
}
}
@ -6215,7 +6221,7 @@ pub(crate) mod test_utils {
};
use log::{debug, trace};
use tempfile::{tempdir, TempDir};
use tempfile::{TempDir, tempdir};
use crate::{
config::{IconSizes, TabConfig, ThumbCfg},
@ -6274,7 +6280,9 @@ pub(crate) mod test_utils {
// TempDir won't leak resources as long as the destructor runs
let root = tempdir()?;
debug!("Root temp directory: {}", root.as_ref().display());
trace!("Creating {files} files and {hidden} hidden files in {dirs} temp dirs with {nested} nested temp dirs");
trace!(
"Creating {files} files and {hidden} hidden files in {dirs} temp dirs with {nested} nested temp dirs"
);
// All paths for directories and nested directories
let paths = (0..dirs).flat_map(|_| {
@ -6349,11 +6357,7 @@ pub(crate) mod test_utils {
Ok(path.read_dir()?.filter_map(|entry| {
entry.ok().and_then(|entry| {
let path = entry.path();
if path.is_dir() {
Some(path)
} else {
None
}
if path.is_dir() { Some(path) } else { None }
})
}))
}

View file

@ -3,9 +3,10 @@
use std::{any::TypeId, num::NonZeroU16, path::PathBuf};
use cosmic::{
cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry},
Application,
cosmic_config::{self, CosmicConfigEntry, cosmic_config_derive::CosmicConfigEntry},
iced::Subscription,
theme, Application,
theme,
};
use ordermap::OrderMap;
use serde::{Deserialize, Serialize};

View file

@ -2,26 +2,25 @@
// SPDX-License-Identifier: GPL-3.0-only
use cosmic::{
app::{context_drawer, cosmic::Cosmic, Core, Task},
Application, ApplicationExt, Element,
app::{Core, Task, context_drawer, cosmic::Cosmic},
cosmic_config, cosmic_theme, executor,
iced::{
self, event,
self, Alignment, Event, Length, Size, Subscription, event,
futures::{self, SinkExt},
keyboard::{Event as KeyEvent, Key, Modifiers},
stream, window, Alignment, Event, Length, Size, Subscription,
stream, window,
},
theme,
widget::{
self,
menu::{key_bind::Modifier, Action as MenuAction, KeyBind},
menu::{Action as MenuAction, KeyBind, key_bind::Modifier},
segmented_button,
},
Application, ApplicationExt, Element,
};
use notify_debouncer_full::{
new_debouncer,
DebouncedEvent, Debouncer, FileIdMap, new_debouncer,
notify::{self, RecommendedWatcher, Watcher},
DebouncedEvent, Debouncer, FileIdMap,
};
use recently_used_xbel::update_recently_used;
use std::{
@ -36,12 +35,12 @@ use std::{
use crate::{
app::{Action, ContextPage, Message as AppMessage, PreviewItem, PreviewKind},
config::{Config, DialogConfig, Favorite, ThumbCfg, TimeConfig, TIME_CONFIG_ID},
config::{Config, DialogConfig, Favorite, TIME_CONFIG_ID, ThumbCfg, TimeConfig},
fl, home_dir,
key_bind::key_binds,
localize::LANGUAGE_SORTER,
menu,
mounter::{MounterItem, MounterItems, MounterKey, MounterMessage, MOUNTERS},
mounter::{MOUNTERS, MounterItem, MounterItems, MounterKey, MounterMessage},
tab::{self, ItemMetadata, Location, Tab},
};
@ -1452,7 +1451,11 @@ impl Application for App {
}
}
Err(err) => {
log::warn!("failed to reload metadata for {:?}: {}", path, err);
log::warn!(
"failed to reload metadata for {:?}: {}",
path,
err
);
}
}
//TODO item.thumbnail_opt =

View file

@ -3,8 +3,8 @@
use std::str::FromStr;
use i18n_embed::{
fluent::{fluent_language_loader, FluentLanguageLoader},
DefaultLocalizer, LanguageLoader, Localizer,
fluent::{FluentLanguageLoader, fluent_language_loader},
};
use icu::locid::Locale;
use icu_collator::{Collator, CollatorOptions, Numeric};

View file

@ -1,18 +1,18 @@
// SPDX-License-Identifier: GPL-3.0-only
use cosmic::{
Element,
app::Core,
iced::{
advanced::widget::text::Style as TextStyle, keyboard::Modifiers, Alignment, Background,
Border, Length,
Alignment, Background, Border, Length, advanced::widget::text::Style as TextStyle,
keyboard::Modifiers,
},
theme,
widget::{
self, button, column, container, divider, horizontal_space,
menu::{self, key_bind::KeyBind, ItemHeight, ItemWidth, MenuBar},
responsive_menu_bar, text, Row,
self, Row, button, column, container, divider, horizontal_space,
menu::{self, ItemHeight, ItemWidth, MenuBar, key_bind::KeyBind},
responsive_menu_bar, text,
},
Element,
};
use i18n_embed::LanguageLoader;
use mime_guess::Mime;

View file

@ -346,7 +346,11 @@ impl MimeAppCache {
{
apps.push(MimeApp::from(app));
} else {
log::info!("failed to add association for {:?}: application {:?} not found", mime, filename);
log::info!(
"failed to add association for {:?}: application {:?} not found",
mime,
filename
);
}
}
}
@ -385,7 +389,11 @@ impl MimeAppCache {
if found {
break;
} else {
log::debug!("failed to set default for {:?}: application {:?} not found", mime, filename);
log::debug!(
"failed to set default for {:?}: application {:?} not found",
mime,
filename
);
}
}
}
@ -625,10 +633,12 @@ mod tests {
let command = commands.first().unwrap();
assert_eq!("/usr/games/gzdoom", command.get_program().to_str().unwrap());
assert!(paths
.iter()
.zip(command.get_args())
.all(|(&expected, actual)| expected == actual.to_string_lossy()));
assert!(
paths
.iter()
.zip(command.get_args())
.all(|(&expected, actual)| expected == actual.to_string_lossy())
);
}
#[test]
@ -669,10 +679,12 @@ mod tests {
assert_eq!(paths.len(), command.get_args().count());
assert_eq!("/usr/bin/mpv", command.get_program().to_str().unwrap());
assert!(paths
.iter()
.zip(command.get_args())
.all(|(&expected, actual)| expected == actual.to_string_lossy()));
assert!(
paths
.iter()
.zip(command.get_args())
.all(|(&expected, actual)| expected == actual.to_string_lossy())
);
}
#[test]
@ -695,11 +707,12 @@ mod tests {
assert_eq!(args.len() + paths.len(), command.get_args().count());
assert_eq!("/usr/bin/flatpak", command.get_program().to_str().unwrap());
assert!(args
.iter()
.chain(paths.iter())
.zip(command.get_args())
.all(|(&expected, actual)| expected == actual.to_string_lossy()));
assert!(
args.iter()
.chain(paths.iter())
.zip(command.get_args())
.all(|(&expected, actual)| expected == actual.to_string_lossy())
);
}
#[test]
@ -719,10 +732,12 @@ mod tests {
"/usr/games/roguelike",
command.get_program().to_str().unwrap()
);
assert!(paths
.iter()
.zip(command.get_args())
.all(|(&expected, actual)| expected == actual.to_string_lossy()));
assert!(
paths
.iter()
.zip(command.get_args())
.all(|(&expected, actual)| expected == actual.to_string_lossy())
);
}
#[test]
@ -751,11 +766,13 @@ mod tests {
);
assert_eq!("/usr/bin/flatpak", command.get_program().to_str().unwrap());
assert!(args_leading
.iter()
.chain(paths.iter())
.chain(args_trailing.iter())
.zip(command.get_args())
.all(|(&expected, actual)| expected == actual.to_string_lossy()));
assert!(
args_leading
.iter()
.chain(paths.iter())
.chain(args_trailing.iter())
.zip(command.get_args())
.all(|(&expected, actual)| expected == actual.to_string_lossy())
);
}
}

View file

@ -1,10 +1,11 @@
use cosmic::{
iced::{futures::SinkExt, stream, Subscription},
widget, Task,
Task,
iced::{Subscription, futures::SinkExt, stream},
widget,
};
use gio::{glib, prelude::*};
use std::{any::TypeId, cell::Cell, future::pending, path::PathBuf, sync::Arc};
use tokio::sync::{mpsc, Mutex};
use tokio::sync::{Mutex, mpsc};
use super::{Mounter, MounterAuth, MounterItem, MounterItems, MounterMessage};
use crate::{

View file

@ -1,4 +1,4 @@
use cosmic::{iced::Subscription, widget, Task};
use cosmic::{Task, iced::Subscription, widget};
use once_cell::sync::Lazy;
use std::{collections::BTreeMap, fmt, path::PathBuf, sync::Arc};
use tokio::sync::mpsc;

View file

@ -4,7 +4,9 @@ use std::time::Instant;
use crate::tab::DOUBLE_CLICK_DURATION;
use cosmic::{
Element, Renderer, Theme,
iced_core::{
Clipboard, Color, Layout, Length, Point, Rectangle, Shell, Size, Vector, Widget,
border::Border,
event::{self, Event},
layout,
@ -12,11 +14,9 @@ use cosmic::{
overlay,
renderer::{self, Quad, Renderer as _},
touch,
widget::{tree, Operation, Tree},
Clipboard, Color, Layout, Length, Point, Rectangle, Shell, Size, Vector, Widget,
widget::{Operation, Tree, tree},
},
widget::Id,
Element, Renderer, Theme,
};
/// Emit messages on mouse events.

View file

@ -5,7 +5,7 @@ use crate::{
spawn_detached::spawn_detached,
tab,
};
use cosmic::iced::futures::{channel::mpsc::Sender, SinkExt};
use cosmic::iced::futures::{SinkExt, channel::mpsc::Sender};
use std::{
borrow::Cow,
fmt::Formatter,
@ -14,7 +14,7 @@ use std::{
path::{Path, PathBuf},
sync::Arc,
};
use tokio::sync::{mpsc, Mutex as TokioMutex};
use tokio::sync::{Mutex as TokioMutex, mpsc};
use walkdir::WalkDir;
use zip::AesMode::Aes256;
@ -140,9 +140,11 @@ async fn copy_or_move(
Ok(()) => {
log::info!("renamed {from:?} to {to:?}");
false
},
}
Err(err) => {
log::info!("failed to rename {from:?} to {to:?}, fallback to recursive move: {err}");
log::info!(
"failed to rename {from:?} to {to:?}, fallback to recursive move: {err}"
);
true
}
}
@ -1155,7 +1157,7 @@ mod tests {
path::PathBuf,
};
use cosmic::iced::futures::{channel::mpsc, StreamExt};
use cosmic::iced::futures::{StreamExt, channel::mpsc};
use log::debug;
use test_log::test;
use tokio::sync;
@ -1163,11 +1165,11 @@ mod tests {
use super::{Controller, Operation, OperationError, OperationSelection, ReplaceResult};
use crate::{
app::{
test_utils::{
empty_fs, filter_dirs, filter_files, simple_fs, NAME_LEN, NUM_DIRS, NUM_FILES,
NUM_HIDDEN, NUM_NESTED,
},
DialogPage, Message,
test_utils::{
NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, empty_fs, filter_dirs,
filter_files, simple_fs,
},
},
fl,
};
@ -1198,10 +1200,13 @@ mod tests {
match msg {
Message::DialogPush(DialogPage::Replace { tx, .. }) => {
debug!("[{id}] Replace request");
tx.send(ReplaceResult::Cancel).await.expect("Sending a response to a replace request should succeed")
tx.send(ReplaceResult::Cancel)
.await
.expect("Sending a response to a replace request should succeed")
}
_ => unreachable!("Only [ `Message::PendingProgress`, `Message::DialogPush(DialogPage::Replace)` ] are sent from operation"),
_ => unreachable!(
"Only [ `Message::PendingProgress`, `Message::DialogPush(DialogPage::Replace)` ] are sent from operation"
),
}
}
};

View file

@ -1,6 +1,6 @@
use compio::BufResult;
use compio::buf::{IntoInner, IoBuf};
use compio::io::{AsyncReadAt, AsyncWriteAt};
use compio::BufResult;
use std::future::Future;
use std::pin::Pin;
use std::time::Instant;
@ -9,7 +9,7 @@ use walkdir::WalkDir;
use crate::operation::OperationError;
use super::{copy_unique_path, Controller, OperationSelection, ReplaceResult};
use super::{Controller, OperationSelection, ReplaceResult, copy_unique_path};
pub enum Method {
Copy,

View file

@ -1,6 +1,16 @@
use cosmic::{
cosmic_theme, font,
Element, cosmic_theme, font,
iced::{
Alignment,
Border,
Color,
ContentFit,
Length,
Point,
Rectangle,
Size,
Subscription,
Vector,
advanced::{
graphics,
text::{self, Paragraph},
@ -17,36 +27,24 @@ use cosmic::{
scrollable::{self, AbsoluteOffset, Viewport},
},
window,
Alignment,
Border,
Color,
ContentFit,
Length,
Point,
Rectangle,
Size,
Subscription,
Vector,
},
iced_core::{mouse::ScrollDelta, widget::tree},
theme,
widget::{
self,
self, DndDestination, DndSource, Id, Space, Widget,
menu::{action::MenuAction, key_bind::KeyBind},
DndDestination, DndSource, Id, Space, Widget,
},
Element,
};
use chrono::{DateTime, Datelike, Timelike, Utc};
use i18n_embed::LanguageLoader;
use icu::datetime::{
options::{components, preferences},
DateTimeFormatter, DateTimeFormatterOptions,
options::{components, preferences},
};
use image::ImageDecoder;
use jxl_oxide::integration::JxlDecoder;
use mime_guess::{mime, Mime};
use mime_guess::{Mime, mime};
use once_cell::sync::Lazy;
use ordermap::OrderMap;
use serde::{Deserialize, Serialize};
@ -62,7 +60,7 @@ use std::{
io::{BufRead, BufReader},
os::unix::fs::MetadataExt,
path::{Path, PathBuf},
sync::{atomic, Arc, LazyLock, Mutex, RwLock},
sync::{Arc, LazyLock, Mutex, RwLock, atomic},
time::{Duration, Instant, SystemTime},
};
use tempfile::NamedTempFile;
@ -73,7 +71,7 @@ use walkdir::WalkDir;
use crate::{
app::{Action, PreviewItem, PreviewKind},
clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste},
config::{DesktopConfig, IconSizes, TabConfig, ThumbCfg, ICON_SCALE_MAX, ICON_SIZE_GRID},
config::{DesktopConfig, ICON_SCALE_MAX, ICON_SIZE_GRID, IconSizes, TabConfig, ThumbCfg},
dialog::DialogKind,
fl,
localize::{LANGUAGE_SORTER, LOCALE},
@ -4020,11 +4018,7 @@ impl Tab {
fn column_sort(&self) -> Option<Vec<(usize, &Item)>> {
let check_reverse = |ord: Ordering, sort: bool| {
if sort {
ord
} else {
ord.reverse()
}
if sort { ord } else { ord.reverse() }
};
let mut items: Vec<_> = self.items_opt.as_ref()?.iter().enumerate().collect();
let (sort_name, sort_direction, folders_first) = self.sort_options();
@ -4658,29 +4652,31 @@ impl Tab {
pub fn empty_view(&self, has_hidden: bool) -> Element<Message> {
let cosmic_theme::Spacing { space_xxs, .. } = theme::active().cosmic().spacing;
mouse_area::MouseArea::new(widget::column::with_children(vec![widget::container(
widget::column::with_children(match self.mode {
Mode::App | Mode::Dialog(_) => vec![
widget::icon::from_name("folder-symbolic")
.size(64)
.icon()
mouse_area::MouseArea::new(widget::column::with_children(vec![
widget::container(
widget::column::with_children(match self.mode {
Mode::App | Mode::Dialog(_) => vec![
widget::icon::from_name("folder-symbolic")
.size(64)
.icon()
.into(),
widget::text::body(if has_hidden {
fl!("empty-folder-hidden")
} else if matches!(self.location, Location::Search(..)) {
fl!("no-results")
} else {
fl!("empty-folder")
})
.into(),
widget::text::body(if has_hidden {
fl!("empty-folder-hidden")
} else if matches!(self.location, Location::Search(..)) {
fl!("no-results")
} else {
fl!("empty-folder")
})
.into(),
],
Mode::Desktop => Vec::new(),
})
.align_x(Alignment::Center)
.spacing(space_xxs),
)
.center(Length::Fill)
.into()]))
],
Mode::Desktop => Vec::new(),
})
.align_x(Alignment::Center)
.spacing(space_xxs),
)
.center(Length::Fill)
.into(),
]))
.on_press(|_| Message::Click(None))
.into()
}
@ -6109,11 +6105,11 @@ mod tests {
use tempfile::TempDir;
use test_log::test;
use super::{respond_to_scroll_direction, scan_path, Location, Message, Tab};
use super::{Location, Message, Tab, respond_to_scroll_direction, scan_path};
use crate::{
app::test_utils::{
assert_eq_tab_path, empty_fs, eq_path_item, filter_dirs, read_dir_sorted, simple_fs,
tab_click_new, NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED,
NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, assert_eq_tab_path, empty_fs,
eq_path_item, filter_dirs, read_dir_sorted, simple_fs, tab_click_new,
},
config::{IconSizes, TabConfig, ThumbCfg},
};
@ -6166,12 +6162,16 @@ mod tests {
);
// All directories (simple_fs only produces one nested layer)
let dirs: Vec<PathBuf> = filter_dirs(path)?
.flat_map(|dir| {
filter_dirs(&dir).map(|nested_dirs| std::iter::once(dir).chain(nested_dirs))
})
.flatten()
.collect();
let dirs: Vec<PathBuf> = {
let top_level = filter_dirs(path)?;
let mut result = Vec::new();
for dir in top_level {
let nested_dirs: Vec<PathBuf> = filter_dirs(&dir)?.collect();
result.push(dir);
result.extend(nested_dirs);
}
result
};
assert!(
dirs.len() == NUM_DIRS + NUM_DIRS * NUM_NESTED,
"Sanity check: Have {} dirs instead of {}",
@ -6210,10 +6210,12 @@ mod tests {
assert_eq!(entries.len(), actual.len());
// Correct files should be scanned
assert!(entries
.into_iter()
.zip(actual.into_iter())
.all(|(path, item)| eq_path_item(&path, &item)));
assert!(
entries
.into_iter()
.zip(actual.into_iter())
.all(|(path, item)| eq_path_item(&path, &item))
);
Ok(())
}
@ -6483,7 +6485,7 @@ mod tests {
#[test]
fn mode_calculations() {
use super::{
get_mode_part, set_mode_part, MODE_SHIFT_GROUP, MODE_SHIFT_OTHER, MODE_SHIFT_USER,
MODE_SHIFT_GROUP, MODE_SHIFT_OTHER, MODE_SHIFT_USER, get_mode_part, set_mode_part,
};
for user in 0..=7 {
for group in 0..=7 {