use alloc::{string::ToString, vec::Vec};
use io_maildir::{
coroutine::*,
maildir::{
list::{MaildirList as InnerMaildirList, MaildirListError},
types::Maildir,
},
store::MaildirStore,
};
use log::trace;
use thiserror::Error;
use crate::mailbox::types::Mailbox;
#[derive(Debug, Error)]
pub enum MaildirMailboxListError {
#[error(transparent)]
List(#[from] MaildirListError),
}
pub struct MaildirMailboxList {
inner: InnerMaildirList,
}
impl MaildirMailboxList {
pub fn new(store: &MaildirStore, _with_counts: bool) -> Self {
trace!(
"prepare Maildir mailbox listing (maildirpp={})",
store.maildirpp
);
Self {
inner: InnerMaildirList::new(store),
}
}
}
impl MaildirCoroutine for MaildirMailboxList {
type Yield = MaildirYield;
type Return = Result<Vec<Mailbox>, MaildirMailboxListError>;
fn resume(
&mut self,
arg: Option<MaildirReply>,
) -> MaildirCoroutineState<Self::Yield, Self::Return> {
match self.inner.resume(arg) {
MaildirCoroutineState::Yielded(y) => MaildirCoroutineState::Yielded(y),
MaildirCoroutineState::Complete(Ok(maildirs)) => {
let mut mailboxes: Vec<Mailbox> = maildirs.into_iter().map(mailbox_from).collect();
mailboxes.sort_by(|a, b| a.name.cmp(&b.name));
MaildirCoroutineState::Complete(Ok(mailboxes))
}
MaildirCoroutineState::Complete(Err(err)) => {
MaildirCoroutineState::Complete(Err(err.into()))
}
}
}
}
fn mailbox_from(maildir: Maildir) -> Mailbox {
let name = maildir.name().unwrap_or("").to_string();
let id = maildir.path().to_string();
Mailbox {
id,
name,
total: None,
unread: None,
}
}