From c9eb30f4e70a34a999a3dba7ef2050196d9c8ace Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Mon, 29 May 2023 01:18:36 -0400 Subject: [PATCH] Implemented more trait functions for Filesystem --- src/mailstore/filesystem.rs | 60 ++++++++++++++++++++++++++++++++----- src/mailstore/mod.rs | 41 +++++++++++++++++++------ 2 files changed, 84 insertions(+), 17 deletions(-) diff --git a/src/mailstore/filesystem.rs b/src/mailstore/filesystem.rs index 0212383..d582804 100644 --- a/src/mailstore/filesystem.rs +++ b/src/mailstore/filesystem.rs @@ -1,11 +1,20 @@ use super::*; -use std::{fs::{self, File}, io::{self, Write}, os::unix::fs::DirBuilderExt, path::PathBuf}; +use std::{ + fs::{self, File}, + io::{self, Write}, + os::unix::fs::DirBuilderExt, + path::PathBuf, + process::id, +}; pub trait MultiDomain: MailStore { type Error; fn domains(&self) -> Result, ::Error>; fn add_domain(&mut self, domain: &str) -> Result<(), ::Error>; - fn remove_domain(&mut self, domain: &str) -> Result<(), ::Error>; + fn remove_domain( + &mut self, + domain: &str, + ) -> Result<(), ::Error>; } #[derive(Clone, Debug)] @@ -73,7 +82,12 @@ impl MailStore for Filesystem { }) } - fn add_message(&mut self, user: &str, folder: &str, message: Message) -> Result<(), Self::Error> { + fn add_message( + &mut self, + user: &str, + folder: &str, + message: Message, + ) -> Result<(), Self::Error> { let Some((user, host)) = user.rsplit_once('@') else { return Err(io::Error::new(io::ErrorKind::Other, "Invalid username")); }; @@ -86,15 +100,45 @@ impl MailStore for Filesystem { write!(fd, "{message}") } - fn delete_message(&mut self, user: &str, folder: &str, key: &str) -> Result<(), Self::Error> { - todo!() + fn delete_message(&mut self, user: &str, folder: &str, id: &str) -> Result<(), Self::Error> { + let Some((user, host)) = user.rsplit_once('@') else { + return Err(io::Error::new(io::ErrorKind::Other, "Invalid username")); + }; + let mut path = self.path.clone(); + path.push(host); + path.push(user); + path.push(folder); + path.push(id); + if path.exists() { + fs::remove_file(&path)?; + } + Ok(()) } - fn move_message(&mut self, user: &str, title: &str, folder: &str) { - todo!() + fn move_message( + &mut self, + user: &str, + id: &str, + folder1: &str, + folder2: &str, + ) -> Result<(), io::Error> { + let Some((user, host)) = user.rsplit_once('@') else { + return Err(io::Error::new(io::ErrorKind::Other, "Invalid username")); + }; + let mut infile = self.path.clone(); + infile.push(host); + infile.push(user); + let mut outfile = infile.clone(); + infile.push(folder1); + infile.push(id); + outfile.push(folder2); + outfile.push(id); + fs::copy(&infile, &outfile)?; + fs::remove_file(infile)?; + Ok(()) } - fn add_user(&mut self, user: &str) -> Result<(), ParseMailboxError> { + fn add_user(&mut self, user: &str) -> Result<(), Self::Error> { todo!() } diff --git a/src/mailstore/mod.rs b/src/mailstore/mod.rs index 658e0f0..a55f388 100644 --- a/src/mailstore/mod.rs +++ b/src/mailstore/mod.rs @@ -1,6 +1,6 @@ #![allow(unused_variables)] use crate::prelude::{Host, Mailbox, Mailuser, Message, ParseMailboxError}; -use std::{collections::HashMap, str::FromStr, convert::Infallible}; +use std::{collections::HashMap, convert::Infallible, io, str::FromStr}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -22,13 +22,24 @@ pub trait MailStore { /// returns the message fn get_message(&self, user: &str, folder: &str, title: &str) -> Option; /// Move a message to a new folder - fn move_message(&mut self, user: &str, id: &str, folder: &str); + fn move_message( + &mut self, + user: &str, + id: &str, + folder1: &str, + folder2: &str, + ) -> Result<(), Self::Error>; /// Deletes a message it it exists fn delete_message(&mut self, user: &str, folder: &str, id: &str) -> Result<(), Self::Error>; /// Adds a message - fn add_message(&mut self, user: &str, folder: &str, message: Message) -> Result<(), Self::Error>; + fn add_message( + &mut self, + user: &str, + folder: &str, + message: Message, + ) -> Result<(), Self::Error>; /// Adds a new mailuser to the given domain - fn add_user(&mut self, user: &str) -> Result<(), ParseMailboxError>; + fn add_user(&mut self, user: &str) -> Result<(), Self::Error>; /// Removes the given user if the account exists fn remove_user(&mut self, user: &str) -> bool; } @@ -61,7 +72,7 @@ pub struct MultiDomain { } impl MailStore for Domain { - type Error = Infallible; + type Error = io::Error; fn users(&self) -> Vec { self.users @@ -101,15 +112,22 @@ impl MailStore for Domain { .cloned() } - fn move_message(&mut self, user: &str, id: &str, folder: &str) { + fn move_message( + &mut self, + user: &str, + id: &str, + folder1: &str, + folder2: &str, + ) -> Result<(), Self::Error> { todo!() } - fn add_user(&mut self, user: &str) -> Result<(), ParseMailboxError> { + fn add_user(&mut self, user: &str) -> Result<(), Self::Error> { if self.users.contains_key(user) { return Ok(()); } - let mbox = Mailbox::from_str(&format!("{user}@{}", self.host.to_string()))?; + let mbox = Mailbox::from_str(&format!("{user}@{}", self.host.to_string())) + .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{e}")))?; let folders = HashMap::new(); let acct = Account { user: mbox, @@ -123,7 +141,12 @@ impl MailStore for Domain { self.users.remove(user).is_some() } - fn add_message(&mut self, user: &str, folder: &str, message: Message) -> Result<(), Self::Error> { + fn add_message( + &mut self, + user: &str, + folder: &str, + message: Message, + ) -> Result<(), Self::Error> { todo!() }