Merge branch 'fix-handling-maybe-unsupported-time-metadata' of https://github.com/ariasuni/exa into ariasuni-fix-handling-maybe-unsupported-time-metadata

# Conflicts:
#	src/fs/file.rs
#	src/options/filter.rs
#	src/options/view.rs
This commit is contained in:
Benjamin Sago 2020-01-19 16:46:51 +00:00
commit 490d9680c2
5 changed files with 19 additions and 84 deletions

View File

@ -331,10 +331,9 @@ impl<'dir> File<'dir> {
/// This files last modified timestamp. /// This files last modified timestamp.
/// If the file's time is invalid, assume it was modified today /// If the file's time is invalid, assume it was modified today
pub fn modified_time(&self) -> Duration { pub fn modified_time(&self) -> Duration {
if self.metadata.modified().unwrap() < UNIX_EPOCH { match self.metadata.modified() {
return SystemTime::now().duration_since(UNIX_EPOCH).unwrap() Ok(system_time) => system_time.duration_since(UNIX_EPOCH).unwrap(),
} else { Err(_) => Duration::new(0, 0),
return self.metadata.modified().unwrap().duration_since(UNIX_EPOCH).unwrap()
} }
} }
@ -346,20 +345,18 @@ impl<'dir> File<'dir> {
/// This files last accessed timestamp. /// This files last accessed timestamp.
/// If the file's time is invalid, assume it was accessed today /// If the file's time is invalid, assume it was accessed today
pub fn accessed_time(&self) -> Duration { pub fn accessed_time(&self) -> Duration {
if self.metadata.accessed().unwrap() < UNIX_EPOCH{ match self.metadata.accessed() {
return SystemTime::now().duration_since(UNIX_EPOCH).unwrap() Ok(system_time) => system_time.duration_since(UNIX_EPOCH).unwrap(),
} else { Err(_) => Duration::new(0, 0),
return self.metadata.accessed().unwrap().duration_since(UNIX_EPOCH).unwrap()
} }
} }
/// This files created timestamp. /// This files created timestamp.
/// If the file's time is invalid, assume it was created today /// If the file's time is invalid, assume it was created today
pub fn created_time(&self) -> Duration { pub fn created_time(&self) -> Duration {
if self.metadata.created().unwrap() < UNIX_EPOCH { match self.metadata.created() {
return SystemTime::now().duration_since(UNIX_EPOCH).unwrap() Ok(system_time) => system_time.duration_since(UNIX_EPOCH).unwrap(),
} else { Err(_) => Duration::new(0, 0),
return self.metadata.created().unwrap().duration_since(UNIX_EPOCH).unwrap()
} }
} }
@ -477,41 +474,6 @@ impl<'dir> FileTarget<'dir> {
} }
pub enum PlatformMetadata {
ModifiedTime,
ChangedTime,
AccessedTime,
CreatedTime,
}
impl PlatformMetadata {
pub fn check_supported(&self) -> Result<(), Misfire> {
use std::env::temp_dir;
let result = match self {
// Call the functions that return a Result to see if it works
PlatformMetadata::AccessedTime => metadata(temp_dir()).unwrap().accessed(),
PlatformMetadata::ModifiedTime => metadata(temp_dir()).unwrap().modified(),
PlatformMetadata::CreatedTime => metadata(temp_dir()).unwrap().created(),
// We use the Unix API so we know its not available elsewhere
PlatformMetadata::ChangedTime => {
if cfg!(target_family = "unix") {
return Ok(())
} else {
return Err(Misfire::Unsupported(
// for consistency, this error message similar to the one Rust
// use when created time is not available
"status modified time is not available on this platform currently".to_string()));
}
},
};
match result {
Ok(_) => Ok(()),
Err(err) => Err(Misfire::Unsupported(err.to_string()))
}
}
}
/// More readable aliases for the permission bits exposed by libc. /// More readable aliases for the permission bits exposed by libc.
#[allow(trivial_numeric_casts)] #[allow(trivial_numeric_casts)]
mod modes { mod modes {

View File

@ -2,7 +2,7 @@ mod dir;
pub use self::dir::{Dir, DotFilter}; pub use self::dir::{Dir, DotFilter};
mod file; mod file;
pub use self::file::{File, FileTarget, PlatformMetadata}; pub use self::file::{File, FileTarget};
pub mod feature; pub mod feature;
pub mod fields; pub mod fields;

View File

@ -1,6 +1,6 @@
//! Parsing the options for `FileFilter`. //! Parsing the options for `FileFilter`.
use crate::fs::{DotFilter, PlatformMetadata}; use crate::fs::DotFilter;
use crate::fs::filter::{FileFilter, SortField, SortCase, IgnorePatterns, GitIgnore}; use crate::fs::filter::{FileFilter, SortField, SortCase, IgnorePatterns, GitIgnore};
use crate::options::{flags, Misfire}; use crate::options::{flags, Misfire};
@ -67,23 +67,7 @@ impl SortField {
_ => return Err(Misfire::BadArgument(&flags::SORT, word.into())) _ => return Err(Misfire::BadArgument(&flags::SORT, word.into()))
}; };
match SortField::to_platform_metadata(field) { Ok(field)
Some(m) => match m.check_supported() {
Ok(_) => Ok(field),
Err(misfire) => Err(misfire),
},
None => Ok(field),
}
}
fn to_platform_metadata(field: Self) -> Option<PlatformMetadata> {
match field {
SortField::ModifiedDate => Some(PlatformMetadata::ModifiedTime),
SortField::ChangedDate => Some(PlatformMetadata::ChangedTime),
SortField::AccessedDate => Some(PlatformMetadata::AccessedTime),
SortField::CreatedDate => Some(PlatformMetadata::CreatedTime),
_ => None
}
} }
} }

View File

@ -7,7 +7,6 @@ use crate::output::grid_details::{self, RowThreshold};
use crate::output::table::{TimeTypes, Environment, SizeFormat, Columns, Options as TableOptions}; use crate::output::table::{TimeTypes, Environment, SizeFormat, Columns, Options as TableOptions};
use crate::output::time::TimeFormat; use crate::output::time::TimeFormat;
use crate::fs::PlatformMetadata;
use crate::fs::feature::xattr; use crate::fs::feature::xattr;
@ -356,17 +355,6 @@ impl TimeTypes {
TimeTypes::default() TimeTypes::default()
}; };
let mut fields = vec![];
if time_types.modified { fields.push(PlatformMetadata::ModifiedTime); }
if time_types.changed { fields.push(PlatformMetadata::ChangedTime); }
if time_types.accessed { fields.push(PlatformMetadata::AccessedTime); }
if time_types.created { fields.push(PlatformMetadata::CreatedTime); }
for field in fields {
if let Err(misfire) = field.check_supported() {
return Err(misfire);
}
}
Ok(time_types) Ok(time_types)
} }
} }
@ -554,15 +542,9 @@ mod test {
test!(time_a: TimeTypes <- ["-t", "acc"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: true, created: false })); test!(time_a: TimeTypes <- ["-t", "acc"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: true, created: false }));
// Created // Created
#[cfg(not(target_os = "linux"))]
test!(cr: TimeTypes <- ["--created"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: false, created: true })); test!(cr: TimeTypes <- ["--created"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: false, created: true }));
#[cfg(target_os = "linux")]
test!(cr: TimeTypes <- ["--created"]; Both => err Misfire::Unsupported("creation time is not available on this platform currently".to_string()));
#[cfg(not(target_os = "linux"))]
test!(c: TimeTypes <- ["-U"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: false, created: true })); test!(c: TimeTypes <- ["-U"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: false, created: true }));
#[cfg(not(target_os = "linux"))]
test!(time_cr: TimeTypes <- ["--time=created"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: false, created: true })); test!(time_cr: TimeTypes <- ["--time=created"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: false, created: true }));
#[cfg(not(target_os = "linux"))]
test!(t_cr: TimeTypes <- ["-tcr"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: false, created: true })); test!(t_cr: TimeTypes <- ["-tcr"]; Both => Ok(TimeTypes { modified: false, changed: false, accessed: false, created: true }));
// Multiples // Multiples

View File

@ -147,6 +147,9 @@ impl DefaultFormat {
#[allow(trivial_numeric_casts)] #[allow(trivial_numeric_casts)]
fn format_local(&self, time: Duration) -> String { fn format_local(&self, time: Duration) -> String {
if time.as_nanos() == 0 {
return "-".to_string();
}
let date = LocalDateTime::at(time.as_secs() as i64); let date = LocalDateTime::at(time.as_secs() as i64);
if self.is_recent(date) { if self.is_recent(date) {
@ -161,6 +164,10 @@ impl DefaultFormat {
#[allow(trivial_numeric_casts)] #[allow(trivial_numeric_casts)]
fn format_zoned(&self, time: Duration, zone: &TimeZone) -> String { fn format_zoned(&self, time: Duration, zone: &TimeZone) -> String {
if time.as_nanos() == 0 {
return "-".to_string();
}
let date = zone.to_zoned(LocalDateTime::at(time.as_secs() as i64)); let date = zone.to_zoned(LocalDateTime::at(time.as_secs() as i64));
if self.is_recent(date) { if self.is_recent(date) {