153 lines
4.3 KiB
Rust
153 lines
4.3 KiB
Rust
#![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<Mailuser>;
|
|
/// 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<Folder>;
|
|
/// 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<Message>;
|
|
/// 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<String, Account>,
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
pub struct Account {
|
|
pub user: Mailbox,
|
|
pub folders: HashMap<String, Folder>,
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
pub struct Folder {
|
|
pub name: String,
|
|
pub messages: HashMap<String, Message>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
|
pub struct MultiDomain {
|
|
pub domains: HashMap<String, Domain>,
|
|
}
|
|
|
|
impl MailStore for Domain {
|
|
type Error = io::Error;
|
|
|
|
fn users(&self) -> Vec<Mailuser> {
|
|
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<Folder> {
|
|
self.users
|
|
.get(user)
|
|
.cloned()
|
|
.and_then(|u| u.folders.get(folder).cloned())
|
|
}
|
|
|
|
fn get_message(&self, user: &str, folder: &str, title: &str) -> Option<Message> {
|
|
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!()
|
|
}
|
|
}
|