Merge pull request #133 from avitex/master

Capability enum changes from imap-proto
This commit is contained in:
Jon Gjengset 2019-09-02 10:39:24 -04:00 committed by GitHub
commit 31e2490d22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 18 deletions

View file

@ -29,7 +29,7 @@ path = "src/lib.rs"
native-tls = "0.2.2" native-tls = "0.2.2"
regex = "1.0" regex = "1.0"
bufstream = "0.1" bufstream = "0.1"
imap-proto = "0.7" imap-proto = "0.8"
nom = "4.0" nom = "4.0"
base64 = "0.10" base64 = "0.10"
chrono = "0.4" chrono = "0.4"

View file

@ -14,7 +14,7 @@ use super::extensions;
use super::parse::*; use super::parse::*;
use super::types::*; use super::types::*;
static TAG_PREFIX: &'static str = "a"; static TAG_PREFIX: &str = "a";
const INITIAL_TAG: u32 = 0; const INITIAL_TAG: u32 = 0;
const CR: u8 = 0x0d; const CR: u8 = 0x0d;
const LF: u8 = 0x0a; const LF: u8 = 0x0a;
@ -1620,7 +1620,7 @@ mod tests {
); );
assert_eq!(capabilities.len(), 4); assert_eq!(capabilities.len(), 4);
for e in expected_capabilities { for e in expected_capabilities {
assert!(capabilities.has(e)); assert!(capabilities.has_str(e));
} }
} }

View file

@ -106,7 +106,7 @@ impl StdError for Error {
} }
} }
fn cause(&self) -> Option<&StdError> { fn cause(&self) -> Option<&dyn StdError> {
match *self { match *self {
Error::Io(ref e) => Some(e), Error::Io(ref e) => Some(e),
Error::Tls(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 { match *self {
ParseError::Authentication(_, Some(ref e)) => Some(e), ParseError::Authentication(_, Some(ref e)) => Some(e),
_ => None, _ => None,
@ -173,7 +173,7 @@ impl StdError for ValidateError {
"Invalid character in input" "Invalid character in input"
} }
fn cause(&self) -> Option<&StdError> { fn cause(&self) -> Option<&dyn StdError> {
None None
} }
} }

View file

@ -342,7 +342,7 @@ mod tests {
assert!(recv.try_recv().is_err()); assert!(recv.try_recv().is_err());
assert_eq!(capabilities.len(), 4); assert_eq!(capabilities.len(), 4);
for e in expected_capabilities { 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); assert_eq!(capabilities.len(), 4);
for e in expected_capabilities { for e in expected_capabilities {
assert!(capabilities.has(e)); assert!(capabilities.has_str(e));
} }
assert_eq!( assert_eq!(

View file

@ -1,7 +1,9 @@
use std::borrow::Borrow; use imap_proto::types::Capability;
use std::collections::hash_set::Iter; use std::collections::hash_set::Iter;
use std::collections::HashSet; 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). /// 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( pub struct Capabilities(
// Note that this field isn't *actually* 'static. // Note that this field isn't *actually* 'static.
// Rather, it is tied to the lifetime of the `ZeroCopy` that contains this `Name`. // Rather, it is tied to the lifetime of the `ZeroCopy` that contains this `Name`.
pub(crate) HashSet<&'static str>, pub(crate) HashSet<Capability<'static>>,
); );
impl Capabilities { impl Capabilities {
/// Check if the server has the given capability. /// Check if the server has the given capability.
pub fn has<S: ?Sized>(&self, s: &S) -> bool pub fn has<'a>(&self, cap: &Capability<'a>) -> bool {
where self.0.contains(cap)
for<'a> &'a str: Borrow<S>, }
S: Hash + Eq,
{ /// Check if the server has the given capability via str.
self.0.contains(s) pub fn has_str<S: AsRef<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 /// Iterate over all the server's capabilities
pub fn iter(&self) -> Iter<&str> { pub fn iter(&self) -> Iter<Capability> {
self.0.iter() self.0.iter()
} }