#![allow(unused_variables)] use crate::prelude::{Host, Mailbox, Mailuser, Message}; use std::{collections::HashMap, io, str::FromStr}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; pub mod filesystem; pub trait MailStore { type Error; /// Retreives a list of all valid mailusers on this server fn users(&self) -> Vec; /// Checks whether this server services that domain fn serves_domain(&self, domain: &str) -> bool; /// Checks whether this server has the given mailuser fn has_mailuser(&self, mailuser: &str) -> bool; /// Retreives all of the messages for this user fn get_folder(&self, user: &str, folder: &str) -> Option; /// Checks whether this server has a message with the given title for this user and if so /// 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, 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>; /// Adds a new mailuser to the given domain 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; } #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Domain { pub host: Host, pub users: HashMap, } #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Account { pub user: Mailbox, pub folders: HashMap, } #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct Folder { pub name: String, pub messages: HashMap, } #[derive(Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MultiDomain { pub domains: HashMap, } impl MailStore for Domain { type Error = io::Error; fn users(&self) -> Vec { self.users .values() .map(|act| act.user.clone().into()) .collect() } fn serves_domain(&self, domain: &str) -> bool { self.host.to_string().as_str() == domain } fn has_mailuser(&self, mailuser: &str) -> bool { self.users().iter().any(|x| x.username == mailuser) } fn get_folder(&self, user: &str, folder: &str) -> Option { self.users .get(user) .cloned() .and_then(|u| u.folders.get(folder).cloned()) } fn get_message(&self, user: &str, folder: &str, title: &str) -> Option { self.users .get(user) .and_then(|u| { u.folders.get(folder).and_then(|f| { f.messages .values() .find(|m| m.title.as_ref().map(String::as_str) == Some(title)) }) }) .cloned() } 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<(), Self::Error> { if self.users.contains_key(user) { return Ok(()); } let mbox = Mailbox::from_str(&format!("{user}@{}", self.host)) .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{e}")))?; let folders = HashMap::new(); let acct = Account { user: mbox, folders, }; self.users.insert(user.to_string(), acct); Ok(()) } fn remove_user(&mut self, user: &str) -> bool { self.users.remove(user).is_some() } fn add_message( &mut self, user: &str, folder: &str, message: Message, ) -> Result<(), Self::Error> { todo!() } fn delete_message(&mut self, user: &str, folder: &str, id: &str) -> Result<(), Self::Error> { todo!() } }