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 {
#[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;
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));
}

View file

@ -186,17 +186,10 @@ impl Meta {
}
}
pub fn from_path(path: &PathBuf) -> Result<Self, std::io::Error> {
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<Self, std::io::Error> {
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),

View file

@ -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!(