diff --git a/src/meta/filetype.rs b/src/meta/filetype.rs index b5276e8..016b05c 100644 --- a/src/meta/filetype.rs +++ b/src/meta/filetype.rs @@ -17,7 +17,11 @@ pub enum FileType { impl FileType { #[cfg(unix)] - pub fn new(meta: &Metadata, symlink_is_dir: Option, permissions: &Permissions) -> Self { + pub fn new( + meta: &Metadata, + symlink_meta: Option<&Metadata>, + permissions: &Permissions, + ) -> Self { use std::os::unix::fs::FileTypeExt; let file_type = meta.file_type(); @@ -35,7 +39,8 @@ impl FileType { FileType::Pipe } else if file_type.is_symlink() { FileType::SymLink { - is_dir: symlink_is_dir.expect("symlink must provide is_dir"), + // if broken, defaults to false + is_dir: symlink_meta.map(|m| m.is_dir()).unwrap_or_default(), } } else if file_type.is_char_device() { FileType::CharDevice @@ -154,7 +159,7 @@ mod test { .expect("failed to get metas"); let colors = Colors::new(Theme::NoLscolors); - let file_type = FileType::new(&meta, Some(false), &Permissions::from(&meta)); + let file_type = FileType::new(&meta, Some(&meta), &Permissions::from(&meta)); assert_eq!(Colour::Fixed(44).paint("l"), file_type.render(&colors)); } diff --git a/src/meta/mod.rs b/src/meta/mod.rs index 5aacd85..216b86a 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -186,17 +186,10 @@ impl Meta { } } - pub fn from_path(path: &PathBuf) -> Result { - let (metadata, symlink_is_dir) = if read_link(path).is_ok() { - // If the file is a link, retrieve the metadata without following - // the link, but provides whether followed link is_dir. Broken links are files. - ( - path.symlink_metadata()?, - Some(match path.metadata() { - Ok(m) => m.is_dir(), - Err(_) => false, // broken link - }), - ) + pub fn from_path(path: &Path) -> Result { + let (metadata, symlink_meta) = if read_link(path).is_ok() { + // If the file is a link, retrieve the metadata without following the link + (path.symlink_metadata()?, path.metadata().ok()) } else { (path.metadata()?, None) }; @@ -209,14 +202,14 @@ impl Meta { #[cfg(windows)] let (owner, permissions) = windows_utils::get_file_data(&path)?; - let file_type = FileType::new(&metadata, symlink_is_dir, &permissions); + let file_type = FileType::new(&metadata, symlink_meta.as_ref(), &permissions); let name = Name::new(&path, file_type); let inode = INode::from(&metadata); Ok(Self { inode, path: path.to_path_buf(), - symlink: SymLink::from(path.as_path()), + symlink: SymLink::from(path), size: Size::from(&metadata), date: Date::from(&metadata), indicator: Indicator::from(file_type), diff --git a/src/meta/name.rs b/src/meta/name.rs index 69a48da..f0adba8 100644 --- a/src/meta/name.rs +++ b/src/meta/name.rs @@ -216,7 +216,7 @@ mod test { .expect("failed to get metas"); let colors = Colors::new(color::Theme::NoLscolors); - let file_type = FileType::new(&meta, Some(false), &Permissions::from(&meta)); + let file_type = FileType::new(&meta, Some(&meta), &Permissions::from(&meta)); let name = Name::new(&symlink_path, file_type); assert_eq!(