Tweak MailStore
and MultiDomain
traits to add Error types
This commit is contained in:
parent
4f2f151173
commit
179b8ad100
3 changed files with 50 additions and 21 deletions
|
@ -1,11 +1,11 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::{fs, io, os::unix::fs::DirBuilderExt, path::PathBuf};
|
use std::{fs::{self, File}, io::{self, Write}, os::unix::fs::DirBuilderExt, path::PathBuf};
|
||||||
|
|
||||||
pub trait MultiDomain: MailStore {
|
pub trait MultiDomain: MailStore {
|
||||||
type Error;
|
type Error;
|
||||||
fn domains(&self) -> Result<Vec<String>, Self::Error>;
|
fn domains(&self) -> Result<Vec<String>, <Self as filesystem::MultiDomain>::Error>;
|
||||||
fn add_domain(&mut self, domain: &str) -> Result<(), Self::Error>;
|
fn add_domain(&mut self, domain: &str) -> Result<(), <Self as filesystem::MultiDomain>::Error>;
|
||||||
fn remove_domain(&mut self, domain: &str) -> Result<(), Self::Error>;
|
fn remove_domain(&mut self, domain: &str) -> Result<(), <Self as filesystem::MultiDomain>::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -15,6 +15,8 @@ pub struct Filesystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MailStore for Filesystem {
|
impl MailStore for Filesystem {
|
||||||
|
type Error = io::Error;
|
||||||
|
|
||||||
fn users(&self) -> Vec<Mailuser> {
|
fn users(&self) -> Vec<Mailuser> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
@ -48,7 +50,10 @@ impl MailStore for Filesystem {
|
||||||
let Ok(dir) = fs::read_dir(path) else {
|
let Ok(dir) = fs::read_dir(path) else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let mut folder = Folder { name: folder.to_string(), messages: HashMap::new() };
|
let mut folder = Folder {
|
||||||
|
name: folder.to_string(),
|
||||||
|
messages: HashMap::new(),
|
||||||
|
};
|
||||||
dir.filter(|x| x.is_ok()).map(|x| x.unwrap()).for_each(|e| {
|
dir.filter(|x| x.is_ok()).map(|x| x.unwrap()).for_each(|e| {
|
||||||
if let Ok(contents) = fs::read_to_string(e.path()) {
|
if let Ok(contents) = fs::read_to_string(e.path()) {
|
||||||
if let Ok(message) = contents.parse::<Message>() {
|
if let Ok(message) = contents.parse::<Message>() {
|
||||||
|
@ -60,14 +65,28 @@ impl MailStore for Filesystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_message(&self, user: &str, folder: &str, title: &str) -> Option<Message> {
|
fn get_message(&self, user: &str, folder: &str, title: &str) -> Option<Message> {
|
||||||
todo!()
|
self.get_folder(user, folder).and_then(|f| {
|
||||||
|
f.messages
|
||||||
|
.values()
|
||||||
|
.find(|m| m.title.as_ref().map(|x| x.as_str()) == Some(title))
|
||||||
|
.cloned()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_message(&mut self, user: &str, folder: &str, message: Message) {
|
fn add_message(&mut self, user: &str, folder: &str, message: Message) -> Result<(), Self::Error> {
|
||||||
todo!()
|
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(&message.id);
|
||||||
|
let mut fd = File::create(path)?;
|
||||||
|
write!(fd, "{message}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_message(&mut self, user: &str, folder: &str, key: &str) -> bool {
|
fn delete_message(&mut self, user: &str, folder: &str, key: &str) -> Result<(), Self::Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +106,7 @@ impl MailStore for Filesystem {
|
||||||
impl MultiDomain for Filesystem {
|
impl MultiDomain for Filesystem {
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
fn domains(&self) -> Result<Vec<String>, Self::Error> {
|
fn domains(&self) -> Result<Vec<String>, io::Error> {
|
||||||
Ok(self
|
Ok(self
|
||||||
.path
|
.path
|
||||||
.read_dir()?
|
.read_dir()?
|
||||||
|
@ -103,7 +122,7 @@ impl MultiDomain for Filesystem {
|
||||||
.collect::<Vec<String>>())
|
.collect::<Vec<String>>())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_domain(&mut self, domain: &str) -> Result<(), Self::Error> {
|
fn add_domain(&mut self, domain: &str) -> Result<(), io::Error> {
|
||||||
let mut path = self.path.clone();
|
let mut path = self.path.clone();
|
||||||
path.push(domain);
|
path.push(domain);
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
|
@ -115,7 +134,7 @@ impl MultiDomain for Filesystem {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_domain(&mut self, domain: &str) -> Result<(), Self::Error> {
|
fn remove_domain(&mut self, domain: &str) -> Result<(), io::Error> {
|
||||||
let mut path = self.path.clone();
|
let mut path = self.path.clone();
|
||||||
path.push(domain);
|
path.push(domain);
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
#![allow(unused_variables)]
|
||||||
use crate::prelude::{Host, Mailbox, Mailuser, Message, ParseMailboxError};
|
use crate::prelude::{Host, Mailbox, Mailuser, Message, ParseMailboxError};
|
||||||
use std::{collections::HashMap, str::FromStr};
|
use std::{collections::HashMap, str::FromStr, convert::Infallible};
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -7,6 +8,8 @@ use serde::{Deserialize, Serialize};
|
||||||
pub mod filesystem;
|
pub mod filesystem;
|
||||||
|
|
||||||
pub trait MailStore {
|
pub trait MailStore {
|
||||||
|
type Error;
|
||||||
|
|
||||||
/// Retreives a list of all valid mailusers on this server
|
/// Retreives a list of all valid mailusers on this server
|
||||||
fn users(&self) -> Vec<Mailuser>;
|
fn users(&self) -> Vec<Mailuser>;
|
||||||
/// Checks whether this server services that domain
|
/// Checks whether this server services that domain
|
||||||
|
@ -19,11 +22,11 @@ pub trait MailStore {
|
||||||
/// returns the message
|
/// returns the message
|
||||||
fn get_message(&self, user: &str, folder: &str, title: &str) -> Option<Message>;
|
fn get_message(&self, user: &str, folder: &str, title: &str) -> Option<Message>;
|
||||||
/// Move a message to a new folder
|
/// Move a message to a new folder
|
||||||
fn move_message(&mut self, user: &str, title: &str, folder: &str);
|
fn move_message(&mut self, user: &str, id: &str, folder: &str);
|
||||||
/// Deletes a message it it exists
|
/// Deletes a message it it exists
|
||||||
fn delete_message(&mut self, user: &str, folder: &str, key: &str) -> bool;
|
fn delete_message(&mut self, user: &str, folder: &str, id: &str) -> Result<(), Self::Error>;
|
||||||
/// Adds a message
|
/// Adds a message
|
||||||
fn add_message(&mut self, user: &str, folder: &str, message: Message);
|
fn add_message(&mut self, user: &str, folder: &str, message: Message) -> Result<(), Self::Error>;
|
||||||
/// Adds a new mailuser to the given domain
|
/// 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<(), ParseMailboxError>;
|
||||||
/// Removes the given user if the account exists
|
/// Removes the given user if the account exists
|
||||||
|
@ -58,6 +61,8 @@ pub struct MultiDomain {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MailStore for Domain {
|
impl MailStore for Domain {
|
||||||
|
type Error = Infallible;
|
||||||
|
|
||||||
fn users(&self) -> Vec<Mailuser> {
|
fn users(&self) -> Vec<Mailuser> {
|
||||||
self.users
|
self.users
|
||||||
.values()
|
.values()
|
||||||
|
@ -96,7 +101,7 @@ impl MailStore for Domain {
|
||||||
.cloned()
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_message(&mut self, user: &str, title: &str, folder: &str) {
|
fn move_message(&mut self, user: &str, id: &str, folder: &str) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,11 +123,11 @@ impl MailStore for Domain {
|
||||||
self.users.remove(user).is_some()
|
self.users.remove(user).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_message(&mut self, user: &str, folder: &str, message: Message) {
|
fn add_message(&mut self, user: &str, folder: &str, message: Message) -> Result<(), Self::Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_message(&mut self, user: &str, folder: &str, key: &str) -> bool {
|
fn delete_message(&mut self, user: &str, folder: &str, id: &str) -> Result<(), Self::Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,12 @@ where
|
||||||
S: CertificateStore + 'static + Clone,
|
S: CertificateStore + 'static + Clone,
|
||||||
C: ClientCertificateStore + Clone,
|
C: ClientCertificateStore + Clone,
|
||||||
{
|
{
|
||||||
pub fn new(sender: &str, recipients: &[&str], store: S, client_store: C) -> Result<Self, Error> {
|
pub fn new(
|
||||||
|
sender: &str,
|
||||||
|
recipients: &[&str],
|
||||||
|
store: S,
|
||||||
|
client_store: C,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
let mut rec = vec![];
|
let mut rec = vec![];
|
||||||
for r in recipients {
|
for r in recipients {
|
||||||
let r = r.parse()?;
|
let r = r.parse()?;
|
||||||
|
@ -115,7 +120,7 @@ where
|
||||||
sender: sender.parse()?,
|
sender: sender.parse()?,
|
||||||
recipients: rec,
|
recipients: rec,
|
||||||
store,
|
store,
|
||||||
client_store
|
client_store,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue