io_email/mailbox/jmap/
delete.rs1use alloc::{string::String, vec};
13use core::mem;
14
15use io_jmap::{
16 coroutine::{JmapCoroutine, JmapCoroutineState, JmapYield},
17 rfc8620::JmapSession,
18 rfc8621::mailbox::set::{
19 JmapMailboxSet as InnerSet, JmapMailboxSetArgs, JmapMailboxSetError as SetErr,
20 },
21};
22use log::trace;
23use secrecy::SecretString;
24use thiserror::Error;
25
26#[derive(Debug, Error)]
28pub enum JmapMailboxDeleteError {
29 #[error(transparent)]
30 Set(#[from] SetErr),
31 #[error("Mailbox/set did not destroy `{0}`")]
32 NotDestroyed(String),
33 #[error("coroutine was resumed after completion")]
34 ResumedAfterDone,
35}
36
37pub struct JmapMailboxDelete {
39 state: State,
40 id: String,
41}
42
43impl JmapMailboxDelete {
44 pub fn new(
45 session: &JmapSession,
46 http_auth: &SecretString,
47 id: &str,
48 ) -> Result<Self, JmapMailboxDeleteError> {
49 trace!("prepare JMAP mailbox delete");
50 let args = JmapMailboxSetArgs {
51 destroy: Some(vec![id.into()]),
52 on_destroy_remove_emails: Some(true),
53 ..JmapMailboxSetArgs::default()
54 };
55 let set = InnerSet::new(session, http_auth, args)?;
56 Ok(Self {
57 state: State::Destroying(set),
58 id: id.into(),
59 })
60 }
61}
62
63enum State {
64 Destroying(InnerSet),
65 Done,
66}
67
68impl JmapCoroutine for JmapMailboxDelete {
69 type Yield = JmapYield;
70 type Return = Result<(), JmapMailboxDeleteError>;
71
72 fn resume(&mut self, bytes: Option<&[u8]>) -> JmapCoroutineState<Self::Yield, Self::Return> {
73 match mem::replace(&mut self.state, State::Done) {
74 State::Destroying(mut set) => match set.resume(bytes) {
75 JmapCoroutineState::Complete(Ok(ok)) => {
76 if ok.destroyed.iter().any(|d| d == &self.id) {
77 JmapCoroutineState::Complete(Ok(()))
78 } else {
79 JmapCoroutineState::Complete(Err(JmapMailboxDeleteError::NotDestroyed(
80 mem::take(&mut self.id),
81 )))
82 }
83 }
84 JmapCoroutineState::Yielded(y) => {
85 self.state = State::Destroying(set);
86 JmapCoroutineState::Yielded(y)
87 }
88 JmapCoroutineState::Complete(Err(err)) => {
89 JmapCoroutineState::Complete(Err(err.into()))
90 }
91 },
92 State::Done => {
93 JmapCoroutineState::Complete(Err(JmapMailboxDeleteError::ResumedAfterDone))
94 }
95 }
96 }
97}