Complete some functions marked as todo in mailstore module

This commit is contained in:
Nathan Fisher 2023-06-21 01:21:19 -04:00
parent 2d3f5ab718
commit 12b10e382e
3 changed files with 100 additions and 13 deletions

View file

@ -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
} }
} }

View file

@ -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(())
} }
} }

View file

@ -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 {