melib/jmap: use IndexMap instead of HashMap
Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>pull/279/head
parent
c875dda496
commit
37a787e6bb
|
@ -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) => {
|
||||
|
|
|
@ -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>,
|
||||
{
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue