diff options
author | Quentin <quentin@dufour.io> | 2024-01-04 11:11:01 +0000 |
---|---|---|
committer | Quentin <quentin@dufour.io> | 2024-01-04 11:11:01 +0000 |
commit | bcf6de83419b405fea95b740869f98d43586ea7c (patch) | |
tree | 9f52832b90685913beda8f1bf19a22b2ec7bc6c6 /src/imap/capability.rs | |
parent | b9a0c1e6eced036eb71e8221a4f236f72832fec2 (diff) | |
parent | 7ae9966675c85b34f1a99d81062b44b74385a15b (diff) | |
download | aerogramme-bcf6de83419b405fea95b740869f98d43586ea7c.tar.gz aerogramme-bcf6de83419b405fea95b740869f98d43586ea7c.zip |
Merge pull request 'Implement some IMAP extensions' (#50) from feat/more-ext into main
Reviewed-on: https://git.deuxfleurs.fr/Deuxfleurs/aerogramme/pulls/50
Diffstat (limited to 'src/imap/capability.rs')
-rw-r--r-- | src/imap/capability.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/imap/capability.rs b/src/imap/capability.rs new file mode 100644 index 0000000..631c3e2 --- /dev/null +++ b/src/imap/capability.rs @@ -0,0 +1,93 @@ +use imap_codec::imap_types::core::NonEmptyVec; +use imap_codec::imap_types::extensions::enable::{CapabilityEnable, Utf8Kind}; +use imap_codec::imap_types::response::Capability; +use std::collections::HashSet; + +fn capability_unselect() -> Capability<'static> { + Capability::try_from("UNSELECT").unwrap() +} + +fn capability_condstore() -> Capability<'static> { + Capability::try_from("CONDSTORE").unwrap() +} + +fn capability_qresync() -> Capability<'static> { + Capability::try_from("QRESYNC").unwrap() +} + +#[derive(Debug, Clone)] +pub struct ServerCapability(HashSet<Capability<'static>>); + +impl Default for ServerCapability { + fn default() -> Self { + Self(HashSet::from([ + Capability::Imap4Rev1, + Capability::Move, + Capability::LiteralPlus, + capability_unselect(), + //capability_condstore(), + //capability_qresync(), + ])) + } +} + +impl ServerCapability { + pub fn to_vec(&self) -> NonEmptyVec<Capability<'static>> { + self.0 + .iter() + .map(|v| v.clone()) + .collect::<Vec<_>>() + .try_into() + .unwrap() + } + + #[allow(dead_code)] + pub fn support(&self, cap: &Capability<'static>) -> bool { + self.0.contains(cap) + } +} + +enum ClientStatus { + NotSupportedByServer, + Disabled, + Enabled, +} + +pub struct ClientCapability { + condstore: ClientStatus, + utf8kind: Option<Utf8Kind>, +} + +impl ClientCapability { + pub fn new(sc: &ServerCapability) -> Self { + Self { + condstore: match sc.0.contains(&capability_condstore()) { + true => ClientStatus::Disabled, + _ => ClientStatus::NotSupportedByServer, + }, + utf8kind: None, + } + } + + pub fn try_enable( + &mut self, + caps: &[CapabilityEnable<'static>], + ) -> Vec<CapabilityEnable<'static>> { + let mut enabled = vec![]; + for cap in caps { + match cap { + CapabilityEnable::CondStore if matches!(self.condstore, ClientStatus::Disabled) => { + self.condstore = ClientStatus::Enabled; + enabled.push(cap.clone()); + } + CapabilityEnable::Utf8(kind) if Some(kind) != self.utf8kind.as_ref() => { + self.utf8kind = Some(kind.clone()); + enabled.push(cap.clone()); + } + _ => (), + } + } + + enabled + } +} |