87 lines
2.4 KiB
Rust
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
|
|
}
|
|
}
|