use indexmap::IndexMap;
use serde_json::value::RawValue;
use crate::{
error::Result,
jmap::{
deserialize_from_str,
email::EmailObject,
mailbox::MailboxObject,
objects::{Account, BlobObject, Id, State},
protocol::Method,
thread::ThreadObject,
},
};
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EmailImport {
pub account_id: Id<Account>,
#[serde(skip_serializing_if = "Option::is_none")]
pub if_in_state: Option<State<EmailObject>>,
pub emails: IndexMap<Id<EmailObject>, EmailImportObject>,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EmailImportObject {
pub blob_id: Id<BlobObject>,
pub mailbox_ids: IndexMap<Id<MailboxObject>, bool>,
pub keywords: IndexMap<String, bool>,
pub received_at: Option<String>,
}
impl EmailImport {
pub fn new() -> Self {
Self {
account_id: Id::empty(),
if_in_state: None,
emails: IndexMap::default(),
}
}
_impl!(
account_id: Id<Account>
);
_impl!(if_in_state: Option<State<EmailObject>>);
_impl!(emails: IndexMap<Id<EmailObject>, EmailImportObject>);
}
impl Default for EmailImport {
fn default() -> Self {
Self::new()
}
}
impl Method<EmailObject> for EmailImport {
const NAME: &'static str = "Email/import";
}
impl EmailImportObject {
pub fn new() -> Self {
Self {
blob_id: Id::empty(),
mailbox_ids: IndexMap::default(),
keywords: IndexMap::default(),
received_at: None,
}
}
_impl!(blob_id: Id<BlobObject>);
_impl!(mailbox_ids: IndexMap<Id<MailboxObject>, bool>);
_impl!(keywords: IndexMap<String, bool>);
_impl!(received_at: Option<String>);
}
impl Default for EmailImportObject {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "type")]
pub enum EmailImportError {
AlreadyExists {
description: Option<String>,
existing_id: Id<EmailObject>,
},
InvalidProperties {
description: Option<String>,
properties: Vec<String>,
},
OverQuota { description: Option<String> },
InvalidEmail { description: Option<String> },
StateMismatch,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EmailImportResponse {
pub account_id: Id<Account>,
pub old_state: Option<State<EmailObject>>,
pub new_state: State<EmailObject>,
pub created: Option<IndexMap<Id<EmailObject>, EmailImportResult>>,
pub not_created: Option<IndexMap<Id<EmailObject>, EmailImportError>>,
}
impl std::convert::TryFrom<&RawValue> for EmailImportResponse {
type Error = crate::error::Error;
fn try_from(t: &RawValue) -> Result<Self> {
let res: (String, Self, String) = deserialize_from_str(t.get())?;
assert_eq!(&res.0, &EmailImport::NAME);
Ok(res.1)
}
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct EmailImportResult {
pub id: Id<EmailObject>,
pub blob_id: Id<BlobObject>,
pub thread_id: Id<ThreadObject>,
pub size: usize,
}