diff --git a/Cargo.toml b/Cargo.toml index a0b23cb..adb39f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ path = "src/lib.rs" native-tls = "0.2.2" regex = "1.0" bufstream = "0.1" -imap-proto = "0.7" +imap-proto = "0.8" nom = "4.0" base64 = "0.10" chrono = "0.4" diff --git a/src/client.rs b/src/client.rs index 5540f4e..5aeb99b 100644 --- a/src/client.rs +++ b/src/client.rs @@ -14,7 +14,7 @@ use super::extensions; use super::parse::*; use super::types::*; -static TAG_PREFIX: &'static str = "a"; +static TAG_PREFIX: &str = "a"; const INITIAL_TAG: u32 = 0; const CR: u8 = 0x0d; const LF: u8 = 0x0a; @@ -1620,7 +1620,7 @@ mod tests { ); assert_eq!(capabilities.len(), 4); for e in expected_capabilities { - assert!(capabilities.has(e)); + assert!(capabilities.has_str(e)); } } diff --git a/src/error.rs b/src/error.rs index 6891406..ef89939 100644 --- a/src/error.rs +++ b/src/error.rs @@ -106,7 +106,7 @@ impl StdError for Error { } } - fn cause(&self) -> Option<&StdError> { + fn cause(&self) -> Option<&dyn StdError> { match *self { Error::Io(ref e) => Some(e), Error::Tls(ref e) => Some(e), @@ -148,7 +148,7 @@ impl StdError for ParseError { } } - fn cause(&self) -> Option<&StdError> { + fn cause(&self) -> Option<&dyn StdError> { match *self { ParseError::Authentication(_, Some(ref e)) => Some(e), _ => None, @@ -173,7 +173,7 @@ impl StdError for ValidateError { "Invalid character in input" } - fn cause(&self) -> Option<&StdError> { + fn cause(&self) -> Option<&dyn StdError> { None } } diff --git a/src/parse.rs b/src/parse.rs index 8b32c17..a2de763 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -342,7 +342,7 @@ mod tests { assert!(recv.try_recv().is_err()); assert_eq!(capabilities.len(), 4); for e in expected_capabilities { - assert!(capabilities.has(e)); + assert!(capabilities.has_str(e)); } } @@ -445,7 +445,7 @@ mod tests { assert_eq!(capabilities.len(), 4); for e in expected_capabilities { - assert!(capabilities.has(e)); + assert!(capabilities.has_str(e)); } assert_eq!( diff --git a/src/types/capabilities.rs b/src/types/capabilities.rs index 166bfa8..2cc3672 100644 --- a/src/types/capabilities.rs +++ b/src/types/capabilities.rs @@ -1,7 +1,9 @@ -use std::borrow::Borrow; +use imap_proto::types::Capability; use std::collections::hash_set::Iter; use std::collections::HashSet; -use std::hash::Hash; + +const IMAP4REV1_CAPABILITY: &str = "IMAP4rev1"; +const AUTH_CAPABILITY_PREFIX: &str = "AUTH="; /// From [section 7.2.1 of RFC 3501](https://tools.ietf.org/html/rfc3501#section-7.2.1). /// @@ -31,21 +33,29 @@ use std::hash::Hash; pub struct Capabilities( // Note that this field isn't *actually* 'static. // Rather, it is tied to the lifetime of the `ZeroCopy` that contains this `Name`. - pub(crate) HashSet<&'static str>, + pub(crate) HashSet>, ); impl Capabilities { /// Check if the server has the given capability. - pub fn has(&self, s: &S) -> bool - where - for<'a> &'a str: Borrow, - S: Hash + Eq, - { - self.0.contains(s) + pub fn has<'a>(&self, cap: &Capability<'a>) -> bool { + self.0.contains(cap) + } + + /// Check if the server has the given capability via str. + pub fn has_str>(&self, cap: S) -> bool { + let s = cap.as_ref(); + if s == IMAP4REV1_CAPABILITY { + self.has(&Capability::Imap4rev1) + } else if s.starts_with(AUTH_CAPABILITY_PREFIX) { + self.has(&Capability::Auth(&s[AUTH_CAPABILITY_PREFIX.len()..])) + } else { + self.has(&Capability::Atom(s)) + } } /// Iterate over all the server's capabilities - pub fn iter(&self) -> Iter<&str> { + pub fn iter(&self) -> Iter { self.0.iter() }