Browse Source

Miscellaneous little optimisations

- Prefer iter over into_iter where appropriate
- Cut down on cloning
Ben S 11 years ago
parent
commit
66339e7a15
6 changed files with 51 additions and 50 deletions
  1. 3 3
      Cargo.lock
  2. 2 2
      src/column.rs
  3. 1 1
      src/dir.rs
  4. 5 6
      src/exa.rs
  5. 36 34
      src/file.rs
  6. 4 4
      src/filetype.rs

+ 3 - 3
Cargo.lock

@@ -4,13 +4,13 @@ version = "0.1.0"
 dependencies = [
  "ansi_term 0.3.0 (git+https://github.com/ogham/rust-ansi-term.git)",
  "natord 1.0.0 (git+https://github.com/lifthrasiir/rust-natord.git)",
- "users 0.1.0 (git+https://github.com/ogham/rust-users)",
+ "users 0.1.0 (git+https://github.com/ogham/rust-users.git)",
 ]
 
 [[package]]
 name = "ansi_term"
 version = "0.3.0"
-source = "git+https://github.com/ogham/rust-ansi-term.git#4b9ea6cf266053e1a771e75b935b4e54c586c139"
+source = "git+https://github.com/ogham/rust-ansi-term.git#e17d8d3dc56526247f88b0f279f90dc46342db49"
 
 [[package]]
 name = "natord"
@@ -20,5 +20,5 @@ source = "git+https://github.com/lifthrasiir/rust-natord.git#83ebf6e7999fe2646bc
 [[package]]
 name = "users"
 version = "0.1.0"
-source = "git+https://github.com/ogham/rust-users#221a1463d3e25acac41615186a1c7fdcf0ad36d7"
+source = "git+https://github.com/ogham/rust-users.git#221a1463d3e25acac41615186a1c7fdcf0ad36d7"
 

+ 2 - 2
src/column.rs

@@ -49,8 +49,8 @@ impl Column {
 impl Alignment {
     pub fn pad_string(&self, string: &String, padding: uint) -> String {
         match *self {
-            Alignment::Left  => string.clone() + " ".repeat(padding).as_slice(),
-            Alignment::Right => " ".repeat(padding) + string.as_slice(),
+            Alignment::Left  => format!("{}{}", string, " ".repeat(padding).as_slice()),
+            Alignment::Right => format!("{}{}", " ".repeat(padding), string.as_slice()),
         }
     }
 }

+ 1 - 1
src/dir.rs

@@ -24,7 +24,7 @@ impl Dir {
         let mut files = vec![];
 
         for path in self.contents.iter() {
-            match File::from_path(path.clone(), Some(self)) {
+            match File::from_path(path, Some(self)) {
                 Ok(file) => files.push(file),
                 Err(e)   => println!("{}: {}", path.display(), e),
             }

+ 5 - 6
src/exa.rs

@@ -56,7 +56,7 @@ fn exa(opts: &Options) {
                 else {
                     // May as well reuse the stat result from earlier
                     // instead of just using File::from_path().
-                    files.push(File::with_stat(stat, path, None));
+                    files.push(File::with_stat(stat, &path, None));
                 }
             }
             Err(e) => println!("{}: {}", file, e),
@@ -72,7 +72,7 @@ fn exa(opts: &Options) {
         view(opts, files);
     }
 
-    for dir_name in dirs.into_iter() {
+    for dir_name in dirs.iter() {
         if first {
             first = false;
         }
@@ -155,13 +155,12 @@ fn grid_view(across: bool, console_width: uint, files: Vec<File>) {
             }
 
             let ref file = files[num];
-            let file_name = file.name.clone();
-            let styled_name = file.file_colour().paint(file_name.as_slice()).to_string();
+            let styled_name = file.file_colour().paint(file.name.as_slice()).to_string();
             if x == num_columns - 1 {
                 print!("{}", styled_name);
             }
             else {
-                print!("{}", Left.pad_string(&styled_name, max_column_length - file_name.len() + 1));
+                print!("{}", Left.pad_string(&styled_name, max_column_length - file.name.len() + 1));
             }
         }
         print!("\n");
@@ -192,7 +191,7 @@ fn details_view(options: &Options, columns: &Vec<Column>, files: Vec<File>) {
     // results are cached.
 
     let lengths: Vec<Vec<uint>> = table.iter()
-        .map(|row| row.iter().map(|col| strip_formatting(col.clone()).len()).collect())
+        .map(|row| row.iter().map(|col| strip_formatting(col.as_slice()).len()).collect())
         .collect();
 
     let column_widths: Vec<uint> = range(0, columns.len())

+ 36 - 34
src/file.rs

@@ -1,5 +1,6 @@
 use std::io::{fs, IoResult};
 use std::io;
+use std::str::CowString;
 
 use ansi_term::{ANSIString, Colour, Style};
 use ansi_term::Style::Plain;
@@ -31,27 +32,27 @@ pub struct File<'a> {
 }
 
 impl<'a> File<'a> {
-    pub fn from_path(path: Path, parent: Option<&'a Dir>) -> IoResult<File<'a>> {
+    pub fn from_path(path: &Path, parent: Option<&'a Dir>) -> IoResult<File<'a>> {
         // Use lstat here instead of file.stat(), as it doesn't follow
         // symbolic links. Otherwise, the stat() call will fail if it
         // encounters a link that's target is non-existent.
-        fs::lstat(&path).map(|stat| File::with_stat(stat, path.clone(), parent))
+        fs::lstat(path).map(|stat| File::with_stat(stat, path, parent))
     }
 
-    pub fn with_stat(stat: io::FileStat, path: Path, parent: Option<&'a Dir>) -> File<'a> {
+    pub fn with_stat(stat: io::FileStat, path: &Path, parent: Option<&'a Dir>) -> File<'a> {
         let v = path.filename().unwrap();  // fails if / or . or ..
-        let filename = String::from_utf8(v.to_vec()).unwrap_or_else(|_| panic!("Name was not valid UTF-8"));
+        let filename = String::from_utf8_lossy(v);
 
         File {
             path:  path.clone(),
             dir:   parent,
             stat:  stat,
-            name:  filename.clone(),
-            ext:   File::ext(filename.clone()),
+            name:  filename.to_string(),
+            ext:   File::ext(filename),
         }
     }
 
-    fn ext(name: String) -> Option<String> {
+    fn ext(name: CowString) -> Option<String> {
         // The extension is the series of characters after a dot at
         // the end of a filename. This deliberately also counts
         // dotfiles - the ".git" folder has the extension "git".
@@ -75,29 +76,30 @@ impl<'a> File<'a> {
     // without a .coffee.
 
     pub fn get_source_files(&self) -> Vec<Path> {
-        if self.ext.is_none() {
-            return vec![];
+        if let Some(ref ext) = self.ext {
+            let ext = ext.as_slice();
+            match ext {
+                "class" => vec![self.path.with_extension("java")],  // Java
+                "css"   => vec![self.path.with_extension("sass"),   self.path.with_extension("less")],  // SASS, Less
+                "elc"   => vec![self.path.with_extension("el")],    // Emacs Lisp
+                "hi"    => vec![self.path.with_extension("hs")],    // Haskell
+                "js"    => vec![self.path.with_extension("coffee"), self.path.with_extension("ts")],  // CoffeeScript, TypeScript
+                "o"     => vec![self.path.with_extension("c"),      self.path.with_extension("cpp")], // C, C++
+                "pyc"   => vec![self.path.with_extension("py")],    // Python
+
+                "aux" => vec![self.path.with_extension("tex")],  // TeX: auxiliary file
+                "bbl" => vec![self.path.with_extension("tex")],  // BibTeX bibliography file
+                "blg" => vec![self.path.with_extension("tex")],  // BibTeX log file
+                "lof" => vec![self.path.with_extension("tex")],  // TeX list of figures
+                "log" => vec![self.path.with_extension("tex")],  // TeX log file
+                "lot" => vec![self.path.with_extension("tex")],  // TeX list of tables
+                "toc" => vec![self.path.with_extension("tex")],  // TeX table of contents
+
+                _ => vec![],  // No source files if none of the above
+            }
         }
-
-        let ext = self.ext.clone().unwrap();
-        match ext.as_slice() {
-            "class" => vec![self.path.with_extension("java")],  // Java
-            "css"   => vec![self.path.with_extension("sass"),   self.path.with_extension("less")],  // SASS, Less
-            "elc"   => vec![self.path.with_extension("el")],    // Emacs Lisp
-            "hi"    => vec![self.path.with_extension("hs")],    // Haskell
-            "js"    => vec![self.path.with_extension("coffee"), self.path.with_extension("ts")],  // CoffeeScript, TypeScript
-            "o"     => vec![self.path.with_extension("c"),      self.path.with_extension("cpp")], // C, C++
-            "pyc"   => vec![self.path.with_extension("py")],    // Python
-
-            "aux" => vec![self.path.with_extension("tex")],  // TeX: auxiliary file
-            "bbl" => vec![self.path.with_extension("tex")],  // BibTeX bibliography file
-            "blg" => vec![self.path.with_extension("tex")],  // BibTeX log file
-            "lof" => vec![self.path.with_extension("tex")],  // TeX list of figures
-            "log" => vec![self.path.with_extension("tex")],  // TeX log file
-            "lot" => vec![self.path.with_extension("tex")],  // TeX list of tables
-            "toc" => vec![self.path.with_extension("tex")],  // TeX table of contents
-
-            _ => vec![],
+        else {
+            vec![]  // No source files if there's no extension, either!
         }
     }
 
@@ -182,7 +184,7 @@ impl<'a> File<'a> {
                         Some(dir) => dir.path.join(path),
                         None => path,
                     };
-                    format!("{} {}", displayed_name, self.target_file_name_and_arrow(target_path))
+                    format!("{} {}", displayed_name, self.target_file_name_and_arrow(&target_path))
                 }
                 Err(_) => displayed_name.to_string(),
             }
@@ -196,16 +198,16 @@ impl<'a> File<'a> {
         self.name.as_slice().width(false)
     }
 
-    fn target_file_name_and_arrow(&self, target_path: Path) -> String {
+    fn target_file_name_and_arrow(&self, target_path: &Path) -> String {
         let v = target_path.filename().unwrap();
-        let filename = String::from_utf8_lossy(v).to_string();
+        let filename = String::from_utf8_lossy(v);
 
         // Use stat instead of lstat - we *want* to follow links.
-        let link_target = fs::stat(&target_path).map(|stat| File {
+        let link_target = fs::stat(target_path).map(|stat| File {
             path:  target_path.clone(),
             dir:   self.dir,
             stat:  stat,
-            name:  filename.clone(),
+            name:  filename.to_string(),
             ext:   File::ext(filename.clone()),
         });
 

+ 4 - 4
src/filetype.rs

@@ -96,9 +96,8 @@ impl<'a> HasType for File<'a> {
         else if name.starts_with("README") || BUILD_TYPES.iter().any(|&s| s == name) {
             return Immediate;
         }
-        else if self.ext.is_some() {
-            let e = self.ext.clone().unwrap().to_ascii_lower();
-            let ext = e.as_slice();
+        else if let Some(ref e) = self.ext {
+            let ext = e.as_slice().to_ascii_lower();
             if IMAGE_TYPES.iter().any(|&s| s == ext) {
                 return Image;
             }
@@ -125,7 +124,7 @@ impl<'a> HasType for File<'a> {
             }
 
             let source_files = self.get_source_files();
-            if source_files.len() == 0 {
+            if source_files.is_empty() {
                 return Normal;
             }
             else if source_files.iter().any(|path| self.dir.map(|d| d.contains(path)).unwrap_or(false)) {
@@ -140,6 +139,7 @@ impl<'a> HasType for File<'a> {
                 }
             }
         }
+
         return Normal;  // no filetype
     }
 }