Merge pull request #225 from CrispinStichart/add-gmail-labels
Add support for Gmail Labels
This commit is contained in:
commit
0217125962
5 changed files with 18 additions and 85 deletions
|
|
@ -22,7 +22,7 @@ native-tls = { version = "0.2.2", optional = true }
|
|||
rustls-connector = { version = "0.16.1", optional = true }
|
||||
regex = "1.0"
|
||||
bufstream = "0.1.3"
|
||||
imap-proto = "0.15.0"
|
||||
imap-proto = "0.16.0"
|
||||
nom = { version = "7.1.0", default-features = false }
|
||||
base64 = "0.13"
|
||||
chrono = { version = "0.4", default-features = false, features = ["std"]}
|
||||
|
|
|
|||
|
|
@ -417,7 +417,7 @@ mod tests {
|
|||
let first = names.get(0).unwrap();
|
||||
assert_eq!(
|
||||
first.attributes(),
|
||||
&[NameAttribute::from("\\HasNoChildren")]
|
||||
&[NameAttribute::Extension(Cow::Borrowed("\\HasNoChildren"))]
|
||||
);
|
||||
assert_eq!(first.delimiter(), Some("."));
|
||||
assert_eq!(first.name(), "INBOX");
|
||||
|
|
@ -507,7 +507,7 @@ mod tests {
|
|||
let first = names.get(0).unwrap();
|
||||
assert_eq!(
|
||||
first.attributes(),
|
||||
&[NameAttribute::from("\\HasNoChildren")]
|
||||
&[NameAttribute::Extension(Cow::Borrowed("\\HasNoChildren"))]
|
||||
);
|
||||
assert_eq!(first.delimiter(), Some("."));
|
||||
assert_eq!(first.name(), "INBOX");
|
||||
|
|
|
|||
|
|
@ -219,6 +219,17 @@ impl<'a> Fetch<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Extract the `X-GM-LABELS` of a `FETCH` response
|
||||
///
|
||||
/// This is a Gmail-specific extension. See their
|
||||
/// [developer's page](https://developers.google.com/gmail/imap/imap-extensions) for details.
|
||||
pub fn gmail_labels(&'a self) -> Option<impl Iterator<Item = &'a str>> {
|
||||
self.fetch.iter().find_map(|av| match av {
|
||||
AttributeValue::GmailLabels(labels) => Some(labels.iter().map(|cow| cow.as_ref())),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Get an owned copy of the [`Fetch`].
|
||||
pub fn into_owned(self) -> Fetch<'static> {
|
||||
Fetch {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ mod mailbox;
|
|||
pub use self::mailbox::Mailbox;
|
||||
|
||||
mod name;
|
||||
pub use self::name::{Name, NameAttribute, Names};
|
||||
pub use self::name::{Name, Names};
|
||||
|
||||
mod capabilities;
|
||||
pub use self::capabilities::Capabilities;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::error::Error;
|
||||
use crate::parse::{parse_many_into, MapOrNot};
|
||||
use crate::types::UnsolicitedResponse;
|
||||
use imap_proto::{MailboxDatum, Response};
|
||||
use imap_proto::{MailboxDatum, NameAttribute, Response};
|
||||
use ouroboros::self_referencing;
|
||||
use std::borrow::Cow;
|
||||
use std::slice::Iter;
|
||||
|
|
@ -28,11 +28,11 @@ impl Names {
|
|||
let mut names = Vec::new();
|
||||
parse_many_into(input, &mut names, unsolicited, |response| match response {
|
||||
Response::MailboxData(MailboxDatum::List {
|
||||
flags,
|
||||
name_attributes,
|
||||
delimiter,
|
||||
name,
|
||||
}) => Ok(MapOrNot::Map(Name {
|
||||
attributes: flags.into_iter().map(NameAttribute::from).collect(),
|
||||
attributes: name_attributes,
|
||||
delimiter,
|
||||
name,
|
||||
})),
|
||||
|
|
@ -73,84 +73,6 @@ pub struct Name<'a> {
|
|||
pub(crate) name: Cow<'a, str>,
|
||||
}
|
||||
|
||||
/// An attribute set for an IMAP name.
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub enum NameAttribute<'a> {
|
||||
/// It is not possible for any child levels of hierarchy to exist
|
||||
/// under this name; no child levels exist now and none can be
|
||||
/// created in the future.
|
||||
NoInferiors,
|
||||
|
||||
/// It is not possible to use this name as a selectable mailbox.
|
||||
NoSelect,
|
||||
|
||||
/// The mailbox has been marked "interesting" by the server; the
|
||||
/// mailbox probably contains messages that have been added since
|
||||
/// the last time the mailbox was selected.
|
||||
Marked,
|
||||
|
||||
/// The mailbox does not contain any additional messages since the
|
||||
/// last time the mailbox was selected.
|
||||
Unmarked,
|
||||
|
||||
/// A non-standard user- or server-defined name attribute.
|
||||
Custom(Cow<'a, str>),
|
||||
}
|
||||
|
||||
impl NameAttribute<'static> {
|
||||
fn system(s: &str) -> Option<Self> {
|
||||
match s {
|
||||
"\\Noinferiors" => Some(NameAttribute::NoInferiors),
|
||||
"\\Noselect" => Some(NameAttribute::NoSelect),
|
||||
"\\Marked" => Some(NameAttribute::Marked),
|
||||
"\\Unmarked" => Some(NameAttribute::Unmarked),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> NameAttribute<'a> {
|
||||
fn into_owned(self) -> NameAttribute<'static> {
|
||||
match self {
|
||||
NameAttribute::NoInferiors => NameAttribute::NoInferiors,
|
||||
NameAttribute::NoSelect => NameAttribute::NoSelect,
|
||||
NameAttribute::Marked => NameAttribute::Marked,
|
||||
NameAttribute::Unmarked => NameAttribute::Unmarked,
|
||||
NameAttribute::Custom(cow) => NameAttribute::Custom(Cow::Owned(cow.into_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<String> for NameAttribute<'a> {
|
||||
fn from(s: String) -> Self {
|
||||
if let Some(f) = NameAttribute::system(&s) {
|
||||
f
|
||||
} else {
|
||||
NameAttribute::Custom(Cow::Owned(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<Cow<'a, str>> for NameAttribute<'a> {
|
||||
fn from(s: Cow<'a, str>) -> Self {
|
||||
if let Some(f) = NameAttribute::system(&*s) {
|
||||
f
|
||||
} else {
|
||||
NameAttribute::Custom(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for NameAttribute<'a> {
|
||||
fn from(s: &'a str) -> Self {
|
||||
if let Some(f) = NameAttribute::system(s) {
|
||||
f
|
||||
} else {
|
||||
NameAttribute::Custom(Cow::Borrowed(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Name<'a> {
|
||||
/// Attributes of this name.
|
||||
pub fn attributes(&self) -> &[NameAttribute<'a>] {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue