Implement RFC822.TEXT

This commit is contained in:
Quentin 2022-06-30 13:36:21 +02:00
parent 69428eaf25
commit 0f0a8d415e
Signed by: quentin
GPG Key ID: E9602264D639FF68
6 changed files with 62 additions and 31 deletions

View File

@ -19,7 +19,10 @@ pub async fn dispatch<'a>(ctx: AuthenticatedContext<'a>) -> Result<(Response, fl
match &ctx.req.command.body {
CommandBody::Create { mailbox } => ctx.create(mailbox).await,
CommandBody::Delete { mailbox } => ctx.delete(mailbox).await,
CommandBody::Rename { mailbox, new_mailbox } => ctx.rename(mailbox, new_mailbox).await,
CommandBody::Rename {
mailbox,
new_mailbox,
} => ctx.rename(mailbox, new_mailbox).await,
CommandBody::Lsub {
reference,
mailbox_wildcard,
@ -28,8 +31,10 @@ pub async fn dispatch<'a>(ctx: AuthenticatedContext<'a>) -> Result<(Response, fl
reference,
mailbox_wildcard,
} => ctx.list(reference, mailbox_wildcard).await,
CommandBody::Status { mailbox, attributes } =>
ctx.status(mailbox, attributes).await,
CommandBody::Status {
mailbox,
attributes,
} => ctx.status(mailbox, attributes).await,
CommandBody::Select { mailbox } => ctx.select(mailbox).await,
CommandBody::Examine { mailbox } => ctx.examine(mailbox).await,
_ => {
@ -53,7 +58,11 @@ impl<'a> AuthenticatedContext<'a> {
Ok((Response::bad("Not implemented")?, flow::Transition::None))
}
async fn rename(self, mailbox: &MailboxCodec, new_mailbox: &MailboxCodec) -> Result<(Response, flow::Transition)> {
async fn rename(
self,
mailbox: &MailboxCodec,
new_mailbox: &MailboxCodec,
) -> Result<(Response, flow::Transition)> {
Ok((Response::bad("Not implemented")?, flow::Transition::None))
}

View File

@ -48,9 +48,7 @@ pub async fn dispatch<'a>(ctx: ExaminedContext<'a>) -> Result<(Response, flow::T
// --- PRIVATE ---
impl<'a> ExaminedContext<'a> {
async fn close(
self,
) -> Result<(Response, flow::Transition)> {
async fn close(self) -> Result<(Response, flow::Transition)> {
Ok((Response::ok("CLOSE completed")?, flow::Transition::Unselect))
}

View File

@ -1,4 +1,4 @@
pub mod anonymous;
pub mod authenticated;
pub mod selected;
pub mod examined;
pub mod selected;

View File

@ -2,9 +2,9 @@ use anyhow::Result;
use boitalettres::proto::Request;
use boitalettres::proto::Response;
use imap_codec::types::command::CommandBody;
use imap_codec::types::mailbox::{Mailbox as MailboxCodec};
use imap_codec::types::flag::{Flag, StoreType, StoreResponse};
use imap_codec::types::fetch_attributes::MacroOrFetchAttributes;
use imap_codec::types::flag::{Flag, StoreResponse, StoreType};
use imap_codec::types::mailbox::Mailbox as MailboxCodec;
use imap_codec::types::sequence::SequenceSet;
@ -27,11 +27,11 @@ pub async fn dispatch<'a>(ctx: SelectedContext<'a>) -> Result<(Response, flow::T
CommandBody::Close => ctx.close().await,
CommandBody::Expunge => ctx.expunge().await,
CommandBody::Store {
sequence_set,
kind,
response,
flags,
uid
sequence_set,
kind,
response,
flags,
uid,
} => ctx.store(sequence_set, kind, response, flags, uid).await,
CommandBody::Copy {
sequence_set,
@ -52,18 +52,14 @@ pub async fn dispatch<'a>(ctx: SelectedContext<'a>) -> Result<(Response, flow::T
// --- PRIVATE ---
impl<'a> SelectedContext<'a> {
async fn close(
self,
) -> Result<(Response, flow::Transition)> {
async fn close(self) -> Result<(Response, flow::Transition)> {
// We expunge messages,
// but we don't send the untagged EXPUNGE responses
self.expunge().await?;
Ok((Response::ok("CLOSE completed")?, flow::Transition::Unselect))
}
async fn expunge(
self,
) -> Result<(Response, flow::Transition)> {
async fn expunge(self) -> Result<(Response, flow::Transition)> {
Ok((Response::bad("Not implemented")?, flow::Transition::None))
}

View File

@ -6,7 +6,7 @@ use anyhow::{anyhow, bail, Error, Result};
use boitalettres::proto::res::body::Data as Body;
use futures::stream::{FuturesOrdered, StreamExt};
use imap_codec::types::address::Address;
use imap_codec::types::core::{Atom, IString, NString};
use imap_codec::types::core::{Atom, IString, NString, NonZeroBytes};
use imap_codec::types::envelope::Envelope;
use imap_codec::types::fetch_attributes::{FetchAttribute, MacroOrFetchAttributes};
use imap_codec::types::flag::Flag;
@ -247,21 +247,49 @@ impl MailboxView {
FetchAttribute::Rfc822Size => {
attributes.push(MessageAttribute::Rfc822Size(meta.rfc822_size as u32))
}
FetchAttribute::Rfc822Header => {
attributes.push(MessageAttribute::Rfc822Header(NString(Some(
IString::Literal(meta.headers.clone().try_into().unwrap()),
FetchAttribute::Rfc822Header => attributes.push(
MessageAttribute::Rfc822Header(NString(Some(IString::Literal(
meta.headers
.clone()
.try_into()
.or(Err(Error::msg("IString conversion error")))?,
)))),
),
FetchAttribute::Rfc822Text => {
let r = parsed
.raw_message.get(parsed.offset_body..parsed.offset_end)
.ok_or(Error::msg("Unable to extract email body, cursors out of bound. This is a bug."))?
.try_into()
.or(Err(Error::msg("IString conversion error")))?;
attributes.push(MessageAttribute::Rfc822Text(NString(Some(
IString::Literal(r),
))))
}
FetchAttribute::Rfc822 => {
attributes.push(MessageAttribute::Rfc822(NString(Some(
IString::Literal(body.as_ref().unwrap().clone().try_into().unwrap()),
))))
attributes.push(MessageAttribute::Rfc822(NString(Some(IString::Literal(
body.as_ref().unwrap().clone().try_into().unwrap(),
)))))
}
FetchAttribute::Envelope => {
attributes.push(MessageAttribute::Envelope(message_envelope(&parsed)))
}
// TODO
_ => (),
FetchAttribute::Body => {
todo!()
}
FetchAttribute::BodyExt {
section,
partial,
peek,
} => {
todo!()
}
FetchAttribute::BodyStructure => {
todo!()
}
FetchAttribute::InternalDate => {
todo!()
}
}
}

View File

@ -7,7 +7,7 @@ use futures::future::FutureExt;
use tokio::sync::mpsc::error::TrySendError;
use tokio::sync::{mpsc, oneshot};
use crate::imap::command::{anonymous, authenticated, selected, examined};
use crate::imap::command::{anonymous, authenticated, examined, selected};
use crate::imap::flow;
use crate::login::ArcLoginProvider;