melib: clippy lint fixes
parent
6858ee1fab
commit
5f29faa640
20
Makefile
20
Makefile
|
@ -18,6 +18,12 @@
|
|||
# along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
.POSIX:
|
||||
.SUFFIXES:
|
||||
CARGO_TARGET_DIR ?= target
|
||||
MIN_RUSTC ?= 1.65.0
|
||||
CARGO_BIN ?= cargo
|
||||
CARGO_ARGS ?=
|
||||
CARGO_SORT_BIN = cargo-sort
|
||||
PRINTF = /usr/bin/printf
|
||||
|
||||
# Options
|
||||
PREFIX ?= /usr/local
|
||||
|
@ -25,11 +31,6 @@ EXPANDED_PREFIX := `cd ${PREFIX} && pwd -P`
|
|||
BINDIR ?= ${EXPANDED_PREFIX}/bin
|
||||
MANDIR ?= ${EXPANDED_PREFIX}/share/man
|
||||
|
||||
CARGO_TARGET_DIR ?= target
|
||||
MIN_RUSTC ?= 1.39.0
|
||||
CARGO_BIN ?= cargo
|
||||
CARGO_ARGS ?=
|
||||
|
||||
# Installation parameters
|
||||
DOCS_SUBDIR ?= docs/
|
||||
MANPAGES ?= meli.1 meli.conf.5 meli-themes.5
|
||||
|
@ -96,6 +97,15 @@ help:
|
|||
check:
|
||||
@${CARGO_BIN} check ${CARGO_ARGS} ${CARGO_COLOR}--target-dir="${CARGO_TARGET_DIR}" ${FEATURES} --all --tests --examples --benches --bins
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
@$(CARGO_BIN) +nightly fmt --all || $(CARGO_BIN) fmt --all
|
||||
@OUT=$$($(CARGO_SORT_BIN) -w 2>&1) || $(PRINTF) "WARN: %s cargo-sort failed or binary not found in PATH.\n" "$$OUT"
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
@$(CARGO_BIN) clippy --no-deps --all-features --all --tests --examples --benches --bins
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
@${CARGO_BIN} test ${CARGO_ARGS} ${CARGO_COLOR}--target-dir="${CARGO_TARGET_DIR}" --all --tests --examples --benches --bins
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#![allow(clippy::needless_range_loop)]
|
||||
|
||||
#[cfg(feature = "unicode_algorithms")]
|
||||
include!("src/text_processing/types.rs");
|
||||
|
||||
|
|
|
@ -41,22 +41,37 @@ pub enum CardId {
|
|||
Hash(u64),
|
||||
}
|
||||
|
||||
impl Into<String> for CardId {
|
||||
fn into(self) -> String {
|
||||
impl std::fmt::Display for CardId {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
CardId::Uuid(u) => u.to_string(),
|
||||
CardId::Hash(u) => u.to_string(),
|
||||
Self::Uuid(u) => u.as_hyphenated().fmt(fmt),
|
||||
Self::Hash(u) => u.fmt(fmt),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CardId> for String {
|
||||
fn from(val: CardId) -> Self {
|
||||
val.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for CardId {
|
||||
fn from(s: String) -> CardId {
|
||||
if let Ok(u) = uuid::Uuid::parse_str(s.as_str()) {
|
||||
CardId::Uuid(u)
|
||||
fn from(s: String) -> Self {
|
||||
use std::{
|
||||
collections::hash_map::DefaultHasher,
|
||||
hash::{Hash, Hasher},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
if let Ok(u) = Uuid::parse_str(s.as_str()) {
|
||||
Self::Uuid(u)
|
||||
} else if let Ok(num) = u64::from_str(s.trim()) {
|
||||
Self::Hash(num)
|
||||
} else {
|
||||
use std::str::FromStr;
|
||||
CardId::Hash(u64::from_str(&s).unwrap())
|
||||
let mut hasher = DefaultHasher::default();
|
||||
s.hash(&mut hasher);
|
||||
Self::Hash(hasher.finish())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,8 +108,8 @@ pub struct Card {
|
|||
}
|
||||
|
||||
impl AddressBook {
|
||||
pub fn new(display_name: String) -> AddressBook {
|
||||
AddressBook {
|
||||
pub fn new(display_name: String) -> Self {
|
||||
Self {
|
||||
display_name,
|
||||
created: datetime::now(),
|
||||
last_edited: datetime::now(),
|
||||
|
@ -102,8 +117,8 @@ impl AddressBook {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn with_account(s: &crate::conf::AccountSettings) -> AddressBook {
|
||||
let mut ret = AddressBook::new(s.name.clone());
|
||||
pub fn with_account(s: &crate::conf::AccountSettings) -> Self {
|
||||
let mut ret = Self::new(s.name.clone());
|
||||
if let Some(mutt_alias_file) = s.extra.get("mutt_alias_file").map(String::as_str) {
|
||||
match std::fs::read_to_string(std::path::Path::new(mutt_alias_file))
|
||||
.map_err(|err| err.to_string())
|
||||
|
@ -171,8 +186,8 @@ impl Deref for AddressBook {
|
|||
}
|
||||
|
||||
impl Card {
|
||||
pub fn new() -> Card {
|
||||
Card {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
id: CardId::Uuid(Uuid::new_v4()),
|
||||
title: String::new(),
|
||||
name: String::new(),
|
||||
|
@ -293,8 +308,8 @@ impl Card {
|
|||
}
|
||||
|
||||
impl From<HashMap<String, String>> for Card {
|
||||
fn from(mut map: HashMap<String, String>) -> Card {
|
||||
let mut card = Card::new();
|
||||
fn from(mut map: HashMap<String, String>) -> Self {
|
||||
let mut card = Self::new();
|
||||
if let Some(val) = map.remove("TITLE") {
|
||||
card.title = val;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ pub struct ContentLine {
|
|||
}
|
||||
|
||||
impl CardDeserializer {
|
||||
pub fn from_str(mut input: &str) -> Result<VCard<impl VCardVersion>> {
|
||||
pub fn try_from_str(mut input: &str) -> Result<VCard<impl VCardVersion>> {
|
||||
input = if (!input.starts_with(HEADER_CRLF) || !input.ends_with(FOOTER_CRLF))
|
||||
&& (!input.starts_with(HEADER_LF) || !input.ends_with(FOOTER_LF))
|
||||
{
|
||||
|
@ -270,7 +270,7 @@ fn test_load_cards() {
|
|||
for s in parse_card().parse(contents.as_str()).unwrap().1 {
|
||||
println!("");
|
||||
println!("{}", s);
|
||||
println!("{:?}", CardDeserializer::from_str(s));
|
||||
println!("{:?}", CardDeserializer::try_from_str(s));
|
||||
println!("");
|
||||
}
|
||||
*/
|
||||
|
@ -295,7 +295,7 @@ pub fn load_cards(p: &std::path::Path) -> Result<Vec<Card>> {
|
|||
Ok((_, c)) => {
|
||||
for s in c {
|
||||
ret.push(
|
||||
CardDeserializer::from_str(s)
|
||||
CardDeserializer::try_from_str(s)
|
||||
.and_then(TryInto::try_into)
|
||||
.map(|mut card| {
|
||||
Card::set_external_resource(&mut card, true);
|
||||
|
@ -326,7 +326,13 @@ pub fn load_cards(p: &std::path::Path) -> Result<Vec<Card>> {
|
|||
#[test]
|
||||
fn test_card() {
|
||||
let j = "BEGIN:VCARD\r\nVERSION:4.0\r\nN:Gump;Forrest;;Mr.;\r\nFN:Forrest Gump\r\nORG:Bubba Gump Shrimp Co.\r\nTITLE:Shrimp Man\r\nPHOTO;MEDIATYPE=image/gif:http://www.example.com/dir_photos/my_photo.gif\r\nTEL;TYPE=work,voice;VALUE=uri:tel:+1-111-555-1212\r\nTEL;TYPE=home,voice;VALUE=uri:tel:+1-404-555-1212\r\nADR;TYPE=WORK;PREF=1;LABEL=\"100 Waters Edge\\nBaytown\\, LA 30314\\nUnited States of America\":;;100 Waters Edge;Baytown;LA;30314;United States of America\r\nADR;TYPE=HOME;LABEL=\"42 Plantation St.\\nBaytown\\, LA 30314\\nUnited States of America\":;;42 Plantation St.;Baytown;LA;30314;United States of America\r\nEMAIL:forrestgump@example.com\r\nREV:20080424T195243Z\r\nx-qq:21588891\r\nEND:VCARD\r\n";
|
||||
println!("results = {:#?}", CardDeserializer::from_str(j).unwrap());
|
||||
println!(
|
||||
"results = {:#?}",
|
||||
CardDeserializer::try_from_str(j).unwrap()
|
||||
);
|
||||
let j = "BEGIN:VCARD\nVERSION:4.0\nN:Gump;Forrest;;Mr.;\nFN:Forrest Gump\nORG:Bubba Gump Shrimp Co.\nTITLE:Shrimp Man\nPHOTO;MEDIATYPE=image/gif:http://www.example.com/dir_photos/my_photo.gif\nTEL;TYPE=work,voice;VALUE=uri:tel:+1-111-555-1212\nTEL;TYPE=home,voice;VALUE=uri:tel:+1-404-555-1212\nADR;TYPE=WORK;PREF=1;LABEL=\"100 Waters Edge\\nBaytown\\, LA 30314\\nUnited States of America\":;;100 Waters Edge;Baytown;LA;30314;United States of America\nADR;TYPE=HOME;LABEL=\"42 Plantation St.\\nBaytown\\, LA 30314\\nUnited States of America\":;;42 Plantation St.;Baytown;LA;30314;United States of America\nEMAIL:forrestgump@example.com\nREV:20080424T195243Z\nx-qq:21588891\nEND:VCARD\n";
|
||||
println!("results = {:#?}", CardDeserializer::from_str(j).unwrap());
|
||||
println!(
|
||||
"results = {:#?}",
|
||||
CardDeserializer::try_from_str(j).unwrap()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -86,6 +86,8 @@ pub type BackendCreator = Box<
|
|||
) -> Result<Box<dyn MailBackend>>,
|
||||
>;
|
||||
|
||||
pub type BackendValidateConfigFn = Box<dyn Fn(&mut AccountSettings) -> Result<()>>;
|
||||
|
||||
/// A hashmap containing all available mail backends.
|
||||
/// An abstraction over any available backends.
|
||||
pub struct Backends {
|
||||
|
@ -94,12 +96,12 @@ pub struct Backends {
|
|||
|
||||
pub struct Backend {
|
||||
pub create_fn: Box<dyn Fn() -> BackendCreator>,
|
||||
pub validate_conf_fn: Box<dyn Fn(&mut AccountSettings) -> Result<()>>,
|
||||
pub validate_conf_fn: BackendValidateConfigFn,
|
||||
}
|
||||
|
||||
impl Default for Backends {
|
||||
fn default() -> Self {
|
||||
Backends::new()
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,7 +151,7 @@ pub const NOTMUCH_ERROR_DETAILS: &str = r#"If notmuch is installed but the libra
|
|||
|
||||
impl Backends {
|
||||
pub fn new() -> Self {
|
||||
let mut b = Backends {
|
||||
let mut b = Self {
|
||||
map: HashMap::with_capacity_and_hasher(1, Default::default()),
|
||||
};
|
||||
#[cfg(feature = "maildir_backend")]
|
||||
|
@ -272,8 +274,8 @@ pub enum BackendEvent {
|
|||
}
|
||||
|
||||
impl From<Error> for BackendEvent {
|
||||
fn from(val: Error) -> BackendEvent {
|
||||
BackendEvent::Notice {
|
||||
fn from(val: Error) -> Self {
|
||||
Self::Notice {
|
||||
description: val.summary.to_string(),
|
||||
content: Some(val.to_string()),
|
||||
level: LogLevel::ERROR,
|
||||
|
@ -310,9 +312,10 @@ pub struct RefreshEvent {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct BackendEventConsumer(Arc<dyn Fn(AccountHash, BackendEvent) + Send + Sync>);
|
||||
|
||||
impl BackendEventConsumer {
|
||||
pub fn new(b: Arc<dyn Fn(AccountHash, BackendEvent) + Send + Sync>) -> Self {
|
||||
BackendEventConsumer(b)
|
||||
Self(b)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,6 +358,7 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
|
|||
Ok(Box::pin(async { Ok(()) }))
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn fetch(
|
||||
&mut self,
|
||||
mailbox_hash: MailboxHash,
|
||||
|
@ -493,8 +497,9 @@ pub struct ReadOnlyOp {
|
|||
}
|
||||
|
||||
impl ReadOnlyOp {
|
||||
#[allow(clippy::new_ret_no_self)]
|
||||
pub fn new(op: Box<dyn BackendOp>) -> Box<dyn BackendOp> {
|
||||
Box::new(ReadOnlyOp { op })
|
||||
Box::new(Self { op })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -507,8 +512,9 @@ impl BackendOp for ReadOnlyOp {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Hash, Eq, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[derive(Default, Debug, Copy, Hash, Eq, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub enum SpecialUsageMailbox {
|
||||
#[default]
|
||||
Normal,
|
||||
Inbox,
|
||||
Archive,
|
||||
|
@ -539,28 +545,22 @@ impl std::fmt::Display for SpecialUsageMailbox {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for SpecialUsageMailbox {
|
||||
fn default() -> Self {
|
||||
SpecialUsageMailbox::Normal
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecialUsageMailbox {
|
||||
pub fn detect_usage(name: &str) -> Option<SpecialUsageMailbox> {
|
||||
pub fn detect_usage(name: &str) -> Option<Self> {
|
||||
if name.eq_ignore_ascii_case("inbox") {
|
||||
Some(SpecialUsageMailbox::Inbox)
|
||||
Some(Self::Inbox)
|
||||
} else if name.eq_ignore_ascii_case("archive") {
|
||||
Some(SpecialUsageMailbox::Archive)
|
||||
Some(Self::Archive)
|
||||
} else if name.eq_ignore_ascii_case("drafts") {
|
||||
Some(SpecialUsageMailbox::Drafts)
|
||||
Some(Self::Drafts)
|
||||
} else if name.eq_ignore_ascii_case("junk") || name.eq_ignore_ascii_case("spam") {
|
||||
Some(SpecialUsageMailbox::Junk)
|
||||
Some(Self::Junk)
|
||||
} else if name.eq_ignore_ascii_case("sent") {
|
||||
Some(SpecialUsageMailbox::Sent)
|
||||
Some(Self::Sent)
|
||||
} else if name.eq_ignore_ascii_case("trash") {
|
||||
Some(SpecialUsageMailbox::Trash)
|
||||
Some(Self::Trash)
|
||||
} else {
|
||||
Some(SpecialUsageMailbox::Normal)
|
||||
Some(Self::Normal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -608,7 +608,7 @@ pub struct MailboxPermissions {
|
|||
|
||||
impl Default for MailboxPermissions {
|
||||
fn default() -> Self {
|
||||
MailboxPermissions {
|
||||
Self {
|
||||
create_messages: false,
|
||||
remove_messages: false,
|
||||
set_flags: false,
|
||||
|
@ -635,7 +635,7 @@ pub struct EnvelopeHashBatch {
|
|||
|
||||
impl From<EnvelopeHash> for EnvelopeHashBatch {
|
||||
fn from(value: EnvelopeHash) -> Self {
|
||||
EnvelopeHashBatch {
|
||||
Self {
|
||||
first: value,
|
||||
rest: SmallVec::new(),
|
||||
}
|
||||
|
@ -649,16 +649,16 @@ impl std::convert::TryFrom<&[EnvelopeHash]> for EnvelopeHashBatch {
|
|||
if value.is_empty() {
|
||||
return Err(());
|
||||
}
|
||||
Ok(EnvelopeHashBatch {
|
||||
Ok(Self {
|
||||
first: value[0],
|
||||
rest: value[1..].iter().cloned().collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<BTreeSet<EnvelopeHash>> for &EnvelopeHashBatch {
|
||||
fn into(self) -> BTreeSet<EnvelopeHash> {
|
||||
self.iter().collect::<BTreeSet<EnvelopeHash>>()
|
||||
impl From<&EnvelopeHashBatch> for BTreeSet<EnvelopeHash> {
|
||||
fn from(val: &EnvelopeHashBatch) -> Self {
|
||||
val.iter().collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -667,6 +667,10 @@ impl EnvelopeHashBatch {
|
|||
std::iter::once(self.first).chain(self.rest.iter().cloned())
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
1 + self.rest.len()
|
||||
}
|
||||
|
@ -715,6 +719,10 @@ impl LazyCountSet {
|
|||
self.not_yet_seen = self.not_yet_seen.saturating_sub(self.set.len() - old_len);
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn len(&self) -> usize {
|
||||
self.set.len() + self.not_yet_seen
|
||||
|
|
|
@ -146,7 +146,7 @@ macro_rules! get_conf_val {
|
|||
#[derive(Debug)]
|
||||
pub struct UIDStore {
|
||||
account_hash: AccountHash,
|
||||
account_name: Arc<String>,
|
||||
account_name: Arc<str>,
|
||||
keep_offline_cache: bool,
|
||||
capabilities: Arc<Mutex<Capabilities>>,
|
||||
hash_index: Arc<Mutex<HashMap<EnvelopeHash, (UID, MailboxHash)>>>,
|
||||
|
@ -171,11 +171,11 @@ pub struct UIDStore {
|
|||
impl UIDStore {
|
||||
fn new(
|
||||
account_hash: AccountHash,
|
||||
account_name: Arc<String>,
|
||||
account_name: Arc<str>,
|
||||
event_consumer: BackendEventConsumer,
|
||||
timeout: Option<Duration>,
|
||||
) -> Self {
|
||||
UIDStore {
|
||||
Self {
|
||||
account_hash,
|
||||
account_name,
|
||||
keep_offline_cache: false,
|
||||
|
@ -422,7 +422,7 @@ impl MailBackend for ImapType {
|
|||
.collect());
|
||||
}
|
||||
}
|
||||
let new_mailboxes = ImapType::imap_mailboxes(&connection).await?;
|
||||
let new_mailboxes = Self::imap_mailboxes(&connection).await?;
|
||||
let mut mailboxes = uid_store.mailboxes.lock().await;
|
||||
*mailboxes = new_mailboxes;
|
||||
/*
|
||||
|
@ -776,9 +776,7 @@ impl MailBackend for ImapType {
|
|||
}
|
||||
Err(tag) => {
|
||||
let hash = TagHash::from_bytes(tag.as_bytes());
|
||||
if !tag_lck.contains_key(&hash) {
|
||||
tag_lck.insert(hash, tag.to_string());
|
||||
}
|
||||
tag_lck.entry(hash).or_insert_with(|| tag.to_string());
|
||||
cmd.push_str(tag);
|
||||
cmd.push(' ');
|
||||
}
|
||||
|
@ -1242,6 +1240,7 @@ impl MailBackend for ImapType {
|
|||
}
|
||||
|
||||
impl ImapType {
|
||||
#[allow(clippy::new_ret_no_self)]
|
||||
pub fn new(
|
||||
s: &AccountSettings,
|
||||
is_subscribed: Box<dyn Fn(&str) -> bool + Send + Sync>,
|
||||
|
@ -1302,7 +1301,7 @@ impl ImapType {
|
|||
timeout,
|
||||
};
|
||||
let account_hash = AccountHash::from_bytes(s.name.as_bytes());
|
||||
let account_name = Arc::new(s.name.to_string());
|
||||
let account_name = s.name.to_string().into();
|
||||
let uid_store: Arc<UIDStore> = Arc::new(UIDStore {
|
||||
keep_offline_cache,
|
||||
..UIDStore::new(
|
||||
|
@ -1319,7 +1318,7 @@ impl ImapType {
|
|||
uid_store.clone(),
|
||||
);
|
||||
|
||||
Ok(Box::new(ImapType {
|
||||
Ok(Box::new(Self {
|
||||
server_conf,
|
||||
_is_subscribed: Arc::new(IsSubscribedFn(is_subscribed)),
|
||||
connection: Arc::new(FutureMutex::new(connection)),
|
||||
|
@ -1423,29 +1422,27 @@ impl ImapType {
|
|||
}
|
||||
if let Ok(mut mailbox) = protocol_parser::list_mailbox_result(l).map(|(_, v)| v) {
|
||||
if let Some(parent) = mailbox.parent {
|
||||
if mailboxes.contains_key(&parent) {
|
||||
mailboxes
|
||||
.entry(parent)
|
||||
.and_modify(|e| e.children.push(mailbox.hash));
|
||||
} else {
|
||||
if let std::collections::hash_map::Entry::Vacant(e) = mailboxes.entry(parent) {
|
||||
/* Insert dummy parent entry, populating only the children field. Later
|
||||
* when we encounter the parent entry we will swap its children with
|
||||
* dummy's */
|
||||
mailboxes.insert(
|
||||
parent,
|
||||
ImapMailbox {
|
||||
children: vec![mailbox.hash],
|
||||
..ImapMailbox::default()
|
||||
},
|
||||
);
|
||||
e.insert(ImapMailbox {
|
||||
children: vec![mailbox.hash],
|
||||
..ImapMailbox::default()
|
||||
});
|
||||
} else {
|
||||
mailboxes
|
||||
.entry(parent)
|
||||
.and_modify(|e| e.children.push(mailbox.hash));
|
||||
}
|
||||
}
|
||||
if mailboxes.contains_key(&mailbox.hash) {
|
||||
if let std::collections::hash_map::Entry::Vacant(e) = mailboxes.entry(mailbox.hash)
|
||||
{
|
||||
e.insert(mailbox);
|
||||
} else {
|
||||
let entry = mailboxes.entry(mailbox.hash).or_default();
|
||||
std::mem::swap(&mut entry.children, &mut mailbox.children);
|
||||
*entry = mailbox;
|
||||
} else {
|
||||
mailboxes.insert(mailbox.hash, mailbox);
|
||||
}
|
||||
} else if let Ok(status) = protocol_parser::status_response(l).map(|(_, v)| v) {
|
||||
if let Some(mailbox_hash) = status.mailbox {
|
||||
|
@ -1828,9 +1825,7 @@ async fn fetch_hlpr(state: &mut FetchState) -> Result<Vec<Envelope>> {
|
|||
}
|
||||
for f in keywords {
|
||||
let hash = TagHash::from_bytes(f.as_bytes());
|
||||
if !tag_lck.contains_key(&hash) {
|
||||
tag_lck.insert(hash, f.to_string());
|
||||
}
|
||||
tag_lck.entry(hash).or_insert_with(|| f.to_string());
|
||||
env.tags_mut().push(hash);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ pub struct ModSequence(pub std::num::NonZeroU64);
|
|||
|
||||
impl TryFrom<i64> for ModSequence {
|
||||
type Error = ();
|
||||
fn try_from(val: i64) -> std::result::Result<ModSequence, ()> {
|
||||
fn try_from(val: i64) -> std::result::Result<Self, ()> {
|
||||
std::num::NonZeroU64::new(val as u64)
|
||||
.map(|u| Ok(ModSequence(u)))
|
||||
.map(|u| Ok(Self(u)))
|
||||
.unwrap_or(Err(()))
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ mod sqlite3_m {
|
|||
if i == 0 {
|
||||
return Err(FromSqlError::OutOfRange(0));
|
||||
}
|
||||
Ok(ModSequence::try_from(i).unwrap())
|
||||
Ok(Self::try_from(i).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ mod sqlite3_m {
|
|||
Ok(Box::new(Self {
|
||||
connection: sqlite3::open_or_create_db(
|
||||
&DB_DESCRIPTION,
|
||||
Some(uid_store.account_name.as_str()),
|
||||
Some(&uid_store.account_name),
|
||||
)?,
|
||||
loaded_mailboxes: BTreeSet::default(),
|
||||
uid_store,
|
||||
|
@ -195,13 +195,13 @@ mod sqlite3_m {
|
|||
|
||||
impl ImapCacheReset for Sqlite3Cache {
|
||||
fn reset_db(uid_store: &UIDStore) -> Result<()> {
|
||||
sqlite3::reset_db(&DB_DESCRIPTION, Some(uid_store.account_name.as_str()))
|
||||
sqlite3::reset_db(&DB_DESCRIPTION, Some(&uid_store.account_name))
|
||||
}
|
||||
}
|
||||
|
||||
impl ImapCache for Sqlite3Cache {
|
||||
fn reset(&mut self) -> Result<()> {
|
||||
Sqlite3Cache::reset_db(&self.uid_store)
|
||||
Self::reset_db(&self.uid_store)
|
||||
}
|
||||
|
||||
fn mailbox_state(&mut self, mailbox_hash: MailboxHash) -> Result<Option<()>> {
|
||||
|
@ -256,10 +256,7 @@ mod sqlite3_m {
|
|||
let mut tag_lck = self.uid_store.collection.tag_index.write().unwrap();
|
||||
for f in to_str!(&flags).split('\0') {
|
||||
let hash = TagHash::from_bytes(f.as_bytes());
|
||||
//debug!("hash {} flag {}", hash, &f);
|
||||
if !tag_lck.contains_key(&hash) {
|
||||
tag_lck.insert(hash, f.to_string());
|
||||
}
|
||||
tag_lck.entry(hash).or_insert_with(|| f.to_string());
|
||||
}
|
||||
self.loaded_mailboxes.insert(mailbox_hash);
|
||||
Ok(Some(()))
|
||||
|
@ -410,6 +407,8 @@ mod sqlite3_m {
|
|||
"SELECT uid, envelope, modsequence FROM envelopes WHERE mailbox_hash = ?1;",
|
||||
)?;
|
||||
|
||||
#[allow(clippy::let_and_return)] // false positive, the let binding is needed
|
||||
// for the temporary to live long enough
|
||||
let x = stmt
|
||||
.query_map(sqlite3::params![mailbox_hash], |row| {
|
||||
Ok((
|
||||
|
@ -619,6 +618,8 @@ mod sqlite3_m {
|
|||
AND uid = ?2;",
|
||||
)?;
|
||||
|
||||
#[allow(clippy::let_and_return)] // false positive, the let binding is needed
|
||||
// for the temporary to live long enough
|
||||
let x = stmt
|
||||
.query_map(sqlite3::params![mailbox_hash, uid as Sqlite3UID], |row| {
|
||||
Ok((
|
||||
|
@ -636,6 +637,8 @@ mod sqlite3_m {
|
|||
AND hash = ?2;",
|
||||
)?;
|
||||
|
||||
#[allow(clippy::let_and_return)] // false positive, the let binding is needed
|
||||
// for the temporary to live long enough
|
||||
let x = stmt
|
||||
.query_map(sqlite3::params![mailbox_hash, env_hash], |row| {
|
||||
Ok((
|
||||
|
@ -670,6 +673,8 @@ mod sqlite3_m {
|
|||
let mut stmt = self.connection.prepare(
|
||||
"SELECT rfc822 FROM envelopes WHERE mailbox_hash = ?1 AND uid = ?2;",
|
||||
)?;
|
||||
#[allow(clippy::let_and_return)] // false positive, the let binding is needed
|
||||
// for the temporary to live long enough
|
||||
let x = stmt
|
||||
.query_map(sqlite3::params![mailbox_hash, uid as Sqlite3UID], |row| {
|
||||
row.get(0)
|
||||
|
@ -681,6 +686,8 @@ mod sqlite3_m {
|
|||
let mut stmt = self.connection.prepare(
|
||||
"SELECT rfc822 FROM envelopes WHERE mailbox_hash = ?1 AND hash = ?2;",
|
||||
)?;
|
||||
#[allow(clippy::let_and_return)] // false positive, the let binding is needed
|
||||
// for the temporary to live long enough
|
||||
let x = stmt
|
||||
.query_map(sqlite3::params![mailbox_hash, env_hash], |row| row.get(0))?
|
||||
.collect::<std::result::Result<_, _>>()?;
|
||||
|
|
|
@ -32,7 +32,7 @@ impl ImapConnection {
|
|||
pub async fn resync(&mut self, mailbox_hash: MailboxHash) -> Result<Option<Vec<Envelope>>> {
|
||||
debug!("resync mailbox_hash {}", mailbox_hash);
|
||||
debug!(&self.sync_policy);
|
||||
if let SyncPolicy::None = self.sync_policy {
|
||||
if matches!(self.sync_policy, SyncPolicy::None) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ impl ImapConnection {
|
|||
.unwrap()
|
||||
.get(&mailbox_hash)
|
||||
.cloned();
|
||||
// 3. tag2 UID FETCH 1:<lastseenuid> FLAGS
|
||||
// 3. tag2 UID FETCH 1:<lastseenuid> FLAGS
|
||||
//if cached_uidvalidity.is_none() || cached_max_uid.is_none() {
|
||||
// return Ok(None);
|
||||
//}
|
||||
|
@ -134,7 +134,7 @@ impl ImapConnection {
|
|||
}
|
||||
cache_handle.update_mailbox(mailbox_hash, &select_response)?;
|
||||
|
||||
// 2. tag1 UID FETCH <lastseenuid+1>:* <descriptors>
|
||||
// 2. tag1 UID FETCH <lastseenuid+1>:* <descriptors>
|
||||
self.send_command(CommandBody::fetch(
|
||||
max_uid + 1..,
|
||||
common_attributes(),
|
||||
|
@ -172,9 +172,7 @@ impl ImapConnection {
|
|||
}
|
||||
for f in keywords {
|
||||
let hash = TagHash::from_bytes(f.as_bytes());
|
||||
if !tag_lck.contains_key(&hash) {
|
||||
tag_lck.insert(hash, f.to_string());
|
||||
}
|
||||
tag_lck.entry(hash).or_insert_with(|| f.to_string());
|
||||
env.tags_mut().push(hash);
|
||||
}
|
||||
}
|
||||
|
@ -232,7 +230,7 @@ impl ImapConnection {
|
|||
unseen_lck.insert_set(new_unseen);
|
||||
}
|
||||
mailbox_exists.lock().unwrap().insert_set(payload_hash_set);
|
||||
// 3. tag2 UID FETCH 1:<lastseenuid> FLAGS
|
||||
// 3. tag2 UID FETCH 1:<lastseenuid> FLAGS
|
||||
let sequence_set = if max_uid == 0 {
|
||||
SequenceSet::from(..)
|
||||
} else {
|
||||
|
@ -246,9 +244,9 @@ impl ImapConnection {
|
|||
.await?;
|
||||
self.read_response(&mut response, RequiredResponses::FETCH_REQUIRED)
|
||||
.await?;
|
||||
//1) update cached flags for old messages;
|
||||
//2) find out which old messages got expunged; and
|
||||
//3) build a mapping between message numbers and UIDs (for old messages).
|
||||
// 1) update cached flags for old messages;
|
||||
// 2) find out which old messages got expunged; and
|
||||
// 3) build a mapping between message numbers and UIDs (for old messages).
|
||||
let mut valid_envs = BTreeSet::default();
|
||||
let mut env_lck = self.uid_store.envelopes.lock().unwrap();
|
||||
let (_, v, _) = protocol_parser::fetch_responses(&response)?;
|
||||
|
@ -422,7 +420,7 @@ impl ImapConnection {
|
|||
// "FETCH 1:* (FLAGS) (CHANGEDSINCE <cached-value>)" or
|
||||
// "SEARCH MODSEQ <cached-value>".
|
||||
|
||||
// 2. tag1 UID FETCH <lastseenuid+1>:* <descriptors>
|
||||
// 2. tag1 UID FETCH <lastseenuid+1>:* <descriptors>
|
||||
self.send_command_raw(
|
||||
format!(
|
||||
"UID FETCH {}:* (UID FLAGS ENVELOPE BODY.PEEK[HEADER.FIELDS (REFERENCES)] \
|
||||
|
@ -464,9 +462,7 @@ impl ImapConnection {
|
|||
}
|
||||
for f in keywords {
|
||||
let hash = TagHash::from_bytes(f.as_bytes());
|
||||
if !tag_lck.contains_key(&hash) {
|
||||
tag_lck.insert(hash, f.to_string());
|
||||
}
|
||||
tag_lck.entry(hash).or_insert_with(|| f.to_string());
|
||||
env.tags_mut().push(hash);
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +514,7 @@ impl ImapConnection {
|
|||
unseen_lck.insert_set(new_unseen);
|
||||
}
|
||||
mailbox_exists.lock().unwrap().insert_set(payload_hash_set);
|
||||
// 3. tag2 UID FETCH 1:<lastseenuid> FLAGS
|
||||
// 3. tag2 UID FETCH 1:<lastseenuid> FLAGS
|
||||
if cached_max_uid == 0 {
|
||||
self.send_command_raw(
|
||||
format!(
|
||||
|
@ -540,7 +536,7 @@ impl ImapConnection {
|
|||
}
|
||||
self.read_response(&mut response, RequiredResponses::FETCH_REQUIRED)
|
||||
.await?;
|
||||
//1) update cached flags for old messages;
|
||||
// 1) update cached flags for old messages;
|
||||
let mut env_lck = self.uid_store.envelopes.lock().unwrap();
|
||||
let (_, v, _) = protocol_parser::fetch_responses(&response)?;
|
||||
for FetchResponse { uid, flags, .. } in v {
|
||||
|
@ -588,14 +584,14 @@ impl ImapConnection {
|
|||
.await?;
|
||||
self.read_response(&mut response, RequiredResponses::SEARCH)
|
||||
.await?;
|
||||
//1) update cached flags for old messages;
|
||||
// 1) update cached flags for old messages;
|
||||
let (_, v) = protocol_parser::search_results(response.as_slice())?;
|
||||
for uid in v {
|
||||
valid_envs.insert(generate_envelope_hash(&mailbox_path, &uid));
|
||||
}
|
||||
{
|
||||
let mut env_lck = self.uid_store.envelopes.lock().unwrap();
|
||||
for env_hash in env_lck
|
||||
let olds = env_lck
|
||||
.iter()
|
||||
.filter_map(|(h, cenv)| {
|
||||
if cenv.mailbox_hash == mailbox_hash {
|
||||
|
@ -604,9 +600,8 @@ impl ImapConnection {
|
|||
None
|
||||
}
|
||||
})
|
||||
.collect::<BTreeSet<EnvelopeHash>>()
|
||||
.difference(&valid_envs)
|
||||
{
|
||||
.collect::<BTreeSet<EnvelopeHash>>();
|
||||
for env_hash in olds.difference(&valid_envs) {
|
||||
refresh_events.push((
|
||||
env_lck[env_hash].uid,
|
||||
RefreshEvent {
|
||||
|
|
|
@ -134,7 +134,7 @@ pub enum MailboxSelection {
|
|||
|
||||
impl MailboxSelection {
|
||||
pub fn take(&mut self) -> Self {
|
||||
std::mem::replace(self, MailboxSelection::None)
|
||||
std::mem::replace(self, Self::None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ impl ImapStream {
|
|||
server_conf: &ImapServerConf,
|
||||
#[cfg(debug_assertions)] id: Cow<'static, str>,
|
||||
uid_store: &UIDStore,
|
||||
) -> Result<(Capabilities, ImapStream)> {
|
||||
) -> Result<(Capabilities, Self)> {
|
||||
use std::net::TcpStream;
|
||||
let path = &server_conf.server_hostname;
|
||||
|
||||
|
@ -293,7 +293,7 @@ impl ImapStream {
|
|||
log::warn!("Could not set TCP keepalive in IMAP connection: {}", err);
|
||||
}
|
||||
let mut res = Vec::with_capacity(8 * 1024);
|
||||
let mut ret = ImapStream {
|
||||
let mut ret = Self {
|
||||
cmd_id,
|
||||
#[cfg(debug_assertions)]
|
||||
id,
|
||||
|
@ -302,7 +302,7 @@ impl ImapStream {
|
|||
current_mailbox: MailboxSelection::None,
|
||||
timeout: server_conf.timeout,
|
||||
};
|
||||
if let ImapProtocol::ManageSieve = server_conf.protocol {
|
||||
if matches!(server_conf.protocol, ImapProtocol::ManageSieve) {
|
||||
ret.read_response(&mut res).await?;
|
||||
let credentials = format!(
|
||||
"\0{}\0{}",
|
||||
|
@ -530,7 +530,7 @@ impl ImapStream {
|
|||
pub async fn send_command(&mut self, body: CommandBody<'_>) -> Result<()> {
|
||||
timeout(self.timeout, async {
|
||||
let command = {
|
||||
let tag = Tag::unchecked(format!("M{}", self.cmd_id.to_string()));
|
||||
let tag = Tag::unchecked(format!("M{}", self.cmd_id));
|
||||
|
||||
Command { tag, body }
|
||||
};
|
||||
|
@ -629,8 +629,8 @@ impl ImapConnection {
|
|||
server_conf: &ImapServerConf,
|
||||
#[cfg(debug_assertions)] id: Cow<'static, str>,
|
||||
uid_store: Arc<UIDStore>,
|
||||
) -> ImapConnection {
|
||||
ImapConnection {
|
||||
) -> Self {
|
||||
Self {
|
||||
stream: Err(Error::new("Offline".to_string())),
|
||||
#[cfg(debug_assertions)]
|
||||
id,
|
||||
|
@ -1167,7 +1167,7 @@ pub struct ImapBlockingConnection {
|
|||
|
||||
impl From<ImapConnection> for ImapBlockingConnection {
|
||||
fn from(conn: ImapConnection) -> Self {
|
||||
ImapBlockingConnection {
|
||||
Self {
|
||||
buf: vec![0; Connection::IO_BUF_SIZE],
|
||||
conn,
|
||||
prev_res_length: 0,
|
||||
|
@ -1186,7 +1186,7 @@ impl ImapBlockingConnection {
|
|||
self.err.take()
|
||||
}
|
||||
|
||||
pub fn as_stream<'a>(&'a mut self) -> impl Future<Output = Option<Vec<u8>>> + 'a {
|
||||
pub fn as_stream(&mut self) -> impl Future<Output = Option<Vec<u8>>> + '_ {
|
||||
self.result.drain(0..self.prev_res_length);
|
||||
self.prev_res_length = 0;
|
||||
let mut break_flag = false;
|
||||
|
|
|
@ -32,8 +32,8 @@ use crate::error::{Error, ErrorKind};
|
|||
|
||||
impl From<LiteralError> for Error {
|
||||
#[inline]
|
||||
fn from(error: LiteralError) -> Error {
|
||||
Error {
|
||||
fn from(error: LiteralError) -> Self {
|
||||
Self {
|
||||
summary: error.to_string().into(),
|
||||
details: None,
|
||||
source: Some(Arc::new(error)),
|
||||
|
@ -44,8 +44,8 @@ impl From<LiteralError> for Error {
|
|||
|
||||
impl From<SequenceSetError> for Error {
|
||||
#[inline]
|
||||
fn from(error: SequenceSetError) -> Error {
|
||||
Error {
|
||||
fn from(error: SequenceSetError) -> Self {
|
||||
Self {
|
||||
summary: error.to_string().into(),
|
||||
details: None,
|
||||
source: Some(Arc::new(error)),
|
||||
|
@ -59,8 +59,8 @@ where
|
|||
AppendError<S, L>: fmt::Debug + fmt::Display + Sync + Send + 'static,
|
||||
{
|
||||
#[inline]
|
||||
fn from(error: AppendError<S, L>) -> Error {
|
||||
Error {
|
||||
fn from(error: AppendError<S, L>) -> Self {
|
||||
Self {
|
||||
summary: error.to_string().into(),
|
||||
details: None,
|
||||
source: Some(Arc::new(error)),
|
||||
|
@ -74,8 +74,8 @@ where
|
|||
CopyError<S, L>: fmt::Debug + fmt::Display + Sync + Send + 'static,
|
||||
{
|
||||
#[inline]
|
||||
fn from(error: CopyError<S, L>) -> Error {
|
||||
Error {
|
||||
fn from(error: CopyError<S, L>) -> Self {
|
||||
Self {
|
||||
summary: error.to_string().into(),
|
||||
details: None,
|
||||
source: Some(Arc::new(error)),
|
||||
|
@ -89,8 +89,8 @@ where
|
|||
MoveError<S, M>: fmt::Debug + fmt::Display + Sync + Send + 'static,
|
||||
{
|
||||
#[inline]
|
||||
fn from(error: MoveError<S, M>) -> Error {
|
||||
Error {
|
||||
fn from(error: MoveError<S, M>) -> Self {
|
||||
Self {
|
||||
summary: error.to_string().into(),
|
||||
details: None,
|
||||
source: Some(Arc::new(error)),
|
||||
|
@ -104,8 +104,8 @@ where
|
|||
ListError<L1, L2>: fmt::Debug + fmt::Display + Sync + Send + 'static,
|
||||
{
|
||||
#[inline]
|
||||
fn from(error: ListError<L1, L2>) -> Error {
|
||||
Error {
|
||||
fn from(error: ListError<L1, L2>) -> Self {
|
||||
Self {
|
||||
summary: error.to_string().into(),
|
||||
details: None,
|
||||
source: Some(Arc::new(error)),
|
||||
|
|
|
@ -328,7 +328,7 @@ impl ManageSieveConnection {
|
|||
))),
|
||||
..UIDStore::new(
|
||||
account_hash,
|
||||
Arc::new(account_name),
|
||||
account_name.into(),
|
||||
event_consumer,
|
||||
server_conf.timeout,
|
||||
)
|
||||
|
|
|
@ -42,7 +42,7 @@ impl ImapOp {
|
|||
connection: Arc<FutureMutex<ImapConnection>>,
|
||||
uid_store: Arc<UIDStore>,
|
||||
) -> Self {
|
||||
ImapOp {
|
||||
Self {
|
||||
uid,
|
||||
connection,
|
||||
mailbox_hash,
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#![allow(clippy::type_complexity)]
|
||||
|
||||
use std::{convert::TryFrom, str::FromStr};
|
||||
|
||||
use nom::{
|
||||
|
@ -78,49 +80,49 @@ impl RequiredResponses {
|
|||
}
|
||||
let line = &line[b"* ".len()..];
|
||||
let mut ret = false;
|
||||
if self.intersects(RequiredResponses::CAPABILITY) {
|
||||
if self.intersects(Self::CAPABILITY) {
|
||||
ret |= line.starts_with(b"CAPABILITY");
|
||||
}
|
||||
if self.intersects(RequiredResponses::BYE) {
|
||||
if self.intersects(Self::BYE) {
|
||||
ret |= line.starts_with(b"BYE");
|
||||
}
|
||||
if self.intersects(RequiredResponses::FLAGS) {
|
||||
if self.intersects(Self::FLAGS) {
|
||||
ret |= line.starts_with(b"FLAGS");
|
||||
}
|
||||
if self.intersects(RequiredResponses::EXISTS) {
|
||||
if self.intersects(Self::EXISTS) {
|
||||
ret |= line.ends_with(b"EXISTS\r\n");
|
||||
}
|
||||
if self.intersects(RequiredResponses::RECENT) {
|
||||
if self.intersects(Self::RECENT) {
|
||||
ret |= line.ends_with(b"RECENT\r\n");
|
||||
}
|
||||
if self.intersects(RequiredResponses::UNSEEN) {
|
||||
if self.intersects(Self::UNSEEN) {
|
||||
ret |= line.starts_with(b"UNSEEN");
|
||||
}
|
||||
if self.intersects(RequiredResponses::PERMANENTFLAGS) {
|
||||
if self.intersects(Self::PERMANENTFLAGS) {
|
||||
ret |= line.starts_with(b"PERMANENTFLAGS");
|
||||
}
|
||||
if self.intersects(RequiredResponses::UIDNEXT) {
|
||||
if self.intersects(Self::UIDNEXT) {
|
||||
ret |= line.starts_with(b"UIDNEXT");
|
||||
}
|
||||
if self.intersects(RequiredResponses::UIDVALIDITY) {
|
||||
if self.intersects(Self::UIDVALIDITY) {
|
||||
ret |= line.starts_with(b"UIDVALIDITY");
|
||||
}
|
||||
if self.intersects(RequiredResponses::LIST) {
|
||||
if self.intersects(Self::LIST) {
|
||||
ret |= line.starts_with(b"LIST");
|
||||
}
|
||||
if self.intersects(RequiredResponses::LSUB) {
|
||||
if self.intersects(Self::LSUB) {
|
||||
ret |= line.starts_with(b"LSUB");
|
||||
}
|
||||
if self.intersects(RequiredResponses::STATUS) {
|
||||
if self.intersects(Self::STATUS) {
|
||||
ret |= line.starts_with(b"STATUS");
|
||||
}
|
||||
if self.intersects(RequiredResponses::EXPUNGE) {
|
||||
if self.intersects(Self::EXPUNGE) {
|
||||
ret |= line.ends_with(b"EXPUNGE\r\n");
|
||||
}
|
||||
if self.intersects(RequiredResponses::SEARCH) {
|
||||
if self.intersects(Self::SEARCH) {
|
||||
ret |= line.starts_with(b"SEARCH");
|
||||
}
|
||||
if self.intersects(RequiredResponses::FETCH) {
|
||||
if self.intersects(Self::FETCH) {
|
||||
let mut ptr = 0;
|
||||
for (i, l) in line.iter().enumerate() {
|
||||
if !l.is_ascii_digit() {
|
||||
|
@ -134,7 +136,7 @@ impl RequiredResponses {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct Alert(String);
|
||||
|
||||
pub type ImapParseResult<'a, T> = Result<(&'a [u8], T, Option<Alert>)>;
|
||||
|
@ -142,7 +144,7 @@ pub struct ImapLineIterator<'a> {
|
|||
slice: &'a [u8],
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum ResponseCode {
|
||||
///The human-readable text contains a special alert that MUST be presented
|
||||
/// to the user in a fashion that calls the user's attention to the message.
|
||||
|
@ -229,7 +231,7 @@ impl std::fmt::Display for ResponseCode {
|
|||
}
|
||||
|
||||
impl ResponseCode {
|
||||
fn from(val: &[u8]) -> ResponseCode {
|
||||
fn from(val: &[u8]) -> Self {
|
||||
use ResponseCode::*;
|
||||
if !val.starts_with(b"[") {
|
||||
let msg = val.trim();
|
||||
|
@ -280,7 +282,7 @@ impl ResponseCode {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum ImapResponse {
|
||||
Ok(ResponseCode),
|
||||
No(ResponseCode),
|
||||
|
@ -291,7 +293,7 @@ pub enum ImapResponse {
|
|||
|
||||
impl TryFrom<&'_ [u8]> for ImapResponse {
|
||||
type Error = Error;
|
||||
fn try_from(val: &'_ [u8]) -> Result<ImapResponse> {
|
||||
fn try_from(val: &'_ [u8]) -> Result<Self> {
|
||||
let val: &[u8] = val.split_rn().last().unwrap_or(val);
|
||||
let mut val = val[val.find(b" ").ok_or_else(|| {
|
||||
Error::new(format!(
|
||||
|
@ -330,16 +332,15 @@ impl TryFrom<&'_ [u8]> for ImapResponse {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<Result<()>> for ImapResponse {
|
||||
fn into(self) -> Result<()> {
|
||||
match self {
|
||||
Self::Ok(_) | Self::Preauth(_) | Self::Bye(_) => Ok(()),
|
||||
Self::No(ResponseCode::Alert(msg)) | Self::Bad(ResponseCode::Alert(msg)) => {
|
||||
Err(Error::new(msg))
|
||||
}
|
||||
Self::No(err) => Err(Error::new(format!("{:?}", err)))
|
||||
impl From<ImapResponse> for Result<()> {
|
||||
fn from(resp: ImapResponse) -> Self {
|
||||
match resp {
|
||||
ImapResponse::Ok(_) | ImapResponse::Preauth(_) | ImapResponse::Bye(_) => Ok(()),
|
||||
ImapResponse::No(ResponseCode::Alert(msg))
|
||||
| ImapResponse::Bad(ResponseCode::Alert(msg)) => Err(Error::new(msg)),
|
||||
ImapResponse::No(err) => Err(Error::new(format!("{:?}", err)))
|
||||
.chain_err_summary(|| "IMAP NO Response.".to_string()),
|
||||
Self::Bad(err) => Err(Error::new(format!("{:?}", err)))
|
||||
ImapResponse::Bad(err) => Err(Error::new(format!("{:?}", err)))
|
||||
.chain_err_summary(|| "IMAP BAD Response.".to_string()),
|
||||
}
|
||||
}
|
||||
|
@ -428,9 +429,11 @@ pub fn list_mailbox_result(input: &[u8]) -> IResult<&[u8], ImapMailbox> {
|
|||
input,
|
||||
({
|
||||
let separator: u8 = separator[0];
|
||||
let mut f = ImapMailbox::default();
|
||||
f.no_select = false;
|
||||
f.is_subscribed = false;
|
||||
let mut f = ImapMailbox {
|
||||
no_select: false,
|
||||
is_subscribed: false,
|
||||
..ImapMailbox::default()
|
||||
};
|
||||
|
||||
if path.eq_ignore_ascii_case("INBOX") {
|
||||
f.is_subscribed = true;
|
||||
|
@ -478,7 +481,7 @@ pub fn list_mailbox_result(input: &[u8]) -> IResult<&[u8], ImapMailbox> {
|
|||
))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct FetchResponse<'a> {
|
||||
pub uid: Option<UID>,
|
||||
pub message_sequence_number: MessageSequenceNumber,
|
||||
|
@ -788,7 +791,7 @@ pub fn capabilities(input: &[u8]) -> IResult<&[u8], Vec<&[u8]>> {
|
|||
|
||||
/// This enum represents the server's untagged responses detailed in `7. Server
|
||||
/// Responses` of RFC 3501 INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum UntaggedResponse<'s> {
|
||||
/// ```text
|
||||
/// 7.4.1. EXPUNGE Response
|
||||
|
@ -926,7 +929,7 @@ pub fn search_results_raw<'a>(input: &'a [u8]) -> IResult<&'a [u8], &'a [u8]> {
|
|||
))(input)
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone)]
|
||||
#[derive(Debug, Default, Eq, PartialEq, Clone)]
|
||||
pub struct SelectResponse {
|
||||
pub exists: ImapNum,
|
||||
pub recent: ImapNum,
|
||||
|
@ -1705,11 +1708,11 @@ mod tests {
|
|||
let mut address = SmallVec::new();
|
||||
address.push(Address::new(None, "xx@xx.com".to_string()));
|
||||
let mut env = Envelope::new(EnvelopeHash::default());
|
||||
env.set_subject("xxxx/xxxx".as_bytes().to_vec());
|
||||
env.set_date("Fri, 24 Jun 2011 10:09:10 +0000".as_bytes());
|
||||
env.set_subject(b"xxxx/xxxx".to_vec());
|
||||
env.set_date(b"Fri, 24 Jun 2011 10:09:10 +0000");
|
||||
env.set_from(address.clone());
|
||||
env.set_to(address);
|
||||
env.set_message_id("<xx@xx.com>".as_bytes());
|
||||
env.set_message_id(b"<xx@xx.com>");
|
||||
assert_eq!(
|
||||
fetch_response(input).unwrap(),
|
||||
(
|
||||
|
|
|
@ -115,7 +115,7 @@ impl ImapConnection {
|
|||
);
|
||||
}
|
||||
let mut events = vec![];
|
||||
for (deleted_uid, deleted_hash) in self
|
||||
let deleteds = self
|
||||
.uid_store
|
||||
.uid_index
|
||||
.lock()
|
||||
|
@ -125,8 +125,8 @@ impl ImapConnection {
|
|||
*mailbox_hash_ == mailbox_hash && !results.contains(u)
|
||||
})
|
||||