monorepo/file-service/src/store/fileinfo.rs

125 lines
3.6 KiB
Rust
Raw Normal View History

2023-09-23 19:17:49 +00:00
use super::{ReadFileError, WriteFileError};
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,
};
#[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;
#[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");
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);
}
}