Просмотр исходного кода

Improve handling of unavailable timestamps.

Previously if a timestamp was unavailable, it defaulted to the epoch.
Prior to this it defaulted to a zero duration.

Switch to an Option<SystemTime> and move the handling of unavailable
timestamps to rendering.
Thomas Hurst 5 лет назад
Родитель
Сommit
acb7c49abf
3 измененных файлов с 34 добавлено и 39 удалено
  1. 22 23
      src/fs/file.rs
  2. 12 9
      src/output/render/times.rs
  3. 0 7
      src/output/time.rs

+ 22 - 23
src/fs/file.rs

@@ -325,37 +325,36 @@ impl<'dir> File<'dir> {
         }
     }
 
-    /// This file’s last modified timestamp.
-    /// If the file's time is invalid, assume it was modified at the epoch
-    pub fn modified_time(&self) -> SystemTime {
-        self.metadata.modified().unwrap_or(UNIX_EPOCH)
+    /// This file’s last modified timestamp, if available on this platform.
+    pub fn modified_time(&self) -> Option<SystemTime> {
+        self.metadata.modified().ok()
     }
 
-    /// This file’s last changed timestamp.
-    pub fn changed_time(&self) -> SystemTime {
+    /// This file’s last changed timestamp, if available on this platform.
+    pub fn changed_time(&self) -> Option<SystemTime> {
         let (mut sec, mut nsec) = (self.metadata.ctime(), self.metadata.ctime_nsec());
 
-        if sec < 0 { // yeah right
-            if nsec > 0 {
-                sec += 1;
-                nsec = nsec - 1_000_000_000;
-            }
-            UNIX_EPOCH - Duration::new(sec.abs() as u64, nsec.abs() as u32)
-        } else {
-            UNIX_EPOCH + Duration::new(sec as u64, nsec as u32)
-        }
+        Some(
+           if sec < 0 {
+               if nsec > 0 {
+                   sec += 1;
+                   nsec = nsec - 1_000_000_000;
+               }
+               UNIX_EPOCH - Duration::new(sec.abs() as u64, nsec.abs() as u32)
+           } else {
+               UNIX_EPOCH + Duration::new(sec as u64, nsec as u32)
+           }
+        )
     }
 
-    /// This file’s last accessed timestamp.
-    /// If the file's time is invalid, assume it was accessed at the epoch
-    pub fn accessed_time(&self) -> SystemTime {
-        self.metadata.accessed().unwrap_or(UNIX_EPOCH)
+    /// This file’s last accessed timestamp, if available on this platform.
+    pub fn accessed_time(&self) -> Option<SystemTime> {
+        self.metadata.accessed().ok()
     }
 
-    /// This file’s created timestamp.
-    /// If the file's time is invalid, assume it was created at the epoch
-    pub fn created_time(&self) -> SystemTime {
-        self.metadata.created().unwrap_or(UNIX_EPOCH)
+    /// This file’s created timestamp, if available on this platform.
+    pub fn created_time(&self) -> Option<SystemTime> {
+        self.metadata.created().ok()
     }
 
     /// This file’s ‘type’.

+ 12 - 9
src/output/render/times.rs

@@ -11,18 +11,21 @@ pub trait Render {
                         format: &TimeFormat) -> TextCell;
 }
 
-impl Render for std::time::SystemTime {
+impl Render for Option<std::time::SystemTime> {
     fn render(self, style: Style,
                         tz: &Option<TimeZone>,
                         format: &TimeFormat) -> TextCell {
 
-        if let Some(ref tz) = *tz {
-            let datestamp = format.format_zoned(self, tz);
-            TextCell::paint(style, datestamp)
-        }
-        else {
-            let datestamp = format.format_local(self);
-            TextCell::paint(style, datestamp)
-        }
+        let datestamp = if let Some(time) = self {
+            if let Some(ref tz) = tz {
+                format.format_zoned(time, tz)
+            } else {
+                format.format_local(time)
+            }
+        } else {
+            String::from("-")
+        };
+
+        TextCell::paint(style, datestamp)
     }
 }

+ 0 - 7
src/output/time.rs

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