diff --git a/Cargo.lock b/Cargo.lock index 2c264f2..f8d3bf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1807,7 +1807,6 @@ dependencies = [ [[package]] name = "imap-codec" version = "1.0.0" -source = "git+https://github.com/duesee/imap-codec?branch=v2#1f490146bb6197eee6032205e3aa7f297efd9b39" dependencies = [ "abnf-core", "base64 0.21.5", @@ -1834,7 +1833,6 @@ dependencies = [ [[package]] name = "imap-types" version = "1.0.0" -source = "git+https://github.com/duesee/imap-codec?branch=v2#1f490146bb6197eee6032205e3aa7f297efd9b39" dependencies = [ "base64 0.21.5", "bounded-static", diff --git a/Cargo.toml b/Cargo.toml index 68a46e3..1e8cc16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,8 +64,10 @@ imap-flow = { git = "https://github.com/duesee/imap-flow.git", rev = "e45ce7bb6a [dev-dependencies] [patch.crates-io] -imap-types = { git = "https://github.com/duesee/imap-codec", branch = "v2" } -imap-codec = { git = "https://github.com/duesee/imap-codec", branch = "v2" } +#imap-types = { git = "https://github.com/duesee/imap-codec", branch = "v2" } +#imap-codec = { git = "https://github.com/duesee/imap-codec", branch = "v2" } +imap-types = { path = "../../imap-codec/imap-types" } +imap-codec = { path = "../../imap-codec/imap-codec" } [[test]] name = "behavior" diff --git a/src/imap/capability.rs b/src/imap/capability.rs index d88673c..be1d4b6 100644 --- a/src/imap/capability.rs +++ b/src/imap/capability.rs @@ -1,4 +1,4 @@ -use imap_codec::imap_types::core::NonEmptyVec; +use imap_codec::imap_types::core::{Atom, NonEmptyVec}; use imap_codec::imap_types::extensions::enable::{CapabilityEnable, Utf8Kind}; use imap_codec::imap_types::response::Capability; use std::collections::HashSet; @@ -48,6 +48,7 @@ impl ServerCapability { } } +#[derive(Clone)] pub enum ClientStatus { NotSupportedByServer, Disabled, @@ -57,6 +58,13 @@ impl ClientStatus { pub fn is_enabled(&self) -> bool { matches!(self, Self::Enabled) } + + pub fn enable(&self) -> Self { + match self { + Self::Disabled => Self::Enabled, + other => other.clone(), + } + } } @@ -76,6 +84,14 @@ impl ClientCapability { } } + pub fn select_enable(&mut self, atoms: &[Atom]) { + for at in atoms.iter() { + if at.as_ref().to_uppercase() == "CONDSTORE" { + self.condstore = self.condstore.enable(); + } + } + } + pub fn try_enable( &mut self, caps: &[CapabilityEnable<'static>], diff --git a/src/imap/command/authenticated.rs b/src/imap/command/authenticated.rs index 954e758..5af8e98 100644 --- a/src/imap/command/authenticated.rs +++ b/src/imap/command/authenticated.rs @@ -58,8 +58,8 @@ pub async fn dispatch<'a>( } => ctx.status(mailbox, item_names).await, CommandBody::Subscribe { mailbox } => ctx.subscribe(mailbox).await, CommandBody::Unsubscribe { mailbox } => ctx.unsubscribe(mailbox).await, - CommandBody::Select { mailbox } => ctx.select(mailbox).await, - CommandBody::Examine { mailbox } => ctx.examine(mailbox).await, + CommandBody::Select { mailbox, parameters } => ctx.select(mailbox, parameters).await, + CommandBody::Examine { mailbox, parameters } => ctx.examine(mailbox, parameters).await, CommandBody::Append { mailbox, flags, @@ -421,7 +421,12 @@ impl<'a> AuthenticatedContext<'a> { async fn select( self, mailbox: &MailboxCodec<'a>, + parameters: &Option>>, ) -> Result<(Response<'static>, flow::Transition)> { + parameters.as_ref().map(|plist| + self.client_capabilities.select_enable(plist.as_ref()) + ); + let name: &str = MailboxName(mailbox).try_into()?; let mb_opt = self.user.open_mailbox(&name).await?; @@ -456,7 +461,12 @@ impl<'a> AuthenticatedContext<'a> { async fn examine( self, mailbox: &MailboxCodec<'a>, + parameters: &Option>>, ) -> Result<(Response<'static>, flow::Transition)> { + parameters.as_ref().map(|plist| + self.client_capabilities.select_enable(plist.as_ref()) + ); + let name: &str = MailboxName(mailbox).try_into()?; let mb_opt = self.user.open_mailbox(&name).await?;