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 std::{
|
||||
fs::{self, File},
|
||||
io::{self, Write},
|
||||
os::unix::fs::DirBuilderExt,
|
||||
path::PathBuf,
|
||||
use {
|
||||
super::*,
|
||||
crate::{message::Parser as MessageParser, prelude::ParseMailboxError},
|
||||
std::{
|
||||
fs::{self, File},
|
||||
io::{self, BufWriter, Write},
|
||||
os::unix::fs::DirBuilderExt,
|
||||
path::PathBuf,
|
||||
},
|
||||
};
|
||||
|
||||
pub trait MultiDomain: MailStore {
|
||||
|
@ -28,7 +29,38 @@ impl MailStore for Filesystem {
|
|||
type Error = io::Error;
|
||||
|
||||
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 {
|
||||
|
@ -143,11 +175,41 @@ impl MailStore for Filesystem {
|
|||
}
|
||||
|
||||
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 {
|
||||
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,
|
||||
message: Message,
|
||||
) -> 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> {
|
||||
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)
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
assert!(month < 13);
|
||||
match month {
|
||||
|
|
Loading…
Add table
Reference in a new issue