vagabond/src/entry.rs

87 lines
2.4 KiB
Rust

use crate::EntryReadError;
use std::path::{Path, PathBuf};
#[derive(PartialEq)]
pub enum EntryType {
File,
Directory,
}
pub struct Entry {
pub entry_type: EntryType,
pub is_symlink: bool,
pub name: String,
pub extension: String,
pub path: PathBuf,
pub original_path: PathBuf,
}
impl Entry {
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, EntryReadError> {
let path = path.as_ref();
let metadata = path.metadata()?;
let canonical_path = std::fs::canonicalize(path)?;
let canonical_metadata = canonical_path.metadata()?;
let entry_type = if canonical_metadata.is_file() {
EntryType::File
} else if canonical_metadata.is_dir() {
EntryType::Directory
} else {
return Err(EntryReadError::NotFound);
};
let name = match path.file_name() {
Some(osstr) => osstr.to_string_lossy().to_string(),
None => unreachable!(),
};
let extension = match path.extension() {
Some(extension) => extension.to_string_lossy().into(),
None => String::default(),
};
Ok(Entry {
entry_type,
name,
extension,
path: canonical_path,
original_path: path.to_path_buf(),
is_symlink: metadata.is_symlink(),
})
}
/// Splits the filename on the last period, ignoring any period at the
/// start of the filename. If no extension is found, the extension is empty.
pub fn split_name(&self) -> (String, String) {
match self.name.rsplit_once(".") {
Some(("", _)) | None => (self.name.to_string(), String::new()),
Some((prefix, extension)) => (prefix.to_string(), extension.to_string()),
}
}
pub fn is_file(&self) -> bool {
match self.entry_type {
EntryType::File => true,
_ => false,
}
}
pub fn is_directory(&self) -> bool {
match self.entry_type {
EntryType::Directory => true,
_ => false,
}
}
pub fn read_as_bytes(&self) -> Result<Vec<u8>, EntryReadError> {
return Ok(std::fs::read(&self.path)?);
}
pub fn read_as_utf8_string(&self) -> Result<String, EntryReadError> {
return Ok(String::from_utf8_lossy(&self.read_as_bytes()?).to_string());
}
}
impl AsRef<Path> for Entry {
fn as_ref(&self) -> &Path {
&self.path
}
}