diff options
Diffstat (limited to 'src/imap/session.rs')
-rw-r--r-- | src/imap/session.rs | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/src/imap/session.rs b/src/imap/session.rs index 6b26478..d86e6ff 100644 --- a/src/imap/session.rs +++ b/src/imap/session.rs @@ -1,7 +1,9 @@ +use anyhow::anyhow; use crate::imap::capability::{ClientCapability, ServerCapability}; use crate::imap::command::{anonymous, authenticated, examined, selected}; use crate::imap::flow; -use crate::imap::response::Response; +use crate::imap::request::Request; +use crate::imap::response::{Response, ResponseOrIdle}; use crate::login::ArcLoginProvider; use imap_codec::imap_types::command::Command; @@ -23,7 +25,24 @@ impl Instance { } } - pub async fn command(&mut self, cmd: Command<'static>) -> Response<'static> { + pub async fn request(&mut self, req: Request) -> ResponseOrIdle { + match req { + Request::IdleUntil(stop) => ResponseOrIdle::Response(self.idle(stop).await), + Request::ImapCommand(cmd) => self.command(cmd).await, + } + } + + pub async fn idle(&mut self, stop: tokio::sync::Notify) -> Response<'static> { + let (user, mbx) = match &mut self.state { + flow::State::Idle(ref user, ref mut mailbox, ref perm) => (user, mailbox), + _ => unreachable!(), + }; + + unimplemented!(); + } + + + pub async fn command(&mut self, cmd: Command<'static>) -> ResponseOrIdle { // Command behavior is modulated by the state. // To prevent state error, we handle the same command in separate code paths. let (resp, tr) = match &mut self.state { @@ -44,26 +63,18 @@ impl Instance { }; authenticated::dispatch(ctx).await } - flow::State::Selected(ref user, ref mut mailbox) => { + flow::State::Selected(ref user, ref mut mailbox, ref perm) => { let ctx = selected::SelectedContext { req: &cmd, server_capabilities: &self.server_capabilities, client_capabilities: &mut self.client_capabilities, user, mailbox, + perm, }; selected::dispatch(ctx).await } - flow::State::Examined(ref user, ref mut mailbox) => { - let ctx = examined::ExaminedContext { - req: &cmd, - server_capabilities: &self.server_capabilities, - client_capabilities: &mut self.client_capabilities, - user, - mailbox, - }; - examined::dispatch(ctx).await - } + flow::State::Idle(..) => Err(anyhow!("can not receive command while idling")), flow::State::Logout => Response::build() .tag(cmd.tag.clone()) .message("No commands are allowed in the LOGOUT state.") @@ -88,15 +99,18 @@ impl Instance { e, cmd ); - return Response::build() + return ResponseOrIdle::Response(Response::build() .to_req(&cmd) .message( "Internal error, processing command triggered an illegal IMAP state transition", ) .bad() - .unwrap(); + .unwrap()); } - resp + match self.state { + flow::State::Idle(..) => ResponseOrIdle::Idle, + _ => ResponseOrIdle::Response(resp), + } } } |