From 4afacccc8adf2df7ef4c127f961d1cc2d20e5c89 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 17 Apr 2026 13:31:55 -0600 Subject: [PATCH] Fix windows compilation issues --- src/archive.rs | 14 ++++++++++---- src/mime_icon.rs | 25 ++++++++++++++++++++++++- src/tab.rs | 35 +++++++++++++++++++---------------- src/thumbnail_cacher.rs | 5 ++++- src/trash.rs | 2 ++ 5 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/archive.rs b/src/archive.rs index 92024d8..ba11cbb 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -189,6 +189,8 @@ fn zip_extract>( if file.is_symlink() && (cfg!(unix) || cfg!(windows)) { let mut target = Vec::with_capacity(file.size() as usize); file.read_to_end(&mut target)?; + // File no longer needed, drop to allow reading target on windows + drop(file); #[cfg(unix)] { @@ -199,11 +201,15 @@ fn zip_extract>( #[cfg(windows)] { let Ok(target) = String::from_utf8(target) else { - return Err(ZipError::InvalidArchive("Invalid UTF-8 as symlink target")); + return Err(ZipError::InvalidArchive( + "Invalid UTF-8 as symlink target".into(), + )); }; - let target = target.into_boxed_str(); - let target_is_dir_from_archive = - archive.shared.files.contains_key(&target) && is_dir(&target); + let target_is_dir_from_archive = match password { + None => archive.by_name(&target), + Some(pwd) => archive.by_name_decrypt(&target, pwd.as_bytes()), + } + .map_or(false, |x| x.is_dir()); let target_path = directory.as_ref().join(OsString::from(target.to_string())); let target_is_dir = if target_is_dir_from_archive { true diff --git a/src/mime_icon.rs b/src/mime_icon.rs index 52b1a27..8d8d2e5 100644 --- a/src/mime_icon.rs +++ b/src/mime_icon.rs @@ -19,6 +19,7 @@ struct MimeIconKey { struct MimeIconCache { cache: FxHashMap>, + #[cfg(unix)] shared_mime_info: xdg_mime::SharedMimeInfo, } @@ -26,10 +27,17 @@ impl MimeIconCache { pub fn new() -> Self { Self { cache: FxHashMap::default(), + #[cfg(unix)] shared_mime_info: xdg_mime::SharedMimeInfo::new(), } } + #[cfg(not(unix))] + pub fn get(&mut self, _key: MimeIconKey) -> Option { + None + } + + #[cfg(unix)] pub fn get(&mut self, key: MimeIconKey) -> Option { self.cache .entry(key) @@ -53,6 +61,16 @@ impl MimeIconCache { static MIME_ICON_CACHE: LazyLock> = LazyLock::new(|| Mutex::new(MimeIconCache::new())); +#[cfg(not(unix))] +pub fn mime_for_path( + path: impl AsRef, + metadata_opt: Option<&fs::Metadata>, + remote: bool, +) -> Mime { + mime_guess::from_path(path).first_or_octet_stream() +} + +#[cfg(unix)] pub fn mime_for_path( path: impl AsRef, metadata_opt: Option<&fs::Metadata>, @@ -100,8 +118,13 @@ pub fn mime_icon(mime: Mime, size: u16) -> icon::Handle { } } +#[cfg(not(unix))] +pub fn parent_mime_types(_mime: &Mime) -> Option> { + None +} + +#[cfg(unix)] pub fn parent_mime_types(mime: &Mime) -> Option> { let mime_icon_cache = MIME_ICON_CACHE.lock().unwrap(); - mime_icon_cache.shared_mime_info.get_parents_aliased(mime) } diff --git a/src/tab.rs b/src/tab.rs index 82dd03d..94eacdd 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -41,6 +41,8 @@ use jiff_icu::ConvertFrom; use mime_guess::{Mime, mime}; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; +#[cfg(unix)] +use std::os::unix::fs::MetadataExt; use std::{ borrow::Cow, cell::Cell, @@ -51,7 +53,6 @@ use std::{ fs::{self, File, Metadata}, hash::Hash, io::{BufRead, BufReader}, - os::unix::fs::MetadataExt, path::{self, Path, PathBuf}, sync::{Arc, LazyLock, RwLock, atomic}, time::{Duration, Instant, SystemTime}, @@ -4339,6 +4340,7 @@ impl Tab { for item in self.items_opt().map_or(Vec::new(), |items| { items.iter().filter(|item| item.selected).collect() }) { + #[cfg(unix)] if let (Some(path), Some(mode)) = ( item.path_opt(), item.file_metadata() @@ -6356,22 +6358,23 @@ impl Tab { } else { total_size = total_size.saturating_add(metadata.len()); } - let mode = metadata.mode(); #[cfg(unix)] - user_name.insert( - uzers::get_user_by_uid(metadata.uid()) - .and_then(|user| user.name().to_str().map(ToOwned::to_owned)) - .unwrap_or_default(), - ); - mode_user.insert(get_mode_part(mode, MODE_SHIFT_USER)); - #[cfg(unix)] - group_name.insert( - uzers::get_group_by_gid(metadata.gid()) - .and_then(|group| group.name().to_str().map(ToOwned::to_owned)) - .unwrap_or_default(), - ); - mode_group.insert(get_mode_part(mode, MODE_SHIFT_GROUP)); - mode_other.insert(get_mode_part(mode, MODE_SHIFT_OTHER)); + { + let mode = metadata.mode(); + user_name.insert( + uzers::get_user_by_uid(metadata.uid()) + .and_then(|user| user.name().to_str().map(ToOwned::to_owned)) + .unwrap_or_default(), + ); + mode_user.insert(get_mode_part(mode, MODE_SHIFT_USER)); + group_name.insert( + uzers::get_group_by_gid(metadata.gid()) + .and_then(|group| group.name().to_str().map(ToOwned::to_owned)) + .unwrap_or_default(), + ); + mode_group.insert(get_mode_part(mode, MODE_SHIFT_GROUP)); + mode_other.insert(get_mode_part(mode, MODE_SHIFT_OTHER)); + } } } let mut mime_types: Vec<(String, u64)> = mime_type_counts.into_iter().collect(); diff --git a/src/thumbnail_cacher.rs b/src/thumbnail_cacher.rs index 719bfc6..e4d616e 100644 --- a/src/thumbnail_cacher.rs +++ b/src/thumbnail_cacher.rs @@ -1,11 +1,12 @@ use image::DynamicImage; use md5::{Digest, Md5}; use rustc_hash::FxHashMap; +#[cfg(unix)] +use std::os::unix::fs::PermissionsExt; use std::{ error::Error, fs::{self, File}, io::{self, BufReader, BufWriter}, - os::unix::fs::PermissionsExt, path::{Path, PathBuf}, sync::LazyLock, time::UNIX_EPOCH, @@ -93,6 +94,7 @@ impl ThumbnailCacher { } pub fn update_with_temp_file(&self, temp_file: NamedTempFile) -> Result<&Path, Box> { + #[cfg(unix)] fs::set_permissions(temp_file.path(), fs::Permissions::from_mode(0o600))?; self.update_thumbnail_text_metadata(temp_file.path())?; fs::rename(temp_file.path(), &self.thumbnail_path)?; @@ -127,6 +129,7 @@ impl ThumbnailCacher { pub fn create_fail_marker(&self) -> Result<(), Box> { if let Some(dir) = self.thumbnail_fail_marker_path.parent() { fs::create_dir_all(dir)?; + #[cfg(unix)] fs::set_permissions(dir, fs::Permissions::from_mode(0o700))?; } diff --git a/src/trash.rs b/src/trash.rs index 0262ba9..ce37c83 100644 --- a/src/trash.rs +++ b/src/trash.rs @@ -74,6 +74,8 @@ impl TrashExt for Trash { } } + // Not available on Windows only + #[cfg(not(target_os = "windows"))] fn folders() -> Result, trash::Error> { trash::os_limited::trash_folders() }