Complete some functions marked as todo
in mailstore module
This commit is contained in:
parent
2d3f5ab718
commit
12b10e382e
3 changed files with 100 additions and 13 deletions
|
@ -1,11 +1,12 @@
|
||||||
use crate::message::Parser as MessageParser;
|
use {
|
||||||
|
super::*,
|
||||||
use super::*;
|
crate::{message::Parser as MessageParser, prelude::ParseMailboxError},
|
||||||
use std::{
|
std::{
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
io::{self, Write},
|
io::{self, BufWriter, Write},
|
||||||
os::unix::fs::DirBuilderExt,
|
os::unix::fs::DirBuilderExt,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait MultiDomain: MailStore {
|
pub trait MultiDomain: MailStore {
|
||||||
|
@ -28,7 +29,38 @@ impl MailStore for Filesystem {
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
fn users(&self) -> Vec<Mailuser> {
|
fn users(&self) -> Vec<Mailuser> {
|
||||||
todo!()
|
let mut users = vec![];
|
||||||
|
let Ok(domains) = fs::read_dir(&self.path) else {
|
||||||
|
return users;
|
||||||
|
};
|
||||||
|
for d in domains {
|
||||||
|
let Ok(dom) = d else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let name = dom.file_name().to_string_lossy().to_string();
|
||||||
|
let Ok(host) = name.parse::<Host>() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let dom_path = dom.path();
|
||||||
|
let Ok(dom_users) = fs::read_dir(&dom_path) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
for u in dom_users {
|
||||||
|
let Ok(user) = u else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if let Ok(ft) = user.file_type() {
|
||||||
|
if ft.is_dir() {
|
||||||
|
let username = user.file_name().to_string_lossy().to_string();
|
||||||
|
users.push(Mailuser {
|
||||||
|
username,
|
||||||
|
host: host.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
users
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serves_domain(&self, domain: &str) -> bool {
|
fn serves_domain(&self, domain: &str) -> bool {
|
||||||
|
@ -143,11 +175,41 @@ impl MailStore for Filesystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_user(&mut self, user: &str) -> Result<(), Self::Error> {
|
fn add_user(&mut self, user: &str) -> Result<(), Self::Error> {
|
||||||
todo!()
|
let mb: Mailbox = user
|
||||||
|
.parse()
|
||||||
|
.map_err(|e: ParseMailboxError| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
|
||||||
|
let mut path = self.path.clone();
|
||||||
|
path.push(&mb.host.to_string());
|
||||||
|
path.push(&mb.username);
|
||||||
|
path.push("Inbox");
|
||||||
|
fs::create_dir_all(&path)?;
|
||||||
|
if let Some(ref blurb) = mb.blurb {
|
||||||
|
let _last = path.pop();
|
||||||
|
path.push("blurb");
|
||||||
|
let fd = File::options()
|
||||||
|
.create(true)
|
||||||
|
.write(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(path)?;
|
||||||
|
let mut writer = BufWriter::new(fd);
|
||||||
|
writer.write_all(blurb.as_bytes())?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_user(&mut self, user: &str) -> bool {
|
fn remove_user(&mut self, user: &str) -> bool {
|
||||||
todo!()
|
let Ok(mu) = user.parse::<Mailbox>() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let mut path = self.path.clone();
|
||||||
|
path.push(&mu.host.to_string());
|
||||||
|
path.push(&mu.username);
|
||||||
|
if path.exists() {
|
||||||
|
if fs::remove_dir_all(path).is_ok() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,10 +144,31 @@ impl MailStore for Domain {
|
||||||
folder: &str,
|
folder: &str,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
todo!()
|
let user = self
|
||||||
|
.users
|
||||||
|
.get_mut(user)
|
||||||
|
.ok_or(io::Error::new(io::ErrorKind::Other, "No such user"))?;
|
||||||
|
let folder = match user.folders.get_mut(folder) {
|
||||||
|
Some(f) => f,
|
||||||
|
_ => {
|
||||||
|
let f = Folder {
|
||||||
|
name: folder.to_string(),
|
||||||
|
messages: HashMap::new(),
|
||||||
|
};
|
||||||
|
user.folders.insert(folder.to_string(), f);
|
||||||
|
user.folders.get_mut(folder).unwrap()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
folder.messages.insert(message.id.clone(), message);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_message(&mut self, user: &str, folder: &str, id: &str) -> Result<(), Self::Error> {
|
fn delete_message(&mut self, user: &str, folder: &str, id: &str) -> Result<(), Self::Error> {
|
||||||
todo!()
|
if let Some(user) = self.users.get_mut(user) {
|
||||||
|
if let Some(folder) = user.folders.get_mut(folder) {
|
||||||
|
let _msg = folder.messages.remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,10 @@ fn is_leap(year: i64) -> bool {
|
||||||
year % 4 == 0 && (year % 100 != 0 || year % 16 == 0)
|
year % 4 == 0 && (year % 100 != 0 || year % 16 == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the number of days in a given month. If the
|
||||||
|
/// given month is February, then we also need to know
|
||||||
|
/// whether it is a leap year or not, hence this function
|
||||||
|
/// takes the year as an argument as well.
|
||||||
pub fn days_in_month(month: u8, year: i64) -> i64 {
|
pub fn days_in_month(month: u8, year: i64) -> i64 {
|
||||||
assert!(month < 13);
|
assert!(month < 13);
|
||||||
match month {
|
match month {
|
||||||
|
|
Loading…
Add table
Reference in a new issue