use alloc::{string::String, vec};
use io_jmap::{
coroutine::{JmapCoroutine, JmapCoroutineState, JmapYield},
rfc8620::JmapSession,
rfc8621::email::set::{
JmapEmailSet as InnerSet, JmapEmailSetArgs, JmapEmailSetError as InnerErr,
},
};
use log::trace;
use secrecy::SecretString;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum JmapMessageDeleteError {
#[error(transparent)]
Set(#[from] InnerErr),
#[error("Email/set did not destroy `{0}`")]
NotDestroyed(String),
}
pub struct JmapMessageDelete {
inner: InnerSet,
id: String,
}
impl JmapMessageDelete {
pub fn new(
session: &JmapSession,
http_auth: &SecretString,
_mailbox: &str,
id: &str,
) -> Result<Self, JmapMessageDeleteError> {
trace!("prepare JMAP message delete");
let args = JmapEmailSetArgs {
destroy: Some(vec![id.into()]),
..JmapEmailSetArgs::default()
};
Ok(Self {
inner: InnerSet::new(session, http_auth, args)?,
id: id.into(),
})
}
}
impl JmapCoroutine for JmapMessageDelete {
type Yield = JmapYield;
type Return = Result<(), JmapMessageDeleteError>;
fn resume(&mut self, bytes: Option<&[u8]>) -> JmapCoroutineState<Self::Yield, Self::Return> {
match self.inner.resume(bytes) {
JmapCoroutineState::Yielded(y) => JmapCoroutineState::Yielded(y),
JmapCoroutineState::Complete(Ok(ok)) => {
if ok.destroyed.iter().any(|d| d == &self.id) {
JmapCoroutineState::Complete(Ok(()))
} else {
JmapCoroutineState::Complete(Err(JmapMessageDeleteError::NotDestroyed(
self.id.clone(),
)))
}
}
JmapCoroutineState::Complete(Err(err)) => JmapCoroutineState::Complete(Err(err.into())),
}
}
}