diff --git a/src/app.rs b/src/app.rs index d958b28..0bb6925 100644 --- a/src/app.rs +++ b/src/app.rs @@ -69,7 +69,7 @@ pub struct Cli { pub directory_only: bool, /// How to display permissions [default: rwx] - #[arg(long, value_name = "MODE", value_parser = ["rwx", "octal"])] + #[arg(long, value_name = "MODE", value_parser = ["rwx", "octal", "disable"])] pub permission: Option, /// How to display size [default: default] diff --git a/src/core.rs b/src/core.rs index 1a7f459..dada4c5 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,7 +1,7 @@ use crate::color::Colors; use crate::display; use crate::flags::{ - ColorOption, Display, Flags, HyperlinkOption, Layout, Literal, SortOrder, ThemeOption, + ColorOption, Display, Flags, HyperlinkOption, Layout, Literal, SortOrder, PermissionFlag, ThemeOption, }; use crate::git::GitCache; use crate::icon::Icons; @@ -105,14 +105,17 @@ impl Core { }; for path in paths { - let mut meta = match Meta::from_path(&path, self.flags.dereference.0) { - Ok(meta) => meta, - Err(err) => { - print_error!("{}: {}.", path.display(), err); - exit_code.set_if_greater(ExitCode::MajorIssue); - continue; - } - }; + let mut meta = + match Meta::from_path(&path, + self.flags.dereference.0, + self.flags.permission == PermissionFlag::Disable) { + Ok(meta) => meta, + Err(err) => { + print_error!("{}: {}.", path.display(), err); + exit_code.set_if_greater(ExitCode::MajorIssue); + continue; + } + }; let cache = if self.flags.blocks.0.contains(&Block::GitStatus) { Some(GitCache::new(&path)) diff --git a/src/flags/permission.rs b/src/flags/permission.rs index fb32fcf..eb4470f 100644 --- a/src/flags/permission.rs +++ b/src/flags/permission.rs @@ -17,6 +17,8 @@ pub enum PermissionFlag { Rwx, /// The variant to show file permissions in octal format Octal, + /// Disable the display of owner and permissions, may be used to speed up in Windows + Disable, } impl PermissionFlag { @@ -24,6 +26,7 @@ impl PermissionFlag { match value { "rwx" => Self::Rwx, "octal" => Self::Octal, + "disable" => Self::Disable, // Invalid value should be handled by `clap` when building an `Cli` other => unreachable!("Invalid value '{other}' for 'permission'"), } diff --git a/src/meta/mod.rs b/src/meta/mod.rs index 3d1e2f4..ccc7765 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -29,7 +29,7 @@ pub use self::size::Size; pub use self::symlink::SymLink; pub use crate::icon::Icons; -use crate::flags::{Display, Flags, Layout}; +use crate::flags::{Display, Flags, Layout, PermissionFlag}; use crate::{print_error, ExitCode}; use crate::git::GitCache; @@ -95,8 +95,11 @@ impl Meta { let mut current_meta = self.clone(); current_meta.name.name = ".".to_owned(); - let mut parent_meta = - Self::from_path(&self.path.join(Component::ParentDir), flags.dereference.0)?; + let mut parent_meta = Self::from_path( + &self.path.join(Component::ParentDir), + flags.dereference.0, + flags.permission == PermissionFlag::Disable, + )?; parent_meta.name.name = "..".to_owned(); current_meta.git_status = cache.and_then(|cache| cache.get(¤t_meta.path, true)); @@ -139,7 +142,11 @@ impl Meta { _ => {} } - let mut entry_meta = match Self::from_path(&path, flags.dereference.0) { + let mut entry_meta = match Self::from_path( + &path, + flags.dereference.0, + flags.permission == PermissionFlag::Disable, + ) { Ok(res) => res, Err(err) => { print_error!("{}: {}.", path.display(), err); @@ -244,7 +251,7 @@ impl Meta { } } - pub fn from_path(path: &Path, dereference: bool) -> io::Result { + pub fn from_path(path: &Path, dereference: bool, disable_permission: bool) -> io::Result { let mut metadata = path.symlink_metadata()?; let mut symlink_meta = None; let mut broken_link = false; @@ -269,15 +276,34 @@ impl Meta { } #[cfg(unix)] - let owner = Owner::from(&metadata); - #[cfg(unix)] - let permissions = Permissions::from(&metadata); + let (owner, permissions) = if disable_permission { + (None, None) + } else { + ( + Some(Owner::from(&metadata)), + Some(Permissions::from(&metadata)), + ) + }; #[cfg(windows)] - let (owner, permissions) = windows_utils::get_file_data(path)?; + let (owner, permissions) = if disable_permission { + (None, None) + } else { + match windows_utils::get_file_data(path) { + Ok((owner, permissions)) => (Some(owner), Some(permissions)), + Err(e) => { + eprintln!("lsd: {}: {}\n", path.to_str().unwrap_or(""), e); + (None, None) + } + } + }; #[cfg(not(windows))] - let file_type = FileType::new(&metadata, symlink_meta.as_ref(), &permissions); + let file_type = FileType::new( + &metadata, + symlink_meta.as_ref(), + &permissions.unwrap_or_default(), + ); #[cfg(windows)] let file_type = FileType::new(&metadata, symlink_meta.as_ref(), path); @@ -305,8 +331,8 @@ impl Meta { size, date, indicator: Indicator::from(file_type), - owner, - permissions, + owner: owner.unwrap_or_default(), + permissions: permissions.unwrap_or_default(), name, file_type, content: None, diff --git a/src/meta/owner.rs b/src/meta/owner.rs index 4c54df3..247a8c9 100644 --- a/src/meta/owner.rs +++ b/src/meta/owner.rs @@ -16,6 +16,15 @@ impl Owner { } } +impl Default for Owner { + fn default() -> Owner { + Owner { + user: String::from("-"), + group: String::from("-"), + } + } +} + #[cfg(unix)] impl From<&Metadata> for Owner { fn from(meta: &Metadata) -> Self { diff --git a/src/meta/permissions.rs b/src/meta/permissions.rs index 7b09252..ba60886 100644 --- a/src/meta/permissions.rs +++ b/src/meta/permissions.rs @@ -54,6 +54,25 @@ impl From<&Metadata> for Permissions { } } +impl Default for Permissions { + fn default() -> Permissions { + Permissions { + user_read: false, + user_write: false, + user_execute: false, + group_read: false, + group_write: false, + group_execute: false, + other_read: false, + other_write: false, + other_execute: false, + sticky: false, + setgid: false, + setuid: false, + } + } +} + impl Permissions { fn bits_to_octal(r: bool, w: bool, x: bool) -> u8 { (r as u8) * 4 + (w as u8) * 2 + (x as u8) @@ -122,6 +141,7 @@ impl Permissions { colors.colorize(octals, &Elem::Octal).to_string() } + PermissionFlag::Disable => colors.colorize('-', &Elem::NoAccess).to_string(), }; ColoredString::new(Colors::default_style(), res)