2023-09-23 19:17:49 +00:00
|
|
|
use super::{ReadFileError, WriteFileError};
|
2023-09-23 03:43:45 +00:00
|
|
|
use chrono::prelude::*;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use serde_json;
|
2023-09-23 19:17:49 +00:00
|
|
|
use std::{
|
|
|
|
io::{Read, Write},
|
|
|
|
path::PathBuf,
|
|
|
|
};
|
2023-09-23 03:43:45 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
|
|
pub struct FileInfo {
|
|
|
|
pub size: usize,
|
|
|
|
pub created: DateTime<Utc>,
|
|
|
|
pub file_type: String,
|
|
|
|
pub hash: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FileInfo {
|
|
|
|
pub fn load(path: PathBuf) -> Result<Self, ReadFileError> {
|
|
|
|
let mut content: Vec<u8> = Vec::new();
|
|
|
|
let mut file = std::fs::File::open(path)?;
|
|
|
|
file.read_to_end(&mut content)?;
|
|
|
|
let js = serde_json::from_slice(&content)?;
|
|
|
|
|
|
|
|
Ok(js)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn save(&self, path: PathBuf) -> Result<(), WriteFileError> {
|
|
|
|
let ser = serde_json::to_string(self).unwrap();
|
|
|
|
let mut file = std::fs::File::create(path)?;
|
|
|
|
file.write(ser.as_bytes())?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
pub fn from_path(path: &Path) -> Result<FileInfo, ReadFileError> {
|
|
|
|
match (path.is_file(), path.is_dir()) {
|
|
|
|
(false, false) => Err(ReadFileError::FileNotFound),
|
|
|
|
(false, true) => Err(ReadFileError::NotAFile),
|
|
|
|
(true, _) => Ok(()),
|
|
|
|
}?;
|
|
|
|
|
|
|
|
let metadata = path.metadata().map_err(ReadFileError::IOError)?;
|
|
|
|
let id = path
|
|
|
|
.file_name()
|
|
|
|
.map(|s| String::from(s.to_string_lossy()))
|
|
|
|
.ok_or(ReadFileError::NotAFile)?;
|
|
|
|
let created = metadata
|
|
|
|
.created()
|
|
|
|
.map(|m| DateTime::from(m))
|
|
|
|
.map_err(|err| ReadFileError::IOError(err))?;
|
|
|
|
let file_type = String::from(
|
|
|
|
mime_guess::from_path(path)
|
|
|
|
.first_or_octet_stream()
|
|
|
|
.essence_str(),
|
|
|
|
);
|
|
|
|
let hash = FileInfo::hash_file(path)?;
|
|
|
|
Ok(FileInfo {
|
|
|
|
id,
|
|
|
|
size: metadata.len(),
|
|
|
|
created,
|
|
|
|
file_type,
|
|
|
|
hash: hash.as_string(),
|
|
|
|
root: PathBuf::from(path.parent().unwrap()),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
fn hash_file(path: &Path) -> Result<HexString, ReadFileError> {
|
|
|
|
let mut buf = Vec::new();
|
|
|
|
let mut file = std::fs::File::open(path).map_err(ReadFileError::from)?;
|
|
|
|
|
|
|
|
file.read_to_end(&mut buf).map_err(ReadFileError::from)?;
|
|
|
|
let mut vec = Vec::new();
|
|
|
|
vec.extend_from_slice(Sha256::digest(&buf).as_slice());
|
|
|
|
Ok(HexString::from_bytes(&vec))
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
fn metadata_path(id: &str, root: &Path) -> PathBuf {
|
|
|
|
let mut path = PathBuf::from(root);
|
|
|
|
path.push(".metadata");
|
|
|
|
path.push(id.clone());
|
|
|
|
append_extension(&path, "json")
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn delete(&self) -> Result<(), FileError> {
|
|
|
|
let path = FileInfo::metadata_path(&self.id, &self.root);
|
|
|
|
remove_file(path).map_err(FileError::from)
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use super::*;
|
2023-09-23 19:17:49 +00:00
|
|
|
use crate::store::{utils::FileCleanup, PathResolver};
|
|
|
|
use std::convert::TryFrom;
|
2023-09-23 03:43:45 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn it_saves_and_loads_metadata() {
|
2023-09-23 19:17:49 +00:00
|
|
|
let resolver = PathResolver::try_from("fixtures/1617654d-a588-4714-b4fa-e00ed0a8a607.png")
|
|
|
|
.expect("a valid path");
|
2023-09-23 03:43:45 +00:00
|
|
|
let _cleanup = FileCleanup(resolver.metadata_path());
|
|
|
|
|
|
|
|
let created = Utc::now();
|
|
|
|
|
|
|
|
let info = FileInfo {
|
|
|
|
size: 23777,
|
|
|
|
created,
|
|
|
|
file_type: "image/png".to_owned(),
|
|
|
|
hash: "abcdefg".to_owned(),
|
|
|
|
};
|
|
|
|
info.save(resolver.metadata_path()).unwrap();
|
|
|
|
|
|
|
|
let info_ = FileInfo::load(resolver.metadata_path()).unwrap();
|
|
|
|
assert_eq!(info_.size, 23777);
|
|
|
|
assert_eq!(info_.created, info.created);
|
|
|
|
assert_eq!(info_.file_type, "image/png");
|
|
|
|
assert_eq!(info_.hash, info.hash);
|
|
|
|
}
|
|
|
|
}
|