Kaynağa Gözat

Keep files and their stat results together

Thanks to #rust for helping me diagnose lifetime problems!
Ben S 11 yıl önce
ebeveyn
işleme
af7689eb0b
1 değiştirilmiş dosya ile 27 ekleme ve 10 silme
  1. 27 10
      exa.rs

+ 27 - 10
exa.rs

@@ -79,31 +79,48 @@ fn formatBytes(mut amount: u64, kilo: u64, prefixes: ~[&str]) -> ~str {
     return format!("{:4}{}", amount, prefixes[prefix]);
 }
 
-fn list(path: Path) {
-    let mut files = match fs::readdir(&path) {
-        Ok(files) => files,
-        Err(e) => fail!("readdir: {}", e),
-    };
-    files.sort_by(|a, b| a.filename_str().cmp(&b.filename_str()));
-    for file in files.iter() {
-        let filename: &str = file.filename_str().unwrap();
+// Each file is definitely going to get `stat`ted at least once, if
+// only to determine what kind of file it is, so carry the `stat`
+// result around with the file for safe keeping.
+struct File<'a> {
+    name: &'a str,
+    path: &'a Path,
+    stat: io::FileStat,
+}
+
+impl<'a> File<'a> {
+    fn from_path(path: &'a Path) -> File<'a> {
+        let filename: &str = path.filename_str().unwrap();
 
         // We have to use lstat here instad 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.
-        let stat: io::FileStat = match fs::lstat(file) {
+        let stat: io::FileStat = match fs::lstat(path) {
             Ok(stat) => stat,
             Err(e) => fail!("Couldn't stat {}: {}", filename, e),
         };
 
+        return File { path: path, stat: stat, name: filename };
+    }
+}
+
+fn list(path: Path) {
+    let mut files = match fs::readdir(&path) {
+        Ok(files) => files,
+        Err(e) => fail!("readdir: {}", e),
+    };
+    files.sort_by(|a, b| a.filename_str().cmp(&b.filename_str()));
+    for subpath in files.iter() {
+        let file = File::from_path(subpath);
+
         let columns = ~[
             ~Permissions as ~Column,
             ~FileSize { useSIPrefixes: false } as ~Column,
             ~FileName as ~Column
         ];
 
-        let mut cells = columns.iter().map(|c| c.display(&stat, filename));
+        let mut cells = columns.iter().map(|c| c.display(&file.stat, file.name));
 
         let mut first = true;
         for cell in cells {