melib/jmap: use IndexMap instead of HashMap

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/279/head
Manos Pitsidianakis 2023-08-28 14:09:36 +03:00
parent c875dda496
commit 37a787e6bb
Signed by: Manos Pitsidianakis
GPG Key ID: 7729C7707F7E09D0
5 changed files with 47 additions and 47 deletions

View File

@ -29,6 +29,7 @@ use std::{
};
use futures::{lock::Mutex as FutureMutex, Stream};
use indexmap::IndexMap;
use isahc::{config::RedirectPolicy, AsyncReadResponseExt, HttpClient};
use serde_json::Value;
use smallvec::SmallVec;
@ -456,19 +457,16 @@ impl MailBackend for JmapType {
};
let mut req = Request::new(conn.request_no.clone());
let creation_id: Id<EmailObject> = "1".to_string().into();
let mut email_imports = HashMap::default();
let mut mailbox_ids = HashMap::default();
mailbox_ids.insert(mailbox_id, true);
email_imports.insert(
creation_id.clone(),
EmailImport::new()
.blob_id(upload_response.blob_id)
.mailbox_ids(mailbox_ids),
);
let import_call: ImportCall = ImportCall::new()
.account_id(conn.mail_account_id())
.emails(email_imports);
.emails(indexmap! {
creation_id.clone() => EmailImport::new()
.blob_id(upload_response.blob_id)
.mailbox_ids(indexmap! {
mailbox_id => true
})
});
req.add_call(&import_call);
let mut res = conn.post_async(None, serde_json::to_string(&req)?).await?;
@ -642,8 +640,8 @@ impl MailBackend for JmapType {
mailboxes_lck[&destination_mailbox_hash].id.clone(),
)
};
let mut update_map: HashMap<Id<EmailObject>, Value> = HashMap::default();
let mut update_keywords: HashMap<String, Value> = HashMap::default();
let mut update_map: IndexMap<Id<EmailObject>, Value> = IndexMap::default();
let mut update_keywords: IndexMap<String, Value> = IndexMap::default();
update_keywords.insert(
format!("mailboxIds/{}", &destination_mailbox_id),
serde_json::json!(true),
@ -711,10 +709,10 @@ impl MailBackend for JmapType {
let store = self.store.clone();
let connection = self.connection.clone();
Ok(Box::pin(async move {
let mut update_map: HashMap<Id<EmailObject>, Value> = HashMap::default();
let mut update_map: IndexMap<Id<EmailObject>, Value> = IndexMap::default();
let mut ids: Vec<Id<EmailObject>> = Vec::with_capacity(env_hashes.rest.len() + 1);
let mut id_map: HashMap<Id<EmailObject>, EnvelopeHash> = HashMap::default();
let mut update_keywords: HashMap<String, Value> = HashMap::default();
let mut id_map: IndexMap<Id<EmailObject>, EnvelopeHash> = IndexMap::default();
let mut update_keywords: IndexMap<String, Value> = IndexMap::default();
for (flag, value) in flags.iter() {
match flag {
Ok(f) => {

View File

@ -19,8 +19,9 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
use std::{collections::HashMap, marker::PhantomData};
use std::marker::PhantomData;
use indexmap::IndexMap;
use serde::de::{Deserialize, Deserializer};
use serde_json::{value::RawValue, Value};
@ -144,7 +145,7 @@ pub struct EmailObject {
#[serde(default)]
pub blob_id: Id<BlobObject>,
#[serde(default)]
pub mailbox_ids: HashMap<Id<MailboxObject>, bool>,
pub mailbox_ids: IndexMap<Id<MailboxObject>, bool>,
#[serde(default)]
pub size: u64,
#[serde(default)]
@ -168,7 +169,7 @@ pub struct EmailObject {
#[serde(default)]
pub references: Option<Vec<String>>,
#[serde(default)]
pub keywords: HashMap<String, bool>,
pub keywords: IndexMap<String, bool>,
#[serde(default)]
pub attached_emails: Option<Id<BlobObject>>,
#[serde(default)]
@ -177,7 +178,7 @@ pub struct EmailObject {
pub has_attachment: bool,
#[serde(default)]
#[serde(deserialize_with = "deserialize_header")]
pub headers: HashMap<String, String>,
pub headers: IndexMap<String, String>,
#[serde(default)]
pub html_body: Vec<HtmlBody>,
#[serde(default)]
@ -191,7 +192,7 @@ pub struct EmailObject {
#[serde(default)]
pub thread_id: Id<ThreadObject>,
#[serde(flatten)]
pub extra: HashMap<String, Value>,
pub extra: IndexMap<String, Value>,
}
/// Deserializer that uses `Default::default()` in place of a present but `null`
@ -207,7 +208,7 @@ where
}
impl EmailObject {
_impl!(get keywords, keywords: HashMap<String, bool>);
_impl!(get keywords, keywords: IndexMap<String, bool>);
}
#[derive(Deserialize, Serialize, Debug, Default)]
@ -219,7 +220,7 @@ pub struct Header {
fn deserialize_header<'de, D>(
deserializer: D,
) -> std::result::Result<HashMap<String, String>, D::Error>
) -> std::result::Result<IndexMap<String, String>, D::Error>
where
D: Deserializer<'de>,
{

View File

@ -19,6 +19,7 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
use indexmap::IndexMap;
use serde_json::value::RawValue;
use super::*;
@ -48,7 +49,7 @@ pub struct ImportCall {
pub if_in_state: Option<State<EmailObject>>,
/// o emails: `Id[EmailImport]`
/// A map of creation id (client specified) to EmailImport objects.
pub emails: HashMap<Id<EmailObject>, EmailImport>,
pub emails: IndexMap<Id<EmailObject>, EmailImport>,
}
#[derive(Deserialize, Serialize, Debug)]
@ -60,10 +61,10 @@ pub struct EmailImport {
/// o mailboxIds: `Id[Boolean]`
/// The ids of the Mailboxes to assign this Email to. At least one
/// Mailbox MUST be given.
pub mailbox_ids: HashMap<Id<MailboxObject>, bool>,
pub mailbox_ids: IndexMap<Id<MailboxObject>, bool>,
/// o keywords: `String[Boolean]` (default: {})
/// The keywords to apply to the Email.
pub keywords: HashMap<String, bool>,
pub keywords: IndexMap<String, bool>,
/// o receivedAt: `UTCDate` (default: time of most recent Received
/// header, or time of import on server if none)
@ -76,7 +77,7 @@ impl ImportCall {
Self {
account_id: Id::new(),
if_in_state: None,
emails: HashMap::default(),
emails: IndexMap::default(),
}
}
@ -87,7 +88,7 @@ impl ImportCall {
account_id: Id<Account>
);
_impl!(if_in_state: Option<State<EmailObject>>);
_impl!(emails: HashMap<Id<EmailObject>, EmailImport>);
_impl!(emails: IndexMap<Id<EmailObject>, EmailImport>);
}
impl Default for ImportCall {
@ -104,15 +105,15 @@ impl EmailImport {
pub fn new() -> Self {
Self {
blob_id: Id::new(),
mailbox_ids: HashMap::default(),
keywords: HashMap::default(),
mailbox_ids: IndexMap::default(),
keywords: IndexMap::default(),
received_at: None,
}
}
_impl!(blob_id: Id<BlobObject>);
_impl!(mailbox_ids: HashMap<Id<MailboxObject>, bool>);
_impl!(keywords: HashMap<String, bool>);
_impl!(mailbox_ids: IndexMap<Id<MailboxObject>, bool>);
_impl!(keywords: IndexMap<String, bool>);
_impl!(received_at: Option<String>);
}
@ -185,13 +186,13 @@ pub struct ImportResponse {
/// A map of the creation id to an object containing the `id`,
/// `blobId`, `threadId`, and `size` properties for each successfully
/// imported Email, or null if none.
pub created: HashMap<Id<EmailObject>, ImportEmailResult>,
pub created: IndexMap<Id<EmailObject>, ImportEmailResult>,
/// o notCreated: `Id[SetError]|null`
/// A map of the creation id to a SetError object for each Email that
/// failed to be created, or null if all successful. The possible
/// errors are defined above.
pub not_created: HashMap<Id<EmailObject>, ImportError>,
pub not_created: IndexMap<Id<EmailObject>, ImportError>,
}
impl std::convert::TryFrom<&RawValue> for ImportResponse {

View File

@ -38,9 +38,8 @@ pub use filters::*;
mod comparator;
pub use comparator::*;
mod argument;
use std::collections::HashMap;
pub use argument::*;
use indexmap::IndexMap;
use super::{deserialize_from_str, protocol::Method};
pub trait Object {
@ -212,9 +211,9 @@ impl<OBJ> State<OBJ> {
#[derive(Deserialize, Serialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct JmapSession {
pub capabilities: HashMap<String, CapabilitiesObject>,
pub accounts: HashMap<Id<Account>, Account>,
pub primary_accounts: HashMap<String, Id<Account>>,
pub capabilities: IndexMap<String, CapabilitiesObject>,
pub accounts: IndexMap<Id<Account>, Account>,
pub primary_accounts: IndexMap<String, Id<Account>>,
pub username: String,
pub api_url: Arc<String>,
pub download_url: Arc<String>,
@ -223,7 +222,7 @@ pub struct JmapSession {
pub event_source_url: Arc<String>,
pub state: State<JmapSession>,
#[serde(flatten)]
pub extra_properties: HashMap<String, Value>,
pub extra_properties: IndexMap<String, Value>,
}
impl Object for JmapSession {
@ -257,9 +256,9 @@ pub struct Account {
pub name: String,
pub is_personal: bool,
pub is_read_only: bool,
pub account_capabilities: HashMap<String, Value>,
pub account_capabilities: IndexMap<String, Value>,
#[serde(flatten)]
pub extra_properties: HashMap<String, Value>,
pub extra_properties: IndexMap<String, Value>,
}
impl Object for Account {
@ -409,7 +408,7 @@ pub struct MethodResponse<'a> {
#[serde(borrow)]
pub method_responses: Vec<&'a RawValue>,
#[serde(default)]
pub created_ids: HashMap<Id<String>, Id<String>>,
pub created_ids: IndexMap<Id<String>, Id<String>>,
#[serde(default)]
pub session_state: State<JmapSession>,
}
@ -736,7 +735,7 @@ where
///
/// The client MUST omit any properties that may only be set by the
/// server (for example, the `id` property on most object types).
pub create: Option<HashMap<Id<OBJ>, OBJ>>,
pub create: Option<IndexMap<Id<OBJ>, OBJ>>,
/// o update: `Id[PatchObject]|null`
///
/// A map of an id to a Patch object to apply to the current Foo
@ -780,7 +779,7 @@ where
/// is also a valid PatchObject. The client may choose to optimise
/// network usage by just sending the diff or may send the whole
/// object; the server processes it the same either way.
pub update: Option<HashMap<Id<OBJ>, Value>>,
pub update: Option<IndexMap<Id<OBJ>, Value>>,
/// o destroy: `Id[]|null`
///
/// A list of ids for Foo objects to permanently delete, or null if no
@ -813,7 +812,7 @@ where
/// state.
if_in_state: Option<State<OBJ>>
);
_impl!(update: Option<HashMap<Id<OBJ>, Value>>);
_impl!(update: Option<IndexMap<Id<OBJ>, Value>>);
}
impl<OBJ> Default for Set<OBJ>
@ -851,7 +850,7 @@ pub struct SetResponse<OBJ: Object> {
/// and thus set to a default by the server.
///
/// This argument is null if no Foo objects were successfully created.
pub created: Option<HashMap<Id<OBJ>, OBJ>>,
pub created: Option<IndexMap<Id<OBJ>, OBJ>>,
/// o updated: `Id[Foo|null]|null`
///
/// The keys in this map are the ids of all Foos that were
@ -863,7 +862,7 @@ pub struct SetResponse<OBJ: Object> {
/// any changes to server-set or computed properties.
///
/// This argument is null if no Foo objects were successfully updated.
pub updated: Option<HashMap<Id<OBJ>, Option<OBJ>>>,
pub updated: Option<IndexMap<Id<OBJ>, Option<OBJ>>>,
/// o destroyed: `Id[]|null`
///
/// A list of Foo ids for records that were successfully destroyed, or

View File

@ -185,6 +185,7 @@ pub extern crate nom;
#[macro_use]
extern crate bitflags;
pub extern crate futures;
#[macro_use]
pub extern crate indexmap;
pub extern crate smallvec;
pub extern crate smol;