From aeb4a679e824158754157275f91634b927c60149 Mon Sep 17 00:00:00 2001 From: Chester Liu Date: Fri, 26 Mar 2021 17:47:18 +0800 Subject: [PATCH] It actually works --- src/fs/file.rs | 11 ++++++++-- src/options/parser.rs | 47 +++++++++++++++++++++++++++++++------------ src/output/table.rs | 13 ++++++++---- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/fs/file.rs b/src/fs/file.rs index 9882d05..0e94340 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -76,7 +76,7 @@ impl<'dir> File<'dir> { let ext = File::ext(&path); debug!("Statting file {:?}", &path); - let metadata = std::fs::symlink_metadata(&path)?; + let metadata = std::fs::symlink_metadata(&path)?; let is_all_all = false; Ok(File { path, parent_dir, metadata, ext, name, is_all_all }) @@ -98,7 +98,7 @@ impl<'dir> File<'dir> { let ext = File::ext(&path); debug!("Statting file {:?}", &path); - let metadata = std::fs::symlink_metadata(&path)?; + let metadata = std::fs::symlink_metadata(&path)?; let is_all_all = true; let parent_dir = Some(parent_dir); @@ -326,10 +326,17 @@ impl<'dir> File<'dir> { /// Block and character devices return their device IDs, because they /// usually just have a file size of zero. pub fn size(&self) -> f::Size { + #[cfg(windows)] if self.is_directory() { f::Size::None } + else { + f::Size::Some(self.metadata.len()) + } #[cfg(unix)] + if self.is_directory() { + f::Size::None + } else if self.is_char_device() || self.is_block_device() { let dev = self.metadata.rdev(); f::Size::DeviceIDs(f::DeviceIDs { diff --git a/src/options/parser.rs b/src/options/parser.rs index f43d44e..1a765b6 100644 --- a/src/options/parser.rs +++ b/src/options/parser.rs @@ -146,8 +146,6 @@ impl Args { pub fn parse<'args, I>(&self, inputs: I, strictness: Strictness) -> Result, ParseError> where I: IntoIterator { - use std::os::unix::ffi::OsStrExt; - let mut parsing = true; // The results that get built up. @@ -159,7 +157,7 @@ impl Args { // doesn’t have one in its string so it needs the next one. let mut inputs = inputs.into_iter(); while let Some(arg) = inputs.next() { - let bytes = arg.as_bytes(); + let bytes = os_str_to_bytes(arg); // Stop parsing if one of the arguments is the literal string “--”. // This allows a file named “--arg” to be specified by passing in @@ -174,7 +172,7 @@ impl Args { // If the string starts with *two* dashes then it’s a long argument. else if bytes.starts_with(b"--") { - let long_arg_name = OsStr::from_bytes(&bytes[2..]); + let long_arg_name = bytes_to_os_str(&bytes[2..]); // If there’s an equals in it, then the string before the // equals will be the flag’s name, and the string after it @@ -221,7 +219,7 @@ impl Args { // If the string starts with *one* dash then it’s one or more // short arguments. else if bytes.starts_with(b"-") && arg != "-" { - let short_arg = OsStr::from_bytes(&bytes[1..]); + let short_arg = bytes_to_os_str(&bytes[1..]); // If there’s an equals in it, then the argument immediately // before the equals was the one that has the value, with the @@ -236,7 +234,7 @@ impl Args { // it’s an error if any of the first set of arguments actually // takes a value. if let Some((before, after)) = split_on_equals(short_arg) { - let (arg_with_value, other_args) = before.as_bytes().split_last().unwrap(); + let (arg_with_value, other_args) = os_str_to_bytes(before).split_last().unwrap(); // Process the characters immediately following the dash... for byte in other_args { @@ -291,7 +289,7 @@ impl Args { TakesValue::Optional(values) => { if index < bytes.len() - 1 { let remnants = &bytes[index+1 ..]; - result_flags.push((flag, Some(OsStr::from_bytes(remnants)))); + result_flags.push((flag, Some(bytes_to_os_str(remnants)))); break; } else if let Some(next_arg) = inputs.next() { @@ -495,19 +493,42 @@ impl fmt::Display for ParseError { } } +#[cfg(unix)] +fn os_str_to_bytes<'b>(s: &'b OsStr) -> &'b [u8]{ + use std::os::unix::ffi::OsStrExt; + + return s.as_bytes() +} + +#[cfg(unix)] +fn bytes_to_os_str<'b>(b: &'b [u8]) -> &'b OsStr{ + use std::os::unix::ffi::OsStrExt; + + return OsStr::from_bytes(b); +} + +#[cfg(windows)] +fn os_str_to_bytes<'b>(s: &'b OsStr) -> &'b [u8]{ + return s.to_str().unwrap().as_bytes() +} + +#[cfg(windows)] +fn bytes_to_os_str<'b>(b: &'b [u8]) -> &'b OsStr{ + use std::str; + + return OsStr::new(str::from_utf8(b).unwrap()); +} /// Splits a string on its `=` character, returning the two substrings on /// either side. Returns `None` if there’s no equals or a string is missing. fn split_on_equals(input: &OsStr) -> Option<(&OsStr, &OsStr)> { - use std::os::unix::ffi::OsStrExt; - - if let Some(index) = input.as_bytes().iter().position(|elem| *elem == b'=') { - let (before, after) = input.as_bytes().split_at(index); + if let Some(index) = os_str_to_bytes(input).iter().position(|elem| *elem == b'=') { + let (before, after) = os_str_to_bytes(input).split_at(index); // The after string contains the = that we need to remove. if ! before.is_empty() && after.len() >= 2 { - return Some((OsStr::from_bytes(before), - OsStr::from_bytes(&after[1..]))) + return Some((bytes_to_os_str(before), + bytes_to_os_str(&after[1..]))) } } diff --git a/src/output/table.rs b/src/output/table.rs index d990273..5398c3e 100644 --- a/src/output/table.rs +++ b/src/output/table.rs @@ -59,11 +59,11 @@ impl Columns { } if self.octal { + #[cfg(unix)] columns.push(Column::Octal); } if self.permissions { - #[cfg(unix)] columns.push(Column::Permissions); } @@ -123,7 +123,6 @@ impl Columns { /// A table contains these. #[derive(Debug, Copy, Clone)] pub enum Column { - #[cfg(unix)] Permissions, FileSize, #[cfg(unix)] @@ -139,6 +138,7 @@ pub enum Column { #[cfg(unix)] Inode, GitStatus, + #[cfg(unix)] Octal, } @@ -177,7 +177,6 @@ impl Column { /// to have a header row printed. pub fn header(self) -> &'static str { match self { - #[cfg(unix)] Self::Permissions => "Permissions", Self::FileSize => "Size", #[cfg(unix)] @@ -193,6 +192,7 @@ impl Column { #[cfg(unix)] Self::Inode => "inode", Self::GitStatus => "Git", + #[cfg(unix)] Self::Octal => "Octal", } } @@ -407,6 +407,7 @@ impl<'a, 'f> Table<'a> { } } + #[cfg(unix)] fn octal_permissions(&self, file: &File<'_>) -> f::OctalPermissions { f::OctalPermissions { permissions: file.permissions(), @@ -415,7 +416,6 @@ impl<'a, 'f> Table<'a> { fn display(&self, file: &File<'_>, column: Column, xattrs: bool) -> TextCell { match column { - #[cfg(unix)] Column::Permissions => { self.permissions_plus(file, xattrs).render(self.theme) } @@ -445,19 +445,24 @@ impl<'a, 'f> Table<'a> { Column::GitStatus => { self.git_status(file).render(self.theme) } + #[cfg(unix)] Column::Octal => { self.octal_permissions(file).render(self.theme.ui.octal) } + #[cfg(unix)] Column::Timestamp(TimeType::Modified) => { file.modified_time().render(self.theme.ui.date, &self.env.tz, self.time_format) } + #[cfg(unix)] Column::Timestamp(TimeType::Changed) => { file.changed_time().render(self.theme.ui.date, &self.env.tz, self.time_format) } + #[cfg(unix)] Column::Timestamp(TimeType::Created) => { file.created_time().render(self.theme.ui.date, &self.env.tz, self.time_format) } + #[cfg(unix)] Column::Timestamp(TimeType::Accessed) => { file.accessed_time().render(self.theme.ui.date, &self.env.tz, self.time_format) }