ableos_userland/libraries/trash_manifest/src/lib.rs

77 lines
2.5 KiB
Rust
Raw Normal View History

2022-12-03 12:15:03 -06:00
use std::fs::File;
use std::io::{Read, Seek, Write};
use std::path::PathBuf;
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct TrashFile {
pub name: String,
pub origin: PathBuf,
}
pub struct Manifest {
files: Vec<TrashFile>,
manifest: File,
}
impl Manifest {
/// Creates a new Manifest from a .manifest.ron file.
/// Expects File to be read and write.
pub fn new(mut manifest: File) -> Result<Self, TrashManifestError> {
let mut contents = String::new();
manifest.read_to_string(&mut contents)?;
manifest.rewind()?;
if contents.len() < 2 {
contents = "[]".to_string();
}
let files: Vec<TrashFile> = ron::from_str(&contents)?;
Ok(Self { files, manifest })
}
/// Get a certain file from the manifest by it's name.
pub fn get(&self, name: String) -> Option<TrashFile> {
self.files
.iter()
.find(|file| file.name == *name)
.map(|file| file.clone())
}
/// Get a clone of the underlying Vec of TrashFile.
pub fn get_all(&self) -> Vec<TrashFile> {
self.files.clone()
}
/// Remove a file from the manifest by it's name.
/// Consumes self and returns self back in a result to prevent inconsistencies
/// between self and the actual manifest file in case of Err.
pub fn remove(mut self, name: String) -> Result<Self, TrashManifestError> {
self.files.retain(|file| file.name != name);
let contents = ron::to_string(&self.files)?;
self.manifest.set_len(0)?;
self.manifest.rewind()?;
write!(&mut self.manifest, "{}", contents)?;
Ok(self)
}
/// Add a file to the manifest by it's name and path to origin.
/// Consumes self and returns self back in a result to prevent inconsistencies
/// between self and the actual manifest file in case of Err.
pub fn add(mut self, name: String, origin: PathBuf) -> Result<Self, TrashManifestError> {
self.files.push(TrashFile { name, origin });
dbg!(&self.files);
let contents = ron::to_string(&self.files)?;
self.manifest.set_len(0)?;
self.manifest.rewind()?;
write!(&mut self.manifest, "{}", contents)?;
Ok(self)
}
}
#[derive(thiserror::Error, Debug)]
pub enum TrashManifestError {
#[error("Could not read manifest file")]
IoError(#[from] std::io::Error),
#[error("Could not serialize or deserialize manifest file")]
SerializationError(#[from] ron::Error),
}