Переглянути джерело

Structify file_name -> FileName

This turns `file` into `self.file` and `colours` into `self.colours`, but it means we don’t need to pass arguments everywhere, which will be more of a problem the more functions there are.

Most of the code has just been indented.
Benjamin Sago 8 роки тому
батько
коміт
05a0a5e199
4 змінених файлів з 136 додано та 124 видалено
  1. 3 3
      src/output/details.rs
  2. 128 116
      src/output/file_name.rs
  3. 3 3
      src/output/grid.rs
  4. 2 2
      src/output/lines.rs

+ 3 - 3
src/output/details.rs

@@ -101,7 +101,7 @@ use output::colours::Colours;
 use output::column::{Alignment, Column, Columns, SizeFormat};
 use output::cell::{TextCell, DisplayWidth};
 use output::tree::TreeTrunk;
-use output::file_name::filename;
+use output::file_name::FileName;
 
 
 /// With the **Details** view, the output gets formatted into columns, with
@@ -307,7 +307,7 @@ impl Details {
             let mut files = Vec::new();
             let mut errors = egg.errors;
 
-            let filename = filename(&egg.file, &self.colours, true, self.classify);
+            let filename = FileName::new(&egg.file, &self.colours).file_name(true, self.classify);
             let mut width = filename.width();
 
             if egg.file.dir.is_none() {
@@ -458,7 +458,7 @@ impl<'a, U: Users+Groups+'a> Table<'a, U> {
     }
 
     pub fn filename_cell(&self, file: File, links: bool) -> TextCell {
-        let filename = filename(&file, &self.opts.colours, links, self.opts.classify);
+        let filename = FileName::new(&file, &self.opts.colours).file_name(links, self.opts.classify);
         let mut width = filename.width();
 
         if file.dir.is_none() {

+ 128 - 116
src/output/file_name.rs

@@ -5,141 +5,153 @@ use output::Colours;
 use output::cell::TextCellContents;
 
 
-pub fn filename(file: &File, colours: &Colours, links: bool, classify: bool) -> TextCellContents {
-    let mut bits = Vec::new();
+pub struct FileName<'a, 'dir: 'a> {
+    file:    &'a File<'dir>,
+    colours: &'a Colours,
+}
 
-    // TODO: This long function could do with some splitting up.
+impl<'a, 'dir> FileName<'a, 'dir> {
+    pub fn new(file: &'a File<'dir>, colours: &'a Colours) -> FileName<'a, 'dir> {
+        FileName {
+            file: file,
+            colours: colours,
+        }
+    }
 
-    if file.dir.is_none() {
-        if let Some(parent) = file.path.parent() {
-            let coconut = parent.components().count();
+    pub fn file_name(&self, links: bool, classify: bool) -> TextCellContents {
+        let mut bits = Vec::new();
 
-            if coconut == 1 && parent.has_root() {
-                bits.push(colours.symlink_path.paint("/"));
-            }
-            else if coconut >= 1 {
-                bits.push(colours.symlink_path.paint(parent.to_string_lossy().to_string()));
-                bits.push(colours.symlink_path.paint("/"));
+        if self.file.dir.is_none() {
+            if let Some(parent) = self.file.path.parent() {
+                let coconut = parent.components().count();
+
+                if coconut == 1 && parent.has_root() {
+                    bits.push(self.colours.symlink_path.paint("/"));
+                }
+                else if coconut >= 1 {
+                    bits.push(self.colours.symlink_path.paint(parent.to_string_lossy().to_string()));
+                    bits.push(self.colours.symlink_path.paint("/"));
+                }
             }
         }
-    }
 
-    if !file.name.is_empty() {
-        for bit in coloured_file_name(file, colours) {
-            bits.push(bit);
+        if !self.file.name.is_empty() {
+            for bit in self.coloured_file_name() {
+                bits.push(bit);
+            }
         }
-    }
-
-    if links && file.is_link() {
-        match file.link_target() {
-            FileTarget::Ok(target) => {
-                bits.push(Style::default().paint(" "));
-                bits.push(colours.punctuation.paint("->"));
-                bits.push(Style::default().paint(" "));
-
-                if let Some(parent) = target.path.parent() {
-                    let coconut = parent.components().count();
 
-                    if coconut == 1 && parent.has_root() {
-                        bits.push(colours.symlink_path.paint("/"));
+        if links && self.file.is_link() {
+            match self.file.link_target() {
+                FileTarget::Ok(target) => {
+                    bits.push(Style::default().paint(" "));
+                    bits.push(self.colours.punctuation.paint("->"));
+                    bits.push(Style::default().paint(" "));
+
+                    if let Some(parent) = target.path.parent() {
+                        let coconut = parent.components().count();
+
+                        if coconut == 1 && parent.has_root() {
+                            bits.push(self.colours.symlink_path.paint("/"));
+                        }
+                        else if coconut >= 1 {
+                            bits.push(self.colours.symlink_path.paint(parent.to_string_lossy().to_string()));
+                            bits.push(self.colours.symlink_path.paint("/"));
+                        }
                     }
-                    else if coconut >= 1 {
-                        bits.push(colours.symlink_path.paint(parent.to_string_lossy().to_string()));
-                        bits.push(colours.symlink_path.paint("/"));
-                    }
-                }
 
-                if !target.name.is_empty() {
-                    bits.push(file_colour(colours, &target).paint(target.name));
-                }
-            },
+                    if !target.name.is_empty() {
+                        bits.push(FileName::new(&target, self.colours).file_colour().paint(target.name));
+                    }
+                },
 
-            FileTarget::Broken(broken_path) => {
-                bits.push(Style::default().paint(" "));
-                bits.push(colours.broken_arrow.paint("->"));
-                bits.push(Style::default().paint(" "));
-                bits.push(colours.broken_filename.paint(broken_path.display().to_string()));
-            },
+                FileTarget::Broken(broken_path) => {
+                    bits.push(Style::default().paint(" "));
+                    bits.push(self.colours.broken_arrow.paint("->"));
+                    bits.push(Style::default().paint(" "));
+                    bits.push(self.colours.broken_filename.paint(broken_path.display().to_string()));
+                },
 
-            FileTarget::Err(_) => {
-                // Do nothing -- the error gets displayed on the next line
+                FileTarget::Err(_) => {
+                    // Do nothing -- the error gets displayed on the next line
+                }
+            }
+        } else if classify {
+            if self.file.is_executable_file() {
+                bits.push(Style::default().paint("*"));
+            } else if self.file.is_directory() {
+                bits.push(Style::default().paint("/"));
+            } else if self.file.is_pipe() {
+                bits.push(Style::default().paint("|"));
+            } else if self.file.is_link() {
+                bits.push(Style::default().paint("@"));
+            } else if self.file.is_socket() {
+                bits.push(Style::default().paint("="));
             }
         }
-    } else if classify {
-        if file.is_executable_file() {
-            bits.push(Style::default().paint("*"));
-        } else if file.is_directory() {
-            bits.push(Style::default().paint("/"));
-        } else if file.is_pipe() {
-            bits.push(Style::default().paint("|"));
-        } else if file.is_link() {
-            bits.push(Style::default().paint("@"));
-        } else if file.is_socket() {
-            bits.push(Style::default().paint("="));
-        }
-    }
-
-    bits.into()
-}
 
-/// Returns at least one ANSI-highlighted string representing this file’s
-/// name using the given set of colours.
-///
-/// Ordinarily, this will be just one string: the file’s complete name,
-/// coloured according to its file type. If the name contains control
-/// characters such as newlines or escapes, though, we can’t just print them
-/// to the screen directly, because then there’ll be newlines in weird places.
-///
-/// So in that situation, those characters will be escaped and highlighted in
-/// a different colour.
-fn coloured_file_name<'a>(file: &File, colours: &Colours) -> Vec<ANSIString<'a>> {
-    let colour = file_colour(colours, file);
-    let mut bits = Vec::new();
-
-    if file.name.chars().all(|c| c >= 0x20 as char) {
-        bits.push(colour.paint(file.name.clone()));
+        bits.into()
     }
-    else {
-        for c in file.name.chars() {
-            // The `escape_default` method on `char` is *almost* what we want here, but
-            // it still escapes non-ASCII UTF-8 characters, which are still printable.
-
-            if c >= 0x20 as char {
-                // TODO: This allocates way too much,
-                // hence the `all` check above.
-                let mut s = String::new();
-                s.push(c);
-                bits.push(colour.paint(s));
-            } else {
-                let s = c.escape_default().collect::<String>();
-                bits.push(colours.control_char.paint(s));
+
+    /// Returns at least one ANSI-highlighted string representing this file’s
+    /// name using the given set of colours.
+    ///
+    /// Ordinarily, this will be just one string: the file’s complete name,
+    /// coloured according to its file type. If the name contains control
+    /// characters such as newlines or escapes, though, we can’t just print them
+    /// to the screen directly, because then there’ll be newlines in weird places.
+    ///
+    /// So in that situation, those characters will be escaped and highlighted in
+    /// a different colour.
+    fn coloured_file_name<'unused>(&self) -> Vec<ANSIString<'unused>> {
+        let colour = self.file_colour();
+        let mut bits = Vec::new();
+
+        if self.file.name.chars().all(|c| c >= 0x20 as char) {
+            bits.push(colour.paint(self.file.name.clone()));
+        }
+        else {
+            for c in self.file.name.chars() {
+                // The `escape_default` method on `char` is *almost* what we want here, but
+                // it still escapes non-ASCII UTF-8 characters, which are still printable.
+
+                if c >= 0x20 as char {
+                    // TODO: This allocates way too much,
+                    // hence the `all` check above.
+                    let mut s = String::new();
+                    s.push(c);
+                    bits.push(colour.paint(s));
+                } else {
+                    let s = c.escape_default().collect::<String>();
+                    bits.push(self.colours.control_char.paint(s));
+                }
             }
         }
-    }
 
-    bits
-}
+        bits
+    }
 
-pub fn file_colour(colours: &Colours, file: &File) -> Style {
-    match file {
-        f if f.is_directory()        => colours.filetypes.directory,
-        f if f.is_executable_file()  => colours.filetypes.executable,
-        f if f.is_link()             => colours.filetypes.symlink,
-        f if f.is_pipe()             => colours.filetypes.pipe,
-        f if f.is_char_device()
-           | f.is_block_device()     => colours.filetypes.device,
-        f if f.is_socket()           => colours.filetypes.socket,
-        f if !f.is_file()            => colours.filetypes.special,
-        f if f.is_immediate()        => colours.filetypes.immediate,
-        f if f.is_image()            => colours.filetypes.image,
-        f if f.is_video()            => colours.filetypes.video,
-        f if f.is_music()            => colours.filetypes.music,
-        f if f.is_lossless()         => colours.filetypes.lossless,
-        f if f.is_crypto()           => colours.filetypes.crypto,
-        f if f.is_document()         => colours.filetypes.document,
-        f if f.is_compressed()       => colours.filetypes.compressed,
-        f if f.is_temp()             => colours.filetypes.temp,
-        f if f.is_compiled()         => colours.filetypes.compiled,
-        _                            => colours.filetypes.normal,
+    pub fn file_colour(&self) -> Style {
+        match self.file {
+            f if f.is_directory()        => self.colours.filetypes.directory,
+            f if f.is_executable_file()  => self.colours.filetypes.executable,
+            f if f.is_link()             => self.colours.filetypes.symlink,
+            f if f.is_pipe()             => self.colours.filetypes.pipe,
+            f if f.is_char_device()
+               | f.is_block_device()     => self.colours.filetypes.device,
+            f if f.is_socket()           => self.colours.filetypes.socket,
+            f if !f.is_file()            => self.colours.filetypes.special,
+            f if f.is_immediate()        => self.colours.filetypes.immediate,
+            f if f.is_image()            => self.colours.filetypes.image,
+            f if f.is_video()            => self.colours.filetypes.video,
+            f if f.is_music()            => self.colours.filetypes.music,
+            f if f.is_lossless()         => self.colours.filetypes.lossless,
+            f if f.is_crypto()           => self.colours.filetypes.crypto,
+            f if f.is_document()         => self.colours.filetypes.document,
+            f if f.is_compressed()       => self.colours.filetypes.compressed,
+            f if f.is_temp()             => self.colours.filetypes.temp,
+            f if f.is_compiled()         => self.colours.filetypes.compiled,
+            _                            => self.colours.filetypes.normal,
+        }
     }
 }

+ 3 - 3
src/output/grid.rs

@@ -5,7 +5,7 @@ use term_grid as grid;
 use fs::File;
 use output::DisplayWidth;
 use output::colours::Colours;
-use output::file_name::filename;
+use output::file_name::FileName;
 
 
 #[derive(PartialEq, Debug, Copy, Clone)]
@@ -29,7 +29,7 @@ impl Grid {
         grid.reserve(files.len());
 
         for file in files.iter() {
-            let filename = filename(file, &self.colours, false, self.classify);
+            let filename = FileName::new(file, &self.colours).file_name(false, self.classify);
 
             let mut width = filename.width();
             if file.dir.is_none() {
@@ -50,7 +50,7 @@ impl Grid {
         else {
             // File names too long for a grid - drop down to just listing them!
             for file in files.iter() {
-                writeln!(w, "{}", filename(file, &self.colours, false, self.classify).strings())?;
+                writeln!(w, "{}", FileName::new(file, &self.colours).file_name(false, self.classify).strings())?;
             }
             Ok(())
         }

+ 2 - 2
src/output/lines.rs

@@ -4,7 +4,7 @@ use ansi_term::ANSIStrings;
 
 use fs::File;
 
-use output::file_name::filename;
+use output::file_name::FileName;
 use super::colours::Colours;
 
 
@@ -18,7 +18,7 @@ pub struct Lines {
 impl Lines {
     pub fn view<W: Write>(&self, files: Vec<File>, w: &mut W) -> IOResult<()> {
         for file in files {
-            writeln!(w, "{}", ANSIStrings(&filename(&file, &self.colours, true, self.classify)))?;
+            writeln!(w, "{}", ANSIStrings(&FileName::new(&file, &self.colours).file_name(true, self.classify)))?;
         }
         Ok(())
     }