mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 13:36:30 +03:00
Remove indexmap dependency
`indexmap` is a large dependency (4K SLoC) containing `unsafe` code. Contact IDs are now passed around as a Vec<u32> or &[u32]. QUOTA roots are now sorted by name instead of perserving original order.
This commit is contained in:
11
Cargo.lock
generated
11
Cargo.lock
generated
@@ -1084,7 +1084,6 @@ dependencies = [
|
||||
"hex",
|
||||
"humansize",
|
||||
"image",
|
||||
"indexmap",
|
||||
"kamadak-exif",
|
||||
"lettre_email",
|
||||
"libc",
|
||||
@@ -1935,16 +1934,6 @@ dependencies = [
|
||||
"nom 6.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
|
||||
dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "infer"
|
||||
version = "0.2.3"
|
||||
|
||||
@@ -36,7 +36,6 @@ escaper = "0.1"
|
||||
futures = "0.3"
|
||||
hex = "0.4.0"
|
||||
image = { version = "0.23.5", default-features=false, features = ["gif", "jpeg", "ico", "png", "pnm", "webp", "bmp"] }
|
||||
indexmap = "1.7"
|
||||
kamadak-exif = "0.5"
|
||||
lettre_email = { git = "https://github.com/deltachat/lettre", branch = "master" }
|
||||
libc = "0.2"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Internet Message Format reception pipeline.
|
||||
|
||||
use std::cmp::min;
|
||||
use std::collections::BTreeSet;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use anyhow::{bail, ensure, Context as _, Result};
|
||||
@@ -35,9 +36,6 @@ use crate::securejoin::{self, handle_securejoin_handshake, observe_securejoin_on
|
||||
use crate::stock_str;
|
||||
use crate::{contact, location};
|
||||
|
||||
// IndexSet is like HashSet but maintains order of insertion.
|
||||
type ContactIds = indexmap::IndexSet<u32>;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
enum CreateEvent {
|
||||
MsgsChanged,
|
||||
@@ -162,23 +160,19 @@ pub(crate) async fn dc_receive_imf_inner(
|
||||
|
||||
let incoming = from_id != DC_CONTACT_ID_SELF;
|
||||
|
||||
let mut to_ids = ContactIds::new();
|
||||
|
||||
to_ids.extend(
|
||||
&dc_add_or_lookup_contacts_by_address_list(
|
||||
context,
|
||||
&mime_parser.recipients,
|
||||
if !incoming {
|
||||
Origin::OutgoingTo
|
||||
} else if incoming_origin.is_known() {
|
||||
Origin::IncomingTo
|
||||
} else {
|
||||
Origin::IncomingUnknownTo
|
||||
},
|
||||
prevent_rename,
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
let to_ids = dc_add_or_lookup_contacts_by_address_list(
|
||||
context,
|
||||
&mime_parser.recipients,
|
||||
if !incoming {
|
||||
Origin::OutgoingTo
|
||||
} else if incoming_origin.is_known() {
|
||||
Origin::IncomingTo
|
||||
} else {
|
||||
Origin::IncomingUnknownTo
|
||||
},
|
||||
prevent_rename,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let rcvd_timestamp = dc_smeared_time(context).await;
|
||||
let sent_timestamp = mime_parser
|
||||
@@ -402,7 +396,7 @@ pub async fn from_field_to_contact_id(
|
||||
"mail has more than one From address, only using first: {:?}", from_address_list
|
||||
);
|
||||
}
|
||||
let from_id = from_ids.get_index(0).cloned().unwrap_or_default();
|
||||
let from_id = from_ids.get(0).cloned().unwrap_or_default();
|
||||
|
||||
let mut from_id_blocked = false;
|
||||
let mut incoming_origin = Origin::Unknown;
|
||||
@@ -430,7 +424,7 @@ async fn add_parts(
|
||||
incoming_origin: Origin,
|
||||
server_folder: &str,
|
||||
server_uid: u32,
|
||||
to_ids: &ContactIds,
|
||||
to_ids: &[u32],
|
||||
rfc724_mid: String,
|
||||
sent_timestamp: i64,
|
||||
rcvd_timestamp: i64,
|
||||
@@ -724,7 +718,7 @@ async fn add_parts(
|
||||
// the mail is on the IMAP server, probably it is also delivered.
|
||||
// We cannot recreate other states (read, error).
|
||||
state = MessageState::OutDelivered;
|
||||
to_id = to_ids.get_index(0).cloned().unwrap_or_default();
|
||||
to_id = to_ids.get(0).cloned().unwrap_or_default();
|
||||
|
||||
let self_sent = from_id == DC_CONTACT_ID_SELF
|
||||
&& to_ids.len() == 1
|
||||
@@ -1316,7 +1310,7 @@ async fn lookup_chat_by_reply(
|
||||
mime_parser: &mut MimeMessage,
|
||||
parent: &Option<Message>,
|
||||
from_id: u32,
|
||||
to_ids: &ContactIds,
|
||||
to_ids: &[u32],
|
||||
) -> Result<Option<(ChatId, Blocked)>> {
|
||||
// Try to assign message to the same chat as the parent message.
|
||||
|
||||
@@ -1356,7 +1350,7 @@ async fn lookup_chat_by_reply(
|
||||
/// If it returns false, it shall be assigned to the parent chat.
|
||||
async fn is_probably_private_reply(
|
||||
context: &Context,
|
||||
to_ids: &indexmap::IndexSet<u32>,
|
||||
to_ids: &[u32],
|
||||
mime_parser: &MimeMessage,
|
||||
parent_chat_id: ChatId,
|
||||
from_id: u32,
|
||||
@@ -1368,7 +1362,7 @@ async fn is_probably_private_reply(
|
||||
// should be assigned to the group chat. We restrict this exception to classical emails, as chat-group-messages
|
||||
// contain a Chat-Group-Id header and can be sorted into the correct chat this way.
|
||||
|
||||
let private_message = to_ids == &[DC_CONTACT_ID_SELF].iter().copied().collect::<ContactIds>();
|
||||
let private_message = to_ids == [DC_CONTACT_ID_SELF].iter().copied().collect::<Vec<u32>>();
|
||||
if !private_message {
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -1397,7 +1391,7 @@ async fn create_or_lookup_group(
|
||||
allow_creation: bool,
|
||||
create_blocked: Blocked,
|
||||
from_id: u32,
|
||||
to_ids: &ContactIds,
|
||||
to_ids: &[u32],
|
||||
) -> Result<Option<(ChatId, Blocked)>> {
|
||||
let grpid = if let Some(grpid) = try_getting_grpid(mime_parser) {
|
||||
grpid
|
||||
@@ -1541,7 +1535,7 @@ async fn apply_group_changes(
|
||||
sent_timestamp: i64,
|
||||
chat_id: ChatId,
|
||||
from_id: u32,
|
||||
to_ids: &ContactIds,
|
||||
to_ids: &[u32],
|
||||
) -> Result<()> {
|
||||
let mut chat = Chat::load_from_db(context, chat_id).await?;
|
||||
if chat.typ != Chattype::Group {
|
||||
@@ -1981,7 +1975,7 @@ async fn check_verified_properties(
|
||||
context: &Context,
|
||||
mimeparser: &MimeMessage,
|
||||
from_id: u32,
|
||||
to_ids: &ContactIds,
|
||||
to_ids: &[u32],
|
||||
) -> Result<()> {
|
||||
let contact = Contact::load_from_db(context, from_id).await?;
|
||||
|
||||
@@ -2024,8 +2018,11 @@ async fn check_verified_properties(
|
||||
}
|
||||
|
||||
// we do not need to check if we are verified with ourself
|
||||
let mut to_ids = to_ids.clone();
|
||||
to_ids.remove(&DC_CONTACT_ID_SELF);
|
||||
let to_ids = to_ids
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|id| *id != DC_CONTACT_ID_SELF)
|
||||
.collect::<Vec<u32>>();
|
||||
|
||||
if to_ids.is_empty() {
|
||||
return Ok(());
|
||||
@@ -2188,6 +2185,10 @@ pub(crate) async fn get_prefetch_parent_message(
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Looks up contact IDs from the database given the list of recipients.
|
||||
///
|
||||
/// Returns vector of IDs guaranteed to be unique.
|
||||
///
|
||||
/// * param `prevent_rename`: if true, the display_name of this contact will not be changed. Useful for
|
||||
/// mailing lists: In some mailing lists, many users write from the same address but with different
|
||||
/// display names. We don't want the display name to change everytime the user gets a new email from
|
||||
@@ -2197,8 +2198,8 @@ async fn dc_add_or_lookup_contacts_by_address_list(
|
||||
address_list: &[SingleInfo],
|
||||
origin: Origin,
|
||||
prevent_rename: bool,
|
||||
) -> Result<ContactIds> {
|
||||
let mut contact_ids = ContactIds::new();
|
||||
) -> Result<Vec<u32>> {
|
||||
let mut contact_ids = BTreeSet::new();
|
||||
for info in address_list.iter() {
|
||||
let display_name = if prevent_rename {
|
||||
Some("")
|
||||
@@ -2210,7 +2211,7 @@ async fn dc_add_or_lookup_contacts_by_address_list(
|
||||
);
|
||||
}
|
||||
|
||||
Ok(contact_ids)
|
||||
Ok(contact_ids.into_iter().collect::<Vec<u32>>())
|
||||
}
|
||||
|
||||
/// Add contacts to database on receiving messages.
|
||||
|
||||
12
src/quota.rs
12
src/quota.rs
@@ -2,7 +2,7 @@
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_imap::types::{Quota, QuotaResource};
|
||||
use indexmap::IndexMap;
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::chat::add_device_msg_with_importance;
|
||||
use crate::config::Config;
|
||||
@@ -43,7 +43,7 @@ pub struct QuotaInfo {
|
||||
/// set to `Err()` if the provider does not support quota or on other errors,
|
||||
/// set to `Ok()` for valid quota information.
|
||||
/// Updated by `Action::UpdateRecentQuota`
|
||||
pub(crate) recent: Result<IndexMap<String, Vec<QuotaResource>>>,
|
||||
pub(crate) recent: Result<BTreeMap<String, Vec<QuotaResource>>>,
|
||||
|
||||
/// Timestamp when structure was modified.
|
||||
pub(crate) modified: i64,
|
||||
@@ -52,8 +52,8 @@ pub struct QuotaInfo {
|
||||
async fn get_unique_quota_roots_and_usage(
|
||||
folders: Vec<String>,
|
||||
imap: &mut Imap,
|
||||
) -> Result<IndexMap<String, Vec<QuotaResource>>> {
|
||||
let mut unique_quota_roots: IndexMap<String, Vec<QuotaResource>> = IndexMap::new();
|
||||
) -> Result<BTreeMap<String, Vec<QuotaResource>>> {
|
||||
let mut unique_quota_roots: BTreeMap<String, Vec<QuotaResource>> = BTreeMap::new();
|
||||
for folder in folders {
|
||||
let (quota_roots, quotas) = &imap.get_quota_roots(&folder).await?;
|
||||
// if there are new quota roots found in this imap folder, add them to the list
|
||||
@@ -69,7 +69,7 @@ async fn get_unique_quota_roots_and_usage(
|
||||
// messages could be recieved and so the usage could have been changed
|
||||
*unique_quota_roots
|
||||
.entry(quota_root_name.clone())
|
||||
.or_insert(vec![]) = quota.resources;
|
||||
.or_insert_with(Vec::new) = quota.resources;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ async fn get_unique_quota_roots_and_usage(
|
||||
}
|
||||
|
||||
fn get_highest_usage<'t>(
|
||||
unique_quota_roots: &'t IndexMap<String, Vec<QuotaResource>>,
|
||||
unique_quota_roots: &'t BTreeMap<String, Vec<QuotaResource>>,
|
||||
) -> Result<(u64, &'t String, &QuotaResource)> {
|
||||
let mut highest: Option<(u64, &'t String, &QuotaResource)> = None;
|
||||
for (name, resources) in unique_quota_roots {
|
||||
|
||||
Reference in New Issue
Block a user