io_email/mailbox/jmap/
list.rs1use alloc::{vec, vec::Vec};
16
17use io_jmap::{
18 coroutine::{JmapCoroutine, JmapCoroutineState, JmapYield},
19 rfc8620::JmapSession,
20 rfc8621::mailbox::{
21 JmapMailbox as JmapMailboxObject, JmapMailboxProperty,
22 query::{
23 JmapMailboxQuery, JmapMailboxQueryError, JmapMailboxQueryOptions,
24 JmapMailboxQueryOutput,
25 },
26 },
27};
28use log::trace;
29use secrecy::SecretString;
30use thiserror::Error;
31
32use crate::mailbox::types::Mailbox;
33
34#[derive(Debug, Error)]
36pub enum JmapMailboxListError {
37 #[error(transparent)]
38 Query(#[from] JmapMailboxQueryError),
39}
40
41pub struct JmapMailboxList {
44 inner: JmapMailboxQuery,
45}
46
47impl JmapMailboxList {
48 pub fn new(
51 session: &JmapSession,
52 http_auth: &SecretString,
53 with_counts: bool,
54 ) -> Result<Self, JmapMailboxListError> {
55 trace!("prepare JMAP mailbox listing (with_counts={with_counts})");
56 let properties = if with_counts {
57 vec![
58 JmapMailboxProperty::Id,
59 JmapMailboxProperty::Name,
60 JmapMailboxProperty::TotalEmails,
61 JmapMailboxProperty::UnreadEmails,
62 ]
63 } else {
64 vec![JmapMailboxProperty::Id, JmapMailboxProperty::Name]
65 };
66 let opts = JmapMailboxQueryOptions {
67 properties: Some(properties),
68 ..Default::default()
69 };
70 Ok(Self {
71 inner: JmapMailboxQuery::new(session, http_auth, opts)?,
72 })
73 }
74}
75
76fn mailbox_from(mailbox: JmapMailboxObject) -> Mailbox {
78 Mailbox {
79 id: mailbox.id.unwrap_or_default(),
80 name: mailbox.name.unwrap_or_default(),
81 total: Some(u64::from(mailbox.total_emails)),
82 unread: Some(u64::from(mailbox.unread_emails)),
83 }
84}
85
86impl JmapCoroutine for JmapMailboxList {
87 type Yield = JmapYield;
88 type Return = Result<Vec<Mailbox>, JmapMailboxListError>;
89
90 fn resume(&mut self, bytes: Option<&[u8]>) -> JmapCoroutineState<Self::Yield, Self::Return> {
91 match self.inner.resume(bytes) {
92 JmapCoroutineState::Yielded(y) => JmapCoroutineState::Yielded(y),
93 JmapCoroutineState::Complete(Ok(JmapMailboxQueryOutput { mailboxes, .. })) => {
94 let mailboxes = mailboxes.into_iter().map(mailbox_from).collect();
95 JmapCoroutineState::Complete(Ok(mailboxes))
96 }
97 JmapCoroutineState::Complete(Err(err)) => JmapCoroutineState::Complete(Err(err.into())),
98 }
99 }
100}