Refactor PathResolver so it cannot fail

This commit is contained in:
Savanni D'Gerinel 2023-09-25 00:05:45 -04:00
parent 759a4b6a1a
commit f7012ee11a
1 changed files with 34 additions and 53 deletions

View File

@ -21,27 +21,34 @@ pub enum PathError {
pub struct PathResolver {
base: PathBuf,
id: FileId,
extension: String,
}
impl PathResolver {
pub fn new(base: &Path, id: FileId) -> Self {
pub fn new(base: &Path, id: FileId, extension: String) -> Self {
Self {
base: base.to_owned(),
id,
extension,
}
}
pub fn metadata_path_by_id(base: &Path, id: FileId) -> PathBuf {
let mut path = base.to_path_buf();
path.push(PathBuf::from(id.clone()));
path.set_extension("json");
path
}
pub fn id(&self) -> FileId {
self.id.clone()
}
pub fn file_path(&self) -> Result<PathBuf, ReadFileError> {
let info = FileInfo::load(self.metadata_path())?;
pub fn file_path(&self) -> PathBuf {
let mut path = self.base.clone();
path.push(PathBuf::from(self.id.clone()));
path.set_extension(info.extension);
Ok(path)
path.set_extension(self.extension.clone());
path
}
pub fn metadata_path(&self) -> PathBuf {
@ -51,13 +58,11 @@ impl PathResolver {
path
}
pub fn thumbnail_path(&self) -> Result<PathBuf, ReadFileError> {
let info = FileInfo::load(self.metadata_path())?;
pub fn thumbnail_path(&self) -> PathBuf {
let mut path = self.base.clone();
path.push(PathBuf::from(self.id.clone()));
path.set_extension(format!("tn.{}", info.extension));
Ok(path)
path.set_extension(format!("tn.{}", self.extension));
path
}
}
@ -94,6 +99,10 @@ impl TryFrom<&Path> for PathResolver {
.file_stem()
.and_then(|s| s.to_str().map(|s| FileId::from(s)))
.ok_or(PathError::InvalidPath)?,
extension: path
.extension()
.and_then(|s| s.to_str().map(|s| s.to_owned()))
.ok_or(PathError::InvalidPath)?,
})
}
}
@ -119,6 +128,7 @@ impl FileHandle {
let path = PathResolver {
base: root.clone(),
id: id.clone(),
extension: extension.clone(),
};
let file_type = mime_guess::from_ext(&extension)
@ -142,8 +152,8 @@ impl FileHandle {
}
pub fn load(id: &FileId, root: &Path) -> Result<Self, ReadFileError> {
let resolver = PathResolver::new(root, id.clone());
let info = FileInfo::load(resolver.metadata_path())?;
let info = FileInfo::load(PathResolver::metadata_path_by_id(root, id.clone()))?;
let resolver = PathResolver::new(root, id.clone(), info.extension.clone());
Ok(Self {
id: info.id.clone(),
path: resolver,
@ -152,11 +162,7 @@ impl FileHandle {
}
pub fn set_content(&mut self, content: Vec<u8>) -> Result<(), WriteFileError> {
let mut content_file = std::fs::File::create(
self.path
.file_path()
.map_err(|_| WriteFileError::NoMetadata)?,
)?;
let mut content_file = std::fs::File::create(self.path.file_path())?;
let byte_count = content_file.write(&content)?;
self.info.size = byte_count;
self.info.hash = self.hash_content(&content).as_string();
@ -170,11 +176,11 @@ impl FileHandle {
}
pub fn content(&self) -> Result<Vec<u8>, ReadFileError> {
load_content(&self.path.file_path()?)
load_content(&self.path.file_path())
}
pub fn thumbnail(&self) -> Result<Vec<u8>, ReadFileError> {
load_content(&self.path.thumbnail_path()?)
load_content(&self.path.thumbnail_path())
}
fn hash_content(&self, data: &Vec<u8>) -> HexString {
@ -182,35 +188,15 @@ impl FileHandle {
}
fn write_thumbnail(&self) -> Result<(), WriteFileError> {
let img = image::open(
&self
.path
.file_path()
.map_err(|_| WriteFileError::NoMetadata)?,
)?;
let img = image::open(&self.path.file_path())?;
let tn = img.resize(640, 640, FilterType::Nearest);
tn.save(
&self
.path
.thumbnail_path()
.map_err(|_| WriteFileError::NoMetadata)?,
)?;
tn.save(&self.path.thumbnail_path())?;
Ok(())
}
pub fn delete(self) {
match self.path.thumbnail_path() {
Ok(path) => {
let _ = std::fs::remove_file(path);
}
Err(_) => {}
};
match self.path.file_path() {
Ok(path) => {
let _ = std::fs::remove_file(path);
}
Err(_) => {}
};
let _ = std::fs::remove_file(self.path.thumbnail_path());
let _ = std::fs::remove_file(self.path.file_path());
let _ = std::fs::remove_file(self.path.metadata_path());
}
}
@ -226,7 +212,6 @@ fn load_content(path: &Path) -> Result<Vec<u8>, ReadFileError> {
mod test {
use super::*;
use crate::store::utils::DirCleanup;
use cool_asserts::assert_matches;
use std::{convert::TryFrom, path::PathBuf};
#[test]
@ -234,21 +219,17 @@ mod test {
let resolver = PathResolver::try_from("path/82420255-d3c8-4d90-a582-f94be588c70c.png")
.expect("to have a valid path");
assert_matches!(
assert_eq!(
resolver.file_path(),
Ok(path) => assert_eq!(path, PathBuf::from(
"path/82420255-d3c8-4d90-a582-f94be588c70c.png"
))
PathBuf::from("path/82420255-d3c8-4d90-a582-f94be588c70c.png")
);
assert_eq!(
resolver.metadata_path(),
PathBuf::from("path/82420255-d3c8-4d90-a582-f94be588c70c.json")
);
assert_matches!(
assert_eq!(
resolver.thumbnail_path(),
Ok(path) => assert_eq!(path, PathBuf::from(
"path/82420255-d3c8-4d90-a582-f94be588c70c.tn.png"
))
PathBuf::from("path/82420255-d3c8-4d90-a582-f94be588c70c.tn.png")
);
}