io_email/message/jmap/
copy.rs1use alloc::{string::String, vec::Vec};
16use core::mem;
17
18use io_jmap::{
19 coroutine::{JmapCoroutine, JmapCoroutineState, JmapYield},
20 rfc8620::JmapSession,
21 rfc8621::email::set::{
22 JmapEmailSet as InnerSet, JmapEmailSetArgs, JmapEmailSetError as SetErr,
23 },
24};
25use log::trace;
26use secrecy::SecretString;
27use thiserror::Error;
28
29#[derive(Debug, Error)]
31pub enum JmapMessageCopyError {
32 #[error(transparent)]
33 Set(#[from] SetErr),
34 #[error("Email/set returned per-id failures: {0:?}")]
35 NotUpdated(Vec<String>),
36 #[error("coroutine was resumed after completion")]
37 ResumedAfterDone,
38}
39
40pub struct JmapMessageCopy {
42 state: State,
43}
44
45impl JmapMessageCopy {
46 pub fn new(
47 session: &JmapSession,
48 http_auth: &SecretString,
49 _from: &str,
50 to: &str,
51 ids: &[&str],
52 ) -> Result<Self, JmapMessageCopyError> {
53 trace!("prepare JMAP message copy");
54 let mut args = JmapEmailSetArgs::default();
55 for id in ids {
56 args.add_to_mailbox(*id, to);
57 }
58 let set = InnerSet::new(session, http_auth, args)?;
59 Ok(Self {
60 state: State::Patching(set),
61 })
62 }
63}
64
65enum State {
66 Patching(InnerSet),
67 Done,
68}
69
70impl JmapCoroutine for JmapMessageCopy {
71 type Yield = JmapYield;
72 type Return = Result<(), JmapMessageCopyError>;
73
74 fn resume(&mut self, bytes: Option<&[u8]>) -> JmapCoroutineState<Self::Yield, Self::Return> {
75 match mem::replace(&mut self.state, State::Done) {
76 State::Patching(mut set) => match set.resume(bytes) {
77 JmapCoroutineState::Complete(Ok(ok)) => {
78 if ok.not_updated.is_empty() {
79 JmapCoroutineState::Complete(Ok(()))
80 } else {
81 JmapCoroutineState::Complete(Err(JmapMessageCopyError::NotUpdated(
82 ok.not_updated.into_keys().collect(),
83 )))
84 }
85 }
86 JmapCoroutineState::Yielded(y) => {
87 self.state = State::Patching(set);
88 JmapCoroutineState::Yielded(y)
89 }
90 JmapCoroutineState::Complete(Err(err)) => {
91 JmapCoroutineState::Complete(Err(err.into()))
92 }
93 },
94 State::Done => {
95 JmapCoroutineState::Complete(Err(JmapMessageCopyError::ResumedAfterDone))
96 }
97 }
98 }
99}