Sfoglia il codice sorgente

Add long-iso style and --time-style option

This has to do its own number formatting because *somebody* didn’t add “print the current month number” functionality to rust-datetime!
Benjamin Sago 8 anni fa
parent
commit
786e8f4d7f
5 ha cambiato i file con 54 aggiunte e 18 eliminazioni
  1. 12 11
      src/options/mod.rs
  2. 15 3
      src/options/view.rs
  3. 23 4
      src/output/time.rs
  4. 3 0
      xtests/dates_long_iso
  5. 1 0
      xtests/run.sh

+ 12 - 11
src/options/mod.rs

@@ -77,17 +77,18 @@ impl Options {
         opts.optopt ("I", "ignore-glob", "ignore files that match these glob patterns", "GLOB1|GLOB2...");
 
         // Long view options
-        opts.optflag("b", "binary",    "list file sizes with binary prefixes");
-        opts.optflag("B", "bytes",     "list file sizes in bytes, without prefixes");
-        opts.optflag("g", "group",     "list each file's group");
-        opts.optflag("h", "header",    "add a header row to each column");
-        opts.optflag("H", "links",     "list each file's number of hard links");
-        opts.optflag("i", "inode",     "list each file's inode number");
-        opts.optflag("m", "modified",  "use the modified timestamp field");
-        opts.optflag("S", "blocks",    "list each file's number of file system blocks");
-        opts.optopt ("t", "time",      "which timestamp field to show", "WORD");
-        opts.optflag("u", "accessed",  "use the accessed timestamp field");
-        opts.optflag("U", "created",   "use the created timestamp field");
+        opts.optflag("b", "binary",     "list file sizes with binary prefixes");
+        opts.optflag("B", "bytes",      "list file sizes in bytes, without prefixes");
+        opts.optflag("g", "group",      "list each file's group");
+        opts.optflag("h", "header",     "add a header row to each column");
+        opts.optflag("H", "links",      "list each file's number of hard links");
+        opts.optflag("i", "inode",      "list each file's inode number");
+        opts.optflag("m", "modified",   "use the modified timestamp field");
+        opts.optflag("S", "blocks",     "list each file's number of file system blocks");
+        opts.optopt ("t", "time",       "which timestamp field to show", "WORD");
+        opts.optflag("u", "accessed",   "use the accessed timestamp field");
+        opts.optflag("U", "created",    "use the created timestamp field");
+        opts.optopt ("",  "time-style", "how to format timestamp fields", "STYLE");
 
         if cfg!(feature="git") {
             opts.optflag("", "git", "list each file's git status");

+ 15 - 3
src/options/view.rs

@@ -6,7 +6,7 @@ use output::Colours;
 use output::{grid, details};
 use output::table::{TimeTypes, Environment, SizeFormat, Options as TableOptions};
 use output::file_name::Classify;
-use output::time::{TimeFormat, DefaultFormat};
+use output::time::TimeFormat;
 use options::Misfire;
 use fs::feature::xattr;
 
@@ -239,8 +239,20 @@ impl SizeFormat {
 impl TimeFormat {
 
     /// Determine how time should be formatted in timestamp columns.
-    fn deduce(_matches: &getopts::Matches) -> Result<TimeFormat, Misfire> {
-        Ok(TimeFormat::DefaultFormat(DefaultFormat::new()))
+    fn deduce(matches: &getopts::Matches) -> Result<TimeFormat, Misfire> {
+        pub use output::time::{DefaultFormat, LongISO};
+        const STYLES: &[&str] = &["default", "long-iso"];
+
+        if let Some(word) = matches.opt_str("time-style") {
+            match &*word {
+                "default"   => Ok(TimeFormat::DefaultFormat(DefaultFormat::new())),
+                "long-iso"  => Ok(TimeFormat::LongISO(LongISO)),
+                otherwise   => Err(Misfire::bad_argument("time-style", otherwise, STYLES))
+            }
+        }
+        else {
+            Ok(TimeFormat::DefaultFormat(DefaultFormat::new()))
+        }
     }
 }
 

+ 23 - 4
src/output/time.rs

@@ -1,4 +1,4 @@
-use datetime::{LocalDateTime, TimeZone, DatePiece};
+use datetime::{LocalDateTime, TimeZone, DatePiece, TimePiece};
 use datetime::fmt::DateFormat;
 use locale;
 
@@ -7,18 +7,21 @@ use fs::fields::Time;
 
 pub enum TimeFormat {
     DefaultFormat(DefaultFormat),
+    LongISO(LongISO),
 }
 
 impl TimeFormat {
     pub fn format_local(&self, time: Time) -> String {
         match *self {
             TimeFormat::DefaultFormat(ref fmt) => fmt.format_local(time),
+            TimeFormat::LongISO(ref iso)       => iso.format_local(time),
         }
     }
 
     pub fn format_zoned(&self, time: Time, zone: &TimeZone) -> String {
         match *self {
             TimeFormat::DefaultFormat(ref fmt) => fmt.format_zoned(time, zone),
+            TimeFormat::LongISO(ref iso)       => iso.format_zoned(time, zone),
         }
     }
 }
@@ -71,9 +74,6 @@ impl DefaultFormat {
     fn is_recent(&self, date: LocalDateTime) -> bool {
         date.year() == self.current_year
     }
-}
-
-impl DefaultFormat {
 
     #[allow(trivial_numeric_casts)]
     fn format_local(&self, time: Time) -> String {
@@ -99,3 +99,22 @@ impl DefaultFormat {
         }
     }
 }
+
+
+pub struct LongISO;
+
+impl LongISO {
+    #[allow(trivial_numeric_casts)]
+    fn format_local(&self, time: Time) -> String {
+        let date = LocalDateTime::at(time.seconds as i64);
+        format!("{:04}-{:02}-{:02} {:02}:{:02}",
+                date.year(), date.month() as usize, date.day(), date.hour(), date.minute())
+    }
+
+    #[allow(trivial_numeric_casts)]
+    fn format_zoned(&self, time: Time, zone: &TimeZone) -> String {
+        let date = zone.to_zoned(LocalDateTime::at(time.seconds as i64));
+        format!("{:04}-{:02}-{:02} {:02}:{:02}",
+                date.year(), date.month() as usize, date.day(), date.hour(), date.minute())
+    }
+}

+ 3 - 0
xtests/dates_long_iso

@@ -0,0 +1,3 @@
+.rw-rw-r-- 0 cassowary 2006-06-15 23:14 peach
+.rw-rw-r-- 0 cassowary 2003-03-03 00:00 pear
+.rw-rw-r-- 0 cassowary 2009-07-22 10:38 plum

+ 1 - 0
xtests/run.sh

@@ -110,6 +110,7 @@ $exa $testcases/file-names-exts/music.* -I "*.OGG|*.mp3" -1 2>&1 | diff -q - $re
 # Dates and times
 $exa $testcases/dates -lh --accessed --sort=accessed 2>&1 | diff -q - $results/dates_accessed  || exit 1
 $exa $testcases/dates -lh            --sort=modified 2>&1 | diff -q - $results/dates_modified  || exit 1
+$exa $testcases/dates -l       --time-style=long-iso 2>&1 | diff -q - $results/dates_long_iso  || exit 1
 
 
 # Paths and directories