forked from meli/meli
1
Fork 0

melib: clippy lint fixes

master
Manos Pitsidianakis 2023-07-01 16:34:06 +03:00
parent 6858ee1fab
commit 5f29faa640
Signed by: Manos Pitsidianakis
GPG Key ID: 7729C7707F7E09D0
70 changed files with 1290 additions and 1194 deletions

View File

@ -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

View File

@ -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");

View File

@ -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;
}

View File

@ -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()
);
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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<_, _>>()?;

View File

@ -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 {

View File

@ -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;

View File

@ -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)),

View File

@ -328,7 +328,7 @@ impl ManageSieveConnection {
))),
..UIDStore::new(
account_hash,
Arc::new(account_name),
account_name.into(),
event_consumer,
server_conf.timeout,
)

View File

@ -42,7 +42,7 @@ impl ImapOp {
connection: Arc<FutureMutex<ImapConnection>>,
uid_store: Arc<UIDStore>,
) -> Self {
ImapOp {
Self {
uid,
connection,
mailbox_hash,

View File

@ -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(),
(

View File

@ -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)
})
.map(|((_, uid), hash)| (*uid, *hash))