aboutsummaryrefslogtreecommitdiff
path: root/src/imap/command
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2024-01-02 15:35:23 +0100
committerQuentin Dufour <quentin@deuxfleurs.fr>2024-01-02 15:35:23 +0100
commit9a8d4c651e5993f09f54cf7c1eacf7a4839ea9db (patch)
tree671e4ef03c534f282818f747751c3c2e038a9646 /src/imap/command
parent07eea38765aecbd53e51be199094eba2871dc7ad (diff)
downloadaerogramme-9a8d4c651e5993f09f54cf7c1eacf7a4839ea9db.tar.gz
aerogramme-9a8d4c651e5993f09f54cf7c1eacf7a4839ea9db.zip
commands now use imap-flow
Diffstat (limited to 'src/imap/command')
-rw-r--r--src/imap/command/anonymous.rs20
-rw-r--r--src/imap/command/anystate.rs27
-rw-r--r--src/imap/command/authenticated.rs150
-rw-r--r--src/imap/command/examined.rs40
-rw-r--r--src/imap/command/selected.rs60
5 files changed, 155 insertions, 142 deletions
diff --git a/src/imap/command/anonymous.rs b/src/imap/command/anonymous.rs
index 42e2a87..4de5fbd 100644
--- a/src/imap/command/anonymous.rs
+++ b/src/imap/command/anonymous.rs
@@ -13,11 +13,11 @@ use crate::mail::user::User;
//--- dispatching
pub struct AnonymousContext<'a> {
- pub req: &'a Command<'static>,
+ pub req: &'a Command<'a>,
pub login_provider: &'a ArcLoginProvider,
}
-pub async fn dispatch(ctx: AnonymousContext<'_>) -> Result<(Response, flow::Transition)> {
+pub async fn dispatch<'a>(ctx: AnonymousContext<'a>) -> Result<(Response<'a>, flow::Transition)> {
match &ctx.req.body {
// Any State
CommandBody::Noop => anystate::noop_nothing(ctx.req.tag.clone()),
@@ -39,14 +39,14 @@ pub async fn dispatch(ctx: AnonymousContext<'_>) -> Result<(Response, flow::Tran
//--- Command controllers, private
impl<'a> AnonymousContext<'a> {
- async fn capability(self) -> Result<(Response, flow::Transition)> {
+ async fn capability(self) -> Result<(Response<'a>, flow::Transition)> {
let capabilities: NonEmptyVec<Capability> =
(vec![Capability::Imap4Rev1, Capability::Idle]).try_into()?;
- let res = Response::ok()
+ let res = Response::build()
.to_req(self.req)
.message("Server capabilities")
.data(Data::Capability(capabilities))
- .build()?;
+ .ok()?;
Ok((res, flow::Transition::None))
}
@@ -54,7 +54,7 @@ impl<'a> AnonymousContext<'a> {
self,
username: &AString<'a>,
password: &Secret<AString<'a>>,
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
let (u, p) = (
std::str::from_utf8(username.as_ref())?,
std::str::from_utf8(password.declassify().as_ref())?,
@@ -65,10 +65,10 @@ impl<'a> AnonymousContext<'a> {
Err(e) => {
tracing::debug!(error=%e, "authentication failed");
return Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message("Authentication failed")
- .build()?,
+ .no()?,
flow::Transition::None,
));
}
@@ -79,10 +79,10 @@ impl<'a> AnonymousContext<'a> {
tracing::info!(username=%u, "connected");
Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("Completed")
- .build()?,
+ .ok()?,
flow::Transition::Authenticate(user),
))
}
diff --git a/src/imap/command/anystate.rs b/src/imap/command/anystate.rs
index 2d10ad8..ea3bc16 100644
--- a/src/imap/command/anystate.rs
+++ b/src/imap/command/anystate.rs
@@ -5,45 +5,48 @@ use imap_codec::imap_types::response::{Capability, Data};
use crate::imap::flow;
use crate::imap::response::Response;
-pub(crate) fn capability(tag: Tag) -> Result<(Response, flow::Transition)> {
+pub(crate) fn capability<'a>(tag: Tag<'a>) -> Result<(Response<'a>, flow::Transition)> {
let capabilities: NonEmptyVec<Capability> =
(vec![Capability::Imap4Rev1, Capability::Idle]).try_into()?;
- let res = Response::ok()
+ let res = Response::build()
.tag(tag)
.message("Server capabilities")
.data(Data::Capability(capabilities))
- .build()?;
+ .ok()?;
Ok((res, flow::Transition::None))
}
-pub(crate) fn noop_nothing(tag: Tag) -> Result<(Response, flow::Transition)> {
+pub(crate) fn noop_nothing<'a>(tag: Tag<'a>) -> Result<(Response<'a>, flow::Transition)> {
Ok((
- Response::ok().tag(tag).message("Noop completed.").build()?,
+ Response::build().tag(tag).message("Noop completed.").ok()?,
flow::Transition::None,
))
}
-pub(crate) fn logout() -> Result<(Response, flow::Transition)> {
+pub(crate) fn logout() -> Result<(Response<'static>, flow::Transition)> {
Ok((Response::bye()?, flow::Transition::Logout))
}
-pub(crate) fn not_implemented(tag: Tag, what: &str) -> Result<(Response, flow::Transition)> {
+pub(crate) fn not_implemented<'a>(
+ tag: Tag<'a>,
+ what: &str,
+) -> Result<(Response<'a>, flow::Transition)> {
Ok((
- Response::bad()
+ Response::build()
.tag(tag)
.message(format!("Command not implemented {}", what))
- .build()?,
+ .bad()?,
flow::Transition::None,
))
}
-pub(crate) fn wrong_state(tag: Tag) -> Result<(Response, flow::Transition)> {
+pub(crate) fn wrong_state<'a>(tag: Tag<'a>) -> Result<(Response<'a>, flow::Transition)> {
Ok((
- Response::bad()
+ Response::build()
.tag(tag)
.message("Command not authorized in this state")
- .build()?,
+ .bad()?,
flow::Transition::None,
))
}
diff --git a/src/imap/command/authenticated.rs b/src/imap/command/authenticated.rs
index ca4ad03..c9f9ff7 100644
--- a/src/imap/command/authenticated.rs
+++ b/src/imap/command/authenticated.rs
@@ -20,14 +20,14 @@ use crate::mail::uidindex::*;
use crate::mail::user::{User, MAILBOX_HIERARCHY_DELIMITER as MBX_HIER_DELIM_RAW};
use crate::mail::IMF;
-static MAILBOX_HIERARCHY_DELIMITER: QuotedChar = QuotedChar::unvalidated(MBX_HIER_DELIM_RAW);
-
pub struct AuthenticatedContext<'a> {
- pub req: &'a Command<'static>,
+ pub req: &'a Command<'a>,
pub user: &'a Arc<User>,
}
-pub async fn dispatch(ctx: AuthenticatedContext<'_>) -> Result<(Response, flow::Transition)> {
+pub async fn dispatch<'a>(
+ ctx: AuthenticatedContext<'a>,
+) -> Result<(Response<'a>, flow::Transition)> {
match &ctx.req.body {
// Any state
CommandBody::Noop => anystate::noop_nothing(ctx.req.tag.clone()),
@@ -68,14 +68,14 @@ pub async fn dispatch(ctx: AuthenticatedContext<'_>) -> Result<(Response, flow::
// --- PRIVATE ---
impl<'a> AuthenticatedContext<'a> {
- async fn create(self, mailbox: &MailboxCodec<'a>) -> Result<(Response, flow::Transition)> {
+ async fn create(self, mailbox: &MailboxCodec<'a>) -> Result<(Response<'a>, flow::Transition)> {
let name = match mailbox {
MailboxCodec::Inbox => {
return Ok((
- Response::bad()
+ Response::build()
.to_req(self.req)
.message("Cannot create INBOX")
- .build()?,
+ .bad()?,
flow::Transition::None,
));
}
@@ -84,38 +84,38 @@ impl<'a> AuthenticatedContext<'a> {
match self.user.create_mailbox(&name).await {
Ok(()) => Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("CREATE complete")
- .build()?,
+ .ok()?,
flow::Transition::None,
)),
Err(e) => Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message(&e.to_string())
- .build()?,
+ .no()?,
flow::Transition::None,
)),
}
}
- async fn delete(self, mailbox: &MailboxCodec<'a>) -> Result<(Response, flow::Transition)> {
+ async fn delete(self, mailbox: &MailboxCodec<'a>) -> Result<(Response<'a>, flow::Transition)> {
let name: &str = MailboxName(mailbox).try_into()?;
match self.user.delete_mailbox(&name).await {
Ok(()) => Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("DELETE complete")
- .build()?,
+ .ok()?,
flow::Transition::None,
)),
Err(e) => Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message(e.to_string())
- .build()?,
+ .no()?,
flow::Transition::None,
)),
}
@@ -125,23 +125,23 @@ impl<'a> AuthenticatedContext<'a> {
self,
from: &MailboxCodec<'a>,
to: &MailboxCodec<'a>,
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
let name: &str = MailboxName(from).try_into()?;
let new_name: &str = MailboxName(to).try_into()?;
match self.user.rename_mailbox(&name, &new_name).await {
Ok(()) => Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("RENAME complete")
- .build()?,
+ .ok()?,
flow::Transition::None,
)),
Err(e) => Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message(e.to_string())
- .build()?,
+ .no()?,
flow::Transition::None,
)),
}
@@ -152,14 +152,16 @@ impl<'a> AuthenticatedContext<'a> {
reference: &MailboxCodec<'a>,
mailbox_wildcard: &ListMailbox<'a>,
is_lsub: bool,
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
+ let mbx_hier_delim: QuotedChar = QuotedChar::unvalidated(MBX_HIER_DELIM_RAW);
+
let reference: &str = MailboxName(reference).try_into()?;
if !reference.is_empty() {
return Ok((
- Response::bad()
+ Response::build()
.to_req(self.req)
.message("References not supported")
- .build()?,
+ .bad()?,
flow::Transition::None,
));
}
@@ -172,28 +174,28 @@ impl<'a> AuthenticatedContext<'a> {
if wildcard.is_empty() {
if is_lsub {
return Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("LSUB complete")
.data(Data::Lsub {
items: vec![],
- delimiter: Some(MAILBOX_HIERARCHY_DELIMITER),
+ delimiter: Some(mbx_hier_delim),
mailbox: "".try_into().unwrap(),
})
- .build()?,
+ .ok()?,
flow::Transition::None,
));
} else {
return Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("LIST complete")
.data(Data::List {
items: vec![],
- delimiter: Some(MAILBOX_HIERARCHY_DELIMITER),
+ delimiter: Some(mbx_hier_delim),
mailbox: "".try_into().unwrap(),
})
- .build()?,
+ .ok()?,
flow::Transition::None,
));
}
@@ -227,13 +229,13 @@ impl<'a> AuthenticatedContext<'a> {
if is_lsub {
ret.push(Data::Lsub {
items,
- delimiter: Some(MAILBOX_HIERARCHY_DELIMITER),
+ delimiter: Some(mbx_hier_delim),
mailbox,
});
} else {
ret.push(Data::List {
items,
- delimiter: Some(MAILBOX_HIERARCHY_DELIMITER),
+ delimiter: Some(mbx_hier_delim),
mailbox,
});
}
@@ -246,11 +248,11 @@ impl<'a> AuthenticatedContext<'a> {
"LIST completed"
};
Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message(msg)
- .set_data(ret)
- .build()?,
+ .many_data(ret)
+ .ok()?,
flow::Transition::None,
))
}
@@ -259,23 +261,23 @@ impl<'a> AuthenticatedContext<'a> {
self,
mailbox: &MailboxCodec<'a>,
attributes: &[StatusDataItemName],
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
let name: &str = MailboxName(mailbox).try_into()?;
let mb_opt = self.user.open_mailbox(name).await?;
let mb = match mb_opt {
Some(mb) => mb,
None => {
return Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message("Mailbox does not exist")
- .build()?,
+ .no()?,
flow::Transition::None,
))
}
};
- let (view, _data) = MailboxView::new(mb).await?;
+ let view = MailboxView::new(mb).await;
let mut ret_attrs = vec![];
for attr in attributes.iter() {
@@ -302,57 +304,63 @@ impl<'a> AuthenticatedContext<'a> {
};
Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("STATUS completed")
.data(data)
- .build()?,
+ .ok()?,
flow::Transition::None,
))
}
- async fn subscribe(self, mailbox: &MailboxCodec<'a>) -> Result<(Response, flow::Transition)> {
+ async fn subscribe(
+ self,
+ mailbox: &MailboxCodec<'a>,
+ ) -> Result<(Response<'a>, flow::Transition)> {
let name: &str = MailboxName(mailbox).try_into()?;
if self.user.has_mailbox(&name).await? {
Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("SUBSCRIBE complete")
- .build()?,
+ .ok()?,
flow::Transition::None,
))
} else {
Ok((
- Response::bad()
+ Response::build()
.to_req(self.req)
.message(format!("Mailbox {} does not exist", name))
- .build()?,
+ .bad()?,
flow::Transition::None,
))
}
}
- async fn unsubscribe(self, mailbox: &MailboxCodec<'a>) -> Result<(Response, flow::Transition)> {
+ async fn unsubscribe(
+ self,
+ mailbox: &MailboxCodec<'a>,
+ ) -> Result<(Response<'a>, flow::Transition)> {
let name: &str = MailboxName(mailbox).try_into()?;
if self.user.has_mailbox(&name).await? {
Ok((
- Response::bad()
+ Response::build()
.to_req(self.req)
.message(format!(
"Cannot unsubscribe from mailbox {}: not supported by Aerogramme",
name
))
- .build()?,
+ .bad()?,
flow::Transition::None,
))
} else {
Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message(format!("Mailbox {} does not exist", name))
- .build()?,
+ .no()?,
flow::Transition::None,
))
}
@@ -391,7 +399,7 @@ impl<'a> AuthenticatedContext<'a> {
* TRACE END ---
*/
- async fn select(self, mailbox: &MailboxCodec<'a>) -> Result<(Response, flow::Transition)> {
+ async fn select(self, mailbox: &MailboxCodec<'a>) -> Result<(Response<'a>, flow::Transition)> {
let name: &str = MailboxName(mailbox).try_into()?;
let mb_opt = self.user.open_mailbox(&name).await?;
@@ -399,29 +407,30 @@ impl<'a> AuthenticatedContext<'a> {
Some(mb) => mb,
None => {
return Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message("Mailbox does not exist")
- .build()?,
+ .no()?,
flow::Transition::None,
))
}
};
tracing::info!(username=%self.user.username, mailbox=%name, "mailbox.selected");
- let (mb, data) = MailboxView::new(mb).await?;
+ let mb = MailboxView::new(mb).await;
+ let data = mb.summary()?;
Ok((
- Response::ok()
+ Response::build()
.message("Select completed")
.code(Code::ReadWrite)
- .data(data)
- .build()?,
+ .set_body(data)
+ .ok()?,
flow::Transition::Select(mb),
))
}
- async fn examine(self, mailbox: &MailboxCodec<'a>) -> Result<(Response, flow::Transition)> {
+ async fn examine(self, mailbox: &MailboxCodec<'a>) -> Result<(Response<'a>, flow::Transition)> {
let name: &str = MailboxName(mailbox).try_into()?;
let mb_opt = self.user.open_mailbox(&name).await?;
@@ -429,25 +438,26 @@ impl<'a> AuthenticatedContext<'a> {
Some(mb) => mb,
None => {
return Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message("Mailbox does not exist")
- .build()?,
+ .no()?,
flow::Transition::None,
))
}
};
tracing::info!(username=%self.user.username, mailbox=%name, "mailbox.examined");
- let (mb, data) = MailboxView::new(mb).await?;
+ let mb = MailboxView::new(mb).await;
+ let data = mb.summary()?;
Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("Examine completed")
.code(Code::ReadOnly)
- .data(data)
- .build()?,
+ .set_body(data)
+ .ok()?,
flow::Transition::Examine(mb),
))
}
@@ -458,24 +468,24 @@ impl<'a> AuthenticatedContext<'a> {
flags: &[Flag<'a>],
date: &Option<DateTime>,
message: &Literal<'a>,
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
let append_tag = self.req.tag.clone();
match self.append_internal(mailbox, flags, date, message).await {
Ok((_mb, uidvalidity, uid)) => Ok((
- Response::ok()
+ Response::build()
.tag(append_tag)
.message("APPEND completed")
.code(Code::Other(CodeOther::unvalidated(
format!("APPENDUID {} {}", uidvalidity, uid).into_bytes(),
)))
- .build()?,
+ .ok()?,
flow::Transition::None,
)),
Err(e) => Ok((
- Response::no()
+ Response::build()
.tag(append_tag)
.message(e.to_string())
- .build()?,
+ .no()?,
flow::Transition::None,
)),
}
diff --git a/src/imap/command/examined.rs b/src/imap/command/examined.rs
index cab3fdd..7f9c39c 100644
--- a/src/imap/command/examined.rs
+++ b/src/imap/command/examined.rs
@@ -19,7 +19,7 @@ pub struct ExaminedContext<'a> {
pub mailbox: &'a mut MailboxView,
}
-pub async fn dispatch(ctx: ExaminedContext<'_>) -> Result<(Response, flow::Transition)> {
+pub async fn dispatch<'a>(ctx: ExaminedContext<'a>) -> Result<(Response<'a>, flow::Transition)> {
match &ctx.req.body {
// Any State
// noop is specific to this state
@@ -41,10 +41,10 @@ pub async fn dispatch(ctx: ExaminedContext<'_>) -> Result<(Response, flow::Trans
} => ctx.search(charset, criteria, uid).await,
CommandBody::Noop | CommandBody::Check => ctx.noop().await,
CommandBody::Expunge { .. } | CommandBody::Store { .. } => Ok((
- Response::bad()
+ Response::build()
.to_req(ctx.req)
.message("Forbidden command: can't write in read-only mode (EXAMINE)")
- .build()?,
+ .bad()?,
flow::Transition::None,
)),
@@ -58,12 +58,12 @@ pub async fn dispatch(ctx: ExaminedContext<'_>) -> Result<(Response, flow::Trans
impl<'a> ExaminedContext<'a> {
/// CLOSE in examined state is not the same as in selected state
/// (in selected state it also does an EXPUNGE, here it doesn't)
- async fn close(self) -> Result<(Response, flow::Transition)> {
+ async fn close(self) -> Result<(Response<'a>, flow::Transition)> {
Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("CLOSE completed")
- .build()?,
+ .ok()?,
flow::Transition::Unselect,
))
}
@@ -71,23 +71,23 @@ impl<'a> ExaminedContext<'a> {
pub async fn fetch(
self,
sequence_set: &SequenceSet,
- attributes: &MacroOrMessageDataItemNames<'a>,
+ attributes: &'a MacroOrMessageDataItemNames<'a>,
uid: &bool,
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
match self.mailbox.fetch(sequence_set, attributes, uid).await {
Ok(resp) => Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("FETCH completed")
- .set_data(resp)
- .build()?,
+ .set_body(resp)
+ .ok()?,
flow::Transition::None,
)),
Err(e) => Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message(e.to_string())
- .build()?,
+ .no()?,
flow::Transition::None,
)),
}
@@ -98,26 +98,26 @@ impl<'a> ExaminedContext<'a> {
_charset: &Option<Charset<'a>>,
_criteria: &SearchKey<'a>,
_uid: &bool,
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
Ok((
- Response::bad()
+ Response::build()
.to_req(self.req)
.message("Not implemented")
- .build()?,
+ .bad()?,
flow::Transition::None,
))
}
- pub async fn noop(self) -> Result<(Response, flow::Transition)> {
+ pub async fn noop(self) -> Result<(Response<'a>, flow::Transition)> {
self.mailbox.mailbox.force_sync().await?;
let updates = self.mailbox.update().await?;
Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("NOOP completed.")
- .set_data(updates)
- .build()?,
+ .set_body(updates)
+ .ok()?,
flow::Transition::None,
))
}
diff --git a/src/imap/command/selected.rs b/src/imap/command/selected.rs
index 148901d..cd5d221 100644
--- a/src/imap/command/selected.rs
+++ b/src/imap/command/selected.rs
@@ -23,7 +23,7 @@ pub struct SelectedContext<'a> {
pub mailbox: &'a mut MailboxView,
}
-pub async fn dispatch(ctx: SelectedContext<'_>) -> Result<(Response, flow::Transition)> {
+pub async fn dispatch<'a>(ctx: SelectedContext<'a>) -> Result<(Response<'a>, flow::Transition)> {
match &ctx.req.body {
// Any State
// noop is specific to this state
@@ -65,13 +65,13 @@ pub async fn dispatch(ctx: SelectedContext<'_>) -> Result<(Response, flow::Trans
// --- PRIVATE ---
impl<'a> SelectedContext<'a> {
- async fn close(self) -> Result<(Response, flow::Transition)> {
+ async fn close(self) -> Result<(Response<'a>, flow::Transition)> {
// We expunge messages,
// but we don't send the untagged EXPUNGE responses
let tag = self.req.tag.clone();
self.expunge().await?;
Ok((
- Response::ok().tag(tag).message("CLOSE completed").build()?,
+ Response::build().tag(tag).message("CLOSE completed").ok()?,
flow::Transition::Unselect,
))
}
@@ -79,23 +79,23 @@ impl<'a> SelectedContext<'a> {
pub async fn fetch(
self,
sequence_set: &SequenceSet,
- attributes: &MacroOrMessageDataItemNames<'a>,
+ attributes: &'a MacroOrMessageDataItemNames<'a>,
uid: &bool,
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
match self.mailbox.fetch(sequence_set, attributes, uid).await {
Ok(resp) => Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("FETCH completed")
- .set_data(resp)
- .build()?,
+ .set_body(resp)
+ .ok()?,
flow::Transition::None,
)),
Err(e) => Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message(e.to_string())
- .build()?,
+ .no()?,
flow::Transition::None,
)),
}
@@ -106,40 +106,40 @@ impl<'a> SelectedContext<'a> {
_charset: &Option<Charset<'a>>,
_criteria: &SearchKey<'a>,
_uid: &bool,
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
Ok((
- Response::bad()
+ Response::build()
.to_req(self.req)
.message("Not implemented")
- .build()?,
+ .bad()?,
flow::Transition::None,
))
}
- pub async fn noop(self) -> Result<(Response, flow::Transition)> {
+ pub async fn noop(self) -> Result<(Response<'a>, flow::Transition)> {
self.mailbox.mailbox.force_sync().await?;
let updates = self.mailbox.update().await?;
Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("NOOP completed.")
- .set_data(updates)
- .build()?,
+ .set_body(updates)
+ .ok()?,
flow::Transition::None,
))
}
- async fn expunge(self) -> Result<(Response, flow::Transition)> {
+ async fn expunge(self) -> Result<(Response<'a>, flow::Transition)> {
let tag = self.req.tag.clone();
let data = self.mailbox.expunge().await?;
Ok((
- Response::ok()
+ Response::build()
.tag(tag)
.message("EXPUNGE completed")
- .data(data)
- .build()?,
+ .set_body(data)
+ .ok()?,
flow::Transition::None,
))
}
@@ -151,18 +151,18 @@ impl<'a> SelectedContext<'a> {
response: &StoreResponse,
flags: &[Flag<'a>],
uid: &bool,
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
let data = self
.mailbox
.store(sequence_set, kind, response, flags, uid)
.await?;
Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("STORE completed")
- .set_data(data)
- .build()?,
+ .set_body(data)
+ .ok()?,
flow::Transition::None,
))
}
@@ -172,7 +172,7 @@ impl<'a> SelectedContext<'a> {
sequence_set: &SequenceSet,
mailbox: &MailboxCodec<'a>,
uid: &bool,
- ) -> Result<(Response, flow::Transition)> {
+ ) -> Result<(Response<'a>, flow::Transition)> {
let name: &str = MailboxName(mailbox).try_into()?;
let mb_opt = self.user.open_mailbox(&name).await?;
@@ -180,11 +180,11 @@ impl<'a> SelectedContext<'a> {
Some(mb) => mb,
None => {
return Ok((
- Response::no()
+ Response::build()
.to_req(self.req)
.message("Destination mailbox does not exist")
.code(Code::TryCreate)
- .build()?,
+ .no()?,
flow::Transition::None,
))
}
@@ -208,13 +208,13 @@ impl<'a> SelectedContext<'a> {
);
Ok((
- Response::ok()
+ Response::build()
.to_req(self.req)
.message("COPY completed")
.code(Code::Other(CodeOther::unvalidated(
format!("COPYUID {}", copyuid_str).into_bytes(),
)))
- .build()?,
+ .ok()?,
flow::Transition::None,
))
}