refactor symlink check into FileType

This commit is contained in:
Jay 2020-06-17 14:30:34 +01:00 committed by Abin Simon
parent 0f8b558493
commit 2b384ed1df
3 changed files with 15 additions and 17 deletions

View file

@ -17,7 +17,11 @@ pub enum FileType {
impl FileType { impl FileType {
#[cfg(unix)] #[cfg(unix)]
pub fn new(meta: &Metadata, symlink_is_dir: Option<bool>, permissions: &Permissions) -> Self { pub fn new(
meta: &Metadata,
symlink_meta: Option<&Metadata>,
permissions: &Permissions,
) -> Self {
use std::os::unix::fs::FileTypeExt; use std::os::unix::fs::FileTypeExt;
let file_type = meta.file_type(); let file_type = meta.file_type();
@ -35,7 +39,8 @@ impl FileType {
FileType::Pipe FileType::Pipe
} else if file_type.is_symlink() { } else if file_type.is_symlink() {
FileType::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() { } else if file_type.is_char_device() {
FileType::CharDevice FileType::CharDevice
@ -154,7 +159,7 @@ mod test {
.expect("failed to get metas"); .expect("failed to get metas");
let colors = Colors::new(Theme::NoLscolors); 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)); assert_eq!(Colour::Fixed(44).paint("l"), file_type.render(&colors));
} }

View file

@ -186,17 +186,10 @@ impl Meta {
} }
} }
pub fn from_path(path: &PathBuf) -> Result<Self, std::io::Error> { pub fn from_path(path: &Path) -> Result<Self, std::io::Error> {
let (metadata, symlink_is_dir) = if read_link(path).is_ok() { let (metadata, symlink_meta) = if read_link(path).is_ok() {
// If the file is a link, retrieve the metadata without following // If the file is a link, retrieve the metadata without following the link
// the link, but provides whether followed link is_dir. Broken links are files. (path.symlink_metadata()?, path.metadata().ok())
(
path.symlink_metadata()?,
Some(match path.metadata() {
Ok(m) => m.is_dir(),
Err(_) => false, // broken link
}),
)
} else { } else {
(path.metadata()?, None) (path.metadata()?, None)
}; };
@ -209,14 +202,14 @@ impl Meta {
#[cfg(windows)] #[cfg(windows)]
let (owner, permissions) = windows_utils::get_file_data(&path)?; 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 name = Name::new(&path, file_type);
let inode = INode::from(&metadata); let inode = INode::from(&metadata);
Ok(Self { Ok(Self {
inode, inode,
path: path.to_path_buf(), path: path.to_path_buf(),
symlink: SymLink::from(path.as_path()), symlink: SymLink::from(path),
size: Size::from(&metadata), size: Size::from(&metadata),
date: Date::from(&metadata), date: Date::from(&metadata),
indicator: Indicator::from(file_type), indicator: Indicator::from(file_type),

View file

@ -216,7 +216,7 @@ mod test {
.expect("failed to get metas"); .expect("failed to get metas");
let colors = Colors::new(color::Theme::NoLscolors); 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); let name = Name::new(&symlink_path, file_type);
assert_eq!( assert_eq!(