use super::Engine; use crate::{FileDescriptor, decrypt_deflate, encrypt_compress, salt}; use pathbufd::PathBufD; use std::{ collections::HashMap, fs::{read_to_string, remove_file, write}, io::Result, }; pub struct FsEngine; impl Engine for FsEngine { const CHUNK_SIZE: usize = 200_000; async fn auth(&mut self) -> Result<()> { unreachable!("Not needed"); } async fn process(&self, name: String, data: Vec) -> Result { let (seed, key, data) = encrypt_compress(data); let mut descriptor = FileDescriptor { name, key, seed, engine_data: HashMap::new(), chunks: Vec::new(), }; for chunk in data.as_bytes().chunks(Self::CHUNK_SIZE) { let id = salt(); self.create_chunk(&id, String::from_utf8(chunk.to_vec()).unwrap()) .await?; descriptor.chunks.push(id); } descriptor.write(PathBufD::current().join(format!("{}.toml", descriptor.name)))?; Ok(descriptor) } async fn reconstruct(&self, descriptor: FileDescriptor) -> Result<()> { let mut encoded_string: String = String::new(); for chunk in descriptor.chunks { encoded_string += &self.get_chunk(&chunk).await?; } let decoded = decrypt_deflate(descriptor.seed, descriptor.key, encoded_string); write(PathBufD::current().join(descriptor.name), decoded)?; Ok(()) } async fn delete(&mut self, descriptor: FileDescriptor) -> Result<()> { for chunk in descriptor.chunks { self.delete_chunk(&chunk).await?; } Ok(()) } async fn get_chunk(&self, id: &str) -> Result { read_to_string(PathBufD::new().join(id)) } async fn create_chunk(&self, id: &str, data: String) -> Result { write(PathBufD::new().join(id), data)?; Ok(String::new()) } async fn delete_chunk(&self, id: &str) -> Result<()> { remove_file(PathBufD::new().join(id)) } }