Initial tests.
parent
e10834ecaa
commit
a23d97e3a4
|
@ -16,7 +16,6 @@ serde = { version = "1.0", features = ["derive"]}
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
chrono = { version = "0.4", features = ["serde"]}
|
chrono = { version = "0.4", features = ["serde"]}
|
||||||
reqwest = "0.11"
|
reqwest = "0.11"
|
||||||
ece = "2.2"
|
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
|
|
||||||
#[dev-dependencies]
|
#[dev-dependencies]
|
||||||
|
|
|
@ -82,4 +82,8 @@ impl UploadResponse {
|
||||||
pub fn size(&self) -> usize {
|
pub fn size(&self) -> usize {
|
||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_blob_id(self) -> String {
|
||||||
|
self.blob_id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,13 @@ use reqwest::{
|
||||||
header::{self},
|
header::{self},
|
||||||
Response,
|
Response,
|
||||||
};
|
};
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
blob,
|
blob,
|
||||||
core::{
|
core::{
|
||||||
request::Request,
|
request::{self, Request},
|
||||||
|
response,
|
||||||
session::{Session, URLPart},
|
session::{Session, URLPart},
|
||||||
},
|
},
|
||||||
event_source, Error,
|
event_source, Error,
|
||||||
|
@ -58,7 +60,7 @@ impl Client {
|
||||||
let default_account_id = session
|
let default_account_id = session
|
||||||
.primary_accounts()
|
.primary_accounts()
|
||||||
.next()
|
.next()
|
||||||
.map(|a| a.0.to_string())
|
.map(|a| a.1.to_string())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
headers.insert(
|
headers.insert(
|
||||||
|
@ -94,8 +96,30 @@ impl Client {
|
||||||
&self.headers
|
&self.headers
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_session(&mut self, new_state: &str) -> crate::Result<()> {
|
pub async fn send<R>(
|
||||||
if new_state != self.session.state() {
|
&mut self,
|
||||||
|
request: &request::Request<'_>,
|
||||||
|
) -> crate::Result<response::Response<R>>
|
||||||
|
where
|
||||||
|
R: DeserializeOwned,
|
||||||
|
{
|
||||||
|
let response: response::Response<R> = serde_json::from_slice(
|
||||||
|
&Client::handle_error(
|
||||||
|
reqwest::Client::builder()
|
||||||
|
.timeout(Duration::from_millis(self.timeout))
|
||||||
|
.default_headers(self.headers.clone())
|
||||||
|
.build()?
|
||||||
|
.post(self.session.api_url())
|
||||||
|
.body(serde_json::to_string(&request)?)
|
||||||
|
.send()
|
||||||
|
.await?,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
.bytes()
|
||||||
|
.await?,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if response.session_state() != self.session.state() {
|
||||||
let session: Session = serde_json::from_slice(
|
let session: Session = serde_json::from_slice(
|
||||||
&Client::handle_error(
|
&Client::handle_error(
|
||||||
reqwest::Client::builder()
|
reqwest::Client::builder()
|
||||||
|
@ -115,7 +139,8 @@ impl Client {
|
||||||
self.event_source_url = URLPart::parse(session.event_source_url())?;
|
self.event_source_url = URLPart::parse(session.event_source_url())?;
|
||||||
self.session = session;
|
self.session = session;
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
|
Ok(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_default_account_id(&mut self, defaul_account_id: impl Into<String>) {
|
pub fn set_default_account_id(&mut self, defaul_account_id: impl Into<String>) {
|
||||||
|
@ -126,7 +151,7 @@ impl Client {
|
||||||
&self.default_account_id
|
&self.default_account_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request(&mut self) -> Request<'_> {
|
pub fn build(&mut self) -> Request<'_> {
|
||||||
Request::new(self)
|
Request::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,18 +179,28 @@ impl Client {
|
||||||
&response.bytes().await?,
|
&response.bytes().await?,
|
||||||
)?))
|
)?))
|
||||||
} else {
|
} else {
|
||||||
Err(Error::ServerError(format!("{}", response.status())))
|
Err(Error::Server(format!("{}", response.status())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::core::response::Response;
|
|
||||||
|
|
||||||
#[test]
|
fn _test_serialize() {
|
||||||
fn test_serialize() {
|
|
||||||
let r: Response = serde_json::from_slice(
|
/*let coco = request
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.unwrap_method_responses()
|
||||||
|
.pop()
|
||||||
|
.unwrap()
|
||||||
|
.unwrap_get_email()
|
||||||
|
.unwrap();*/
|
||||||
|
//coco.list().first().unwrap().subject().unwrap();
|
||||||
|
|
||||||
|
/*let r: Response = serde_json::from_slice(
|
||||||
br#"{"sessionState": "123", "methodResponses": [[ "Email/query", {
|
br#"{"sessionState": "123", "methodResponses": [[ "Email/query", {
|
||||||
"accountId": "A1",
|
"accountId": "A1",
|
||||||
"queryState": "abcdefg",
|
"queryState": "abcdefg",
|
||||||
|
@ -202,9 +237,9 @@ mod tests {
|
||||||
"notFound": []
|
"notFound": []
|
||||||
}, "t2" ]]}"#,
|
}, "t2" ]]}"#,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();*/
|
||||||
|
|
||||||
println!("{:?}", r);
|
//println!("{:?}", r);
|
||||||
|
|
||||||
/*let mut client = Client::connect("coco");
|
/*let mut client = Client::connect("coco");
|
||||||
let mut request = client.request();
|
let mut request = client.request();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, fmt::Display};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ pub struct CopyRequest<T: Create> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct CopyResponse<T, U> {
|
pub struct CopyResponse<T, U: Display> {
|
||||||
#[serde(rename = "fromAccountId")]
|
#[serde(rename = "fromAccountId")]
|
||||||
from_account_id: String,
|
from_account_id: String,
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ impl<T: Create> CopyRequest<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, U> CopyResponse<T, U> {
|
impl<T, U: Display> CopyResponse<T, U> {
|
||||||
pub fn from_account_id(&self) -> &str {
|
pub fn from_account_id(&self) -> &str {
|
||||||
&self.from_account_id
|
&self.from_account_id
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,37 @@ impl MethodError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for MethodError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self.p_type {
|
||||||
|
MethodErrorType::ServerUnavailable => write!(f, "Server unavailable"),
|
||||||
|
MethodErrorType::ServerFail => write!(f, "Server fail"),
|
||||||
|
MethodErrorType::ServerPartialFail => write!(f, "Server partial fail"),
|
||||||
|
MethodErrorType::UnknownMethod => write!(f, "Unknown method"),
|
||||||
|
MethodErrorType::InvalidArguments => write!(f, "Invalid arguments"),
|
||||||
|
MethodErrorType::InvalidResultReference => write!(f, "Invalid result reference"),
|
||||||
|
MethodErrorType::Forbidden => write!(f, "Forbidden"),
|
||||||
|
MethodErrorType::AccountNotFound => write!(f, "Account not found"),
|
||||||
|
MethodErrorType::AccountNotSupportedByMethod => {
|
||||||
|
write!(f, "Account not supported by method")
|
||||||
|
}
|
||||||
|
MethodErrorType::AccountReadOnly => write!(f, "Account read only"),
|
||||||
|
MethodErrorType::RequestTooLarge => write!(f, "Request too large"),
|
||||||
|
MethodErrorType::CannotCalculateChanges => write!(f, "Cannot calculate changes"),
|
||||||
|
MethodErrorType::StateMismatch => write!(f, "State mismatch"),
|
||||||
|
MethodErrorType::AlreadyExists => write!(f, "Already exists"),
|
||||||
|
MethodErrorType::FromAccountNotFound => write!(f, "From account not found"),
|
||||||
|
MethodErrorType::FromAccountNotSupportedByMethod => {
|
||||||
|
write!(f, "From account not supported by method")
|
||||||
|
}
|
||||||
|
MethodErrorType::AnchorNotFound => write!(f, "Anchor not found"),
|
||||||
|
MethodErrorType::UnsupportedSort => write!(f, "Unsupported sort"),
|
||||||
|
MethodErrorType::UnsupportedFilter => write!(f, "Unsupported filter"),
|
||||||
|
MethodErrorType::TooManyChanges => write!(f, "Too many changes"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for ProblemDetails {
|
impl Display for ProblemDetails {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self.p_type {
|
match self.p_type {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{collections::HashMap, time::Duration};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
blob::copy::CopyBlobRequest,
|
blob::copy::CopyBlobRequest,
|
||||||
|
@ -12,18 +12,25 @@ use crate::{
|
||||||
push_subscription::{self, PushSubscription},
|
push_subscription::{self, PushSubscription},
|
||||||
thread,
|
thread,
|
||||||
vacation_response::{self, VacationResponse},
|
vacation_response::{self, VacationResponse},
|
||||||
Method, Set, URI,
|
Error, Method, Set, URI,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
changes::ChangesRequest, copy::CopyRequest, get::GetRequest, query::QueryRequest,
|
changes::ChangesRequest,
|
||||||
query_changes::QueryChangesRequest, response::Response, set::SetRequest,
|
copy::CopyRequest,
|
||||||
|
get::GetRequest,
|
||||||
|
query::QueryRequest,
|
||||||
|
query_changes::QueryChangesRequest,
|
||||||
|
response::{MethodResponse, Response, SingleMethodResponse},
|
||||||
|
set::SetRequest,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct Request<'x> {
|
pub struct Request<'x> {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
client: &'x mut Client,
|
client: Option<&'x mut Client>,
|
||||||
|
#[serde(skip)]
|
||||||
|
default_account_id: String,
|
||||||
|
|
||||||
using: Vec<URI>,
|
using: Vec<URI>,
|
||||||
|
|
||||||
|
@ -399,28 +406,29 @@ impl<'x> Request<'x> {
|
||||||
using: vec![URI::Core, URI::Mail],
|
using: vec![URI::Core, URI::Mail],
|
||||||
method_calls: vec![],
|
method_calls: vec![],
|
||||||
created_ids: None,
|
created_ids: None,
|
||||||
client,
|
default_account_id: client.default_account_id().to_string(),
|
||||||
|
client: client.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(&mut self) -> crate::Result<Response> {
|
pub async fn send(mut self) -> crate::Result<Response<MethodResponse>> {
|
||||||
let response: Response = serde_json::from_slice(
|
Option::take(&mut self.client).unwrap().send(&self).await
|
||||||
&Client::handle_error(
|
}
|
||||||
reqwest::Client::builder()
|
|
||||||
.timeout(Duration::from_millis(self.client.timeout()))
|
pub async fn send_single<T>(mut self) -> crate::Result<T>
|
||||||
.default_headers(self.client.headers().clone())
|
where
|
||||||
.build()?
|
T: DeserializeOwned,
|
||||||
.post(self.client.session().api_url())
|
{
|
||||||
.body(serde_json::to_string(&self)?)
|
let response: Response<SingleMethodResponse<T>> =
|
||||||
.send()
|
Option::take(&mut self.client).unwrap().send(&self).await?;
|
||||||
.await?,
|
match response
|
||||||
)
|
.unwrap_method_responses()
|
||||||
.await?
|
.pop()
|
||||||
.bytes()
|
.ok_or_else(|| Error::Internal("Server returned no results".to_string()))?
|
||||||
.await?,
|
{
|
||||||
)?;
|
SingleMethodResponse::Ok((_, response, _)) => Ok(response),
|
||||||
self.client.update_session(response.session_state()).await?;
|
SingleMethodResponse::Error((_, err, _)) => Err(err.into()),
|
||||||
Ok(response)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_method_call(&mut self, method: Method, arguments: Arguments) -> &mut Arguments {
|
fn add_method_call(&mut self, method: Method, arguments: Arguments) -> &mut Arguments {
|
||||||
|
@ -432,7 +440,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn get_push(&mut self) -> &mut GetRequest<push_subscription::Property, ()> {
|
pub fn get_push(&mut self) -> &mut GetRequest<push_subscription::Property, ()> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::GetPushSubscription,
|
Method::GetPushSubscription,
|
||||||
Arguments::push_get(self.client.default_account_id().to_string()),
|
Arguments::push_get(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.push_get_mut()
|
.push_get_mut()
|
||||||
}
|
}
|
||||||
|
@ -440,7 +448,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn set_push(&mut self) -> &mut SetRequest<PushSubscription<Set>, ()> {
|
pub fn set_push(&mut self) -> &mut SetRequest<PushSubscription<Set>, ()> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::SetPushSubscription,
|
Method::SetPushSubscription,
|
||||||
Arguments::push_set(self.client.default_account_id().to_string()),
|
Arguments::push_set(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.push_set_mut()
|
.push_set_mut()
|
||||||
}
|
}
|
||||||
|
@ -460,7 +468,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn get_mailbox(&mut self) -> &mut GetRequest<mailbox::Property, ()> {
|
pub fn get_mailbox(&mut self) -> &mut GetRequest<mailbox::Property, ()> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::GetMailbox,
|
Method::GetMailbox,
|
||||||
Arguments::mailbox_get(self.client.default_account_id().to_string()),
|
Arguments::mailbox_get(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.mailbox_get_mut()
|
.mailbox_get_mut()
|
||||||
}
|
}
|
||||||
|
@ -468,10 +476,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn changes_mailbox(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
pub fn changes_mailbox(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::ChangesMailbox,
|
Method::ChangesMailbox,
|
||||||
Arguments::changes(
|
Arguments::changes(self.default_account_id.clone(), since_state.into()),
|
||||||
self.client.default_account_id().to_string(),
|
|
||||||
since_state.into(),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.changes_mut()
|
.changes_mut()
|
||||||
}
|
}
|
||||||
|
@ -485,7 +490,7 @@ impl<'x> Request<'x> {
|
||||||
> {
|
> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::QueryMailbox,
|
Method::QueryMailbox,
|
||||||
Arguments::mailbox_query(self.client.default_account_id().to_string()),
|
Arguments::mailbox_query(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.mailbox_query_mut()
|
.mailbox_query_mut()
|
||||||
}
|
}
|
||||||
|
@ -501,7 +506,7 @@ impl<'x> Request<'x> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::QueryChangesMailbox,
|
Method::QueryChangesMailbox,
|
||||||
Arguments::mailbox_query_changes(
|
Arguments::mailbox_query_changes(
|
||||||
self.client.default_account_id().to_string(),
|
self.default_account_id.clone(),
|
||||||
since_query_state.into(),
|
since_query_state.into(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -511,7 +516,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn set_mailbox(&mut self) -> &mut SetRequest<Mailbox<Set>, mailbox::SetArguments> {
|
pub fn set_mailbox(&mut self) -> &mut SetRequest<Mailbox<Set>, mailbox::SetArguments> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::SetMailbox,
|
Method::SetMailbox,
|
||||||
Arguments::mailbox_set(self.client.default_account_id().to_string()),
|
Arguments::mailbox_set(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.mailbox_set_mut()
|
.mailbox_set_mut()
|
||||||
}
|
}
|
||||||
|
@ -519,7 +524,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn get_thread(&mut self) -> &mut GetRequest<thread::Property, ()> {
|
pub fn get_thread(&mut self) -> &mut GetRequest<thread::Property, ()> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::GetThread,
|
Method::GetThread,
|
||||||
Arguments::thread_get(self.client.default_account_id().to_string()),
|
Arguments::thread_get(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.thread_get_mut()
|
.thread_get_mut()
|
||||||
}
|
}
|
||||||
|
@ -527,17 +532,14 @@ impl<'x> Request<'x> {
|
||||||
pub fn changes_thread(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
pub fn changes_thread(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::ChangesThread,
|
Method::ChangesThread,
|
||||||
Arguments::changes(
|
Arguments::changes(self.default_account_id.clone(), since_state.into()),
|
||||||
self.client.default_account_id().to_string(),
|
|
||||||
since_state.into(),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.changes_mut()
|
.changes_mut()
|
||||||
}
|
}
|
||||||
pub fn get_email(&mut self) -> &mut GetRequest<email::Property, email::GetArguments> {
|
pub fn get_email(&mut self) -> &mut GetRequest<email::Property, email::GetArguments> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::GetEmail,
|
Method::GetEmail,
|
||||||
Arguments::email_get(self.client.default_account_id().to_string()),
|
Arguments::email_get(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.email_get_mut()
|
.email_get_mut()
|
||||||
}
|
}
|
||||||
|
@ -545,10 +547,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn changes_email(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
pub fn changes_email(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::ChangesEmail,
|
Method::ChangesEmail,
|
||||||
Arguments::changes(
|
Arguments::changes(self.default_account_id.clone(), since_state.into()),
|
||||||
self.client.default_account_id().to_string(),
|
|
||||||
since_state.into(),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.changes_mut()
|
.changes_mut()
|
||||||
}
|
}
|
||||||
|
@ -559,7 +558,7 @@ impl<'x> Request<'x> {
|
||||||
{
|
{
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::QueryEmail,
|
Method::QueryEmail,
|
||||||
Arguments::email_query(self.client.default_account_id().to_string()),
|
Arguments::email_query(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.email_query_mut()
|
.email_query_mut()
|
||||||
}
|
}
|
||||||
|
@ -575,7 +574,7 @@ impl<'x> Request<'x> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::QueryChangesEmail,
|
Method::QueryChangesEmail,
|
||||||
Arguments::email_query_changes(
|
Arguments::email_query_changes(
|
||||||
self.client.default_account_id().to_string(),
|
self.default_account_id.clone(),
|
||||||
since_query_state.into(),
|
since_query_state.into(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -585,7 +584,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn set_email(&mut self) -> &mut SetRequest<Email<Set>, ()> {
|
pub fn set_email(&mut self) -> &mut SetRequest<Email<Set>, ()> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::SetEmail,
|
Method::SetEmail,
|
||||||
Arguments::email_set(self.client.default_account_id().to_string()),
|
Arguments::email_set(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.email_set_mut()
|
.email_set_mut()
|
||||||
}
|
}
|
||||||
|
@ -605,7 +604,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn import_email(&mut self) -> &mut EmailImportRequest {
|
pub fn import_email(&mut self) -> &mut EmailImportRequest {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::ImportEmail,
|
Method::ImportEmail,
|
||||||
Arguments::email_import(self.client.default_account_id().to_string()),
|
Arguments::email_import(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.email_import_mut()
|
.email_import_mut()
|
||||||
}
|
}
|
||||||
|
@ -613,7 +612,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn parse_email(&mut self) -> &mut EmailParseRequest {
|
pub fn parse_email(&mut self) -> &mut EmailParseRequest {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::ParseEmail,
|
Method::ParseEmail,
|
||||||
Arguments::email_parse(self.client.default_account_id().to_string()),
|
Arguments::email_parse(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.email_parse_mut()
|
.email_parse_mut()
|
||||||
}
|
}
|
||||||
|
@ -621,7 +620,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn get_identity(&mut self) -> &mut GetRequest<identity::Property, ()> {
|
pub fn get_identity(&mut self) -> &mut GetRequest<identity::Property, ()> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::GetIdentity,
|
Method::GetIdentity,
|
||||||
Arguments::identity_get(self.client.default_account_id().to_string()),
|
Arguments::identity_get(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.identity_get_mut()
|
.identity_get_mut()
|
||||||
}
|
}
|
||||||
|
@ -629,7 +628,7 @@ impl<'x> Request<'x> {
|
||||||
pub fn set_identity(&mut self) -> &mut SetRequest<Identity<Set>, ()> {
|
pub fn set_identity(&mut self) -> &mut SetRequest<Identity<Set>, ()> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::SetIdentity,
|
Method::SetIdentity,
|
||||||
Arguments::identity_set(self.client.default_account_id().to_string()),
|
Arguments::identity_set(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.identity_set_mut()
|
.identity_set_mut()
|
||||||
}
|
}
|
||||||
|
@ -640,7 +639,7 @@ impl<'x> Request<'x> {
|
||||||
}
|
}
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::GetEmailSubmission,
|
Method::GetEmailSubmission,
|
||||||
Arguments::email_submission_get(self.client.default_account_id().to_string()),
|
Arguments::email_submission_get(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.email_submission_get_mut()
|
.email_submission_get_mut()
|
||||||
}
|
}
|
||||||
|
@ -654,10 +653,7 @@ impl<'x> Request<'x> {
|
||||||
}
|
}
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::ChangesEmailSubmission,
|
Method::ChangesEmailSubmission,
|
||||||
Arguments::changes(
|
Arguments::changes(self.default_account_id.clone(), since_state.into()),
|
||||||
self.client.default_account_id().to_string(),
|
|
||||||
since_state.into(),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.changes_mut()
|
.changes_mut()
|
||||||
}
|
}
|
||||||
|
@ -671,7 +667,7 @@ impl<'x> Request<'x> {
|
||||||
}
|
}
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::QueryEmailSubmission,
|
Method::QueryEmailSubmission,
|
||||||
Arguments::email_submission_query(self.client.default_account_id().to_string()),
|
Arguments::email_submission_query(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.email_submission_query_mut()
|
.email_submission_query_mut()
|
||||||
}
|
}
|
||||||
|
@ -690,7 +686,7 @@ impl<'x> Request<'x> {
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::QueryChangesEmailSubmission,
|
Method::QueryChangesEmailSubmission,
|
||||||
Arguments::email_submission_query_changes(
|
Arguments::email_submission_query_changes(
|
||||||
self.client.default_account_id().to_string(),
|
self.default_account_id.clone(),
|
||||||
since_query_state.into(),
|
since_query_state.into(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -705,7 +701,7 @@ impl<'x> Request<'x> {
|
||||||
}
|
}
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::SetEmailSubmission,
|
Method::SetEmailSubmission,
|
||||||
Arguments::email_submission_set(self.client.default_account_id().to_string()),
|
Arguments::email_submission_set(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.email_submission_set_mut()
|
.email_submission_set_mut()
|
||||||
}
|
}
|
||||||
|
@ -716,7 +712,7 @@ impl<'x> Request<'x> {
|
||||||
}
|
}
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::GetVacationResponse,
|
Method::GetVacationResponse,
|
||||||
Arguments::vacation_response_get(self.client.default_account_id().to_string()),
|
Arguments::vacation_response_get(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.vacation_response_get_mut()
|
.vacation_response_get_mut()
|
||||||
}
|
}
|
||||||
|
@ -727,7 +723,7 @@ impl<'x> Request<'x> {
|
||||||
}
|
}
|
||||||
self.add_method_call(
|
self.add_method_call(
|
||||||
Method::SetVacationResponse,
|
Method::SetVacationResponse,
|
||||||
Arguments::vacation_response_set(self.client.default_account_id().to_string()),
|
Arguments::vacation_response_set(self.default_account_id.clone()),
|
||||||
)
|
)
|
||||||
.vacation_response_set_mut()
|
.vacation_response_set_mut()
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@ use super::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Response {
|
pub struct Response<T> {
|
||||||
#[serde(rename = "methodResponses")]
|
#[serde(rename = "methodResponses")]
|
||||||
method_responses: Vec<MethodResponse>,
|
method_responses: Vec<T>,
|
||||||
|
|
||||||
#[serde(rename = "createdIds")]
|
#[serde(rename = "createdIds")]
|
||||||
created_ids: Option<HashMap<String, String>>,
|
created_ids: Option<HashMap<String, String>>,
|
||||||
|
@ -31,15 +31,13 @@ pub struct Response {
|
||||||
session_state: String,
|
session_state: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Response {
|
impl<T> Response<T> {
|
||||||
pub fn method_responses(&self) -> &[MethodResponse] {
|
pub fn method_responses(&self) -> &[T] {
|
||||||
self.method_responses.as_ref()
|
self.method_responses.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn method_response(&self, id: &str) -> Option<&MethodResponse> {
|
pub fn unwrap_method_responses(self) -> Vec<T> {
|
||||||
self.method_responses
|
self.method_responses
|
||||||
.iter()
|
|
||||||
.find(|response| response.call_id() == id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn created_ids(&self) -> Option<impl Iterator<Item = (&String, &String)>> {
|
pub fn created_ids(&self) -> Option<impl Iterator<Item = (&String, &String)>> {
|
||||||
|
@ -51,92 +49,82 @@ impl Response {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Response<MethodResponse> {
|
||||||
|
pub fn method_response(&self, id: &str) -> Option<&MethodResponse> {
|
||||||
|
self.method_responses
|
||||||
|
.iter()
|
||||||
|
.find(|response| response.call_id() == id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum SingleMethodResponse<T> {
|
||||||
|
Error((Error, MethodError, String)),
|
||||||
|
Ok((String, T, String)),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type PushSubscriptionSetResponse =
|
||||||
|
SetResponse<PushSubscription<Get>, push_subscription::Property>;
|
||||||
|
pub type PushSubscriptionGetResponse = GetResponse<PushSubscription<Get>>;
|
||||||
|
pub type MaiboxChangesResponse = ChangesResponse<mailbox::ChangesResponse>;
|
||||||
|
pub type MailboxSetResponse = SetResponse<Mailbox<Get>, mailbox::Property>;
|
||||||
|
pub type MailboxGetResponse = GetResponse<Mailbox<Get>>;
|
||||||
|
pub type ThreadGetResponse = GetResponse<Thread>;
|
||||||
|
pub type ThreadChangesResponse = ChangesResponse<()>;
|
||||||
|
pub type EmailGetResponse = GetResponse<Email<Get>>;
|
||||||
|
pub type EmailSetResponse = SetResponse<Email<Get>, email::Property>;
|
||||||
|
pub type EmailCopyResponse = CopyResponse<Email<Get>, email::Property>;
|
||||||
|
pub type EmailChangesResponse = ChangesResponse<()>;
|
||||||
|
pub type SearchSnippetGetResponse = GetResponse<String>;
|
||||||
|
pub type IdentitySetResponse = SetResponse<Identity<Get>, identity::Property>;
|
||||||
|
pub type IdentityGetResponse = GetResponse<Identity<Get>>;
|
||||||
|
pub type IdentityChangesResponse = ChangesResponse<()>;
|
||||||
|
pub type EmailSubmissionSetResponse = SetResponse<EmailSubmission<Get>, email_submission::Property>;
|
||||||
|
pub type EmailSubmissionGetResponse = GetResponse<EmailSubmission<Get>>;
|
||||||
|
pub type EmailSubmissionChangesResponse = ChangesResponse<()>;
|
||||||
|
pub type VacationResponseGetResponse = GetResponse<VacationResponse<Get>>;
|
||||||
|
pub type VacationResponseSetResponse =
|
||||||
|
SetResponse<VacationResponse<Get>, vacation_response::Property>;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum MethodResponse {
|
pub enum MethodResponse {
|
||||||
CopyBlob((CopyBlob, CopyBlobResponse, String)),
|
CopyBlob((CopyBlob, CopyBlobResponse, String)),
|
||||||
GetPushSubscription(
|
GetPushSubscription((GetPushSubscription, PushSubscriptionGetResponse, String)),
|
||||||
(
|
SetPushSubscription((SetPushSubscription, PushSubscriptionSetResponse, String)),
|
||||||
GetPushSubscription,
|
GetMailbox((GetMailbox, MailboxGetResponse, String)),
|
||||||
GetResponse<PushSubscription<Get>>,
|
ChangesMailbox((ChangesMailbox, MaiboxChangesResponse, String)),
|
||||||
String,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SetPushSubscription(
|
|
||||||
(
|
|
||||||
SetPushSubscription,
|
|
||||||
SetResponse<PushSubscription<Get>, push_subscription::Property>,
|
|
||||||
String,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
GetMailbox((GetMailbox, GetResponse<Mailbox<Get>>, String)),
|
|
||||||
ChangesMailbox(
|
|
||||||
(
|
|
||||||
ChangesMailbox,
|
|
||||||
ChangesResponse<mailbox::ChangesResponse>,
|
|
||||||
String,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
QueryMailbox((QueryMailbox, QueryResponse, String)),
|
QueryMailbox((QueryMailbox, QueryResponse, String)),
|
||||||
QueryChangesMailbox((QueryChangesMailbox, QueryChangesResponse, String)),
|
QueryChangesMailbox((QueryChangesMailbox, QueryChangesResponse, String)),
|
||||||
SetMailbox(
|
SetMailbox((SetMailbox, MailboxSetResponse, String)),
|
||||||
(
|
GetThread((GetThread, ThreadGetResponse, String)),
|
||||||
SetMailbox,
|
ChangesThread((ChangesThread, ThreadChangesResponse, String)),
|
||||||
SetResponse<Mailbox<Get>, mailbox::Property>,
|
GetEmail((GetEmail, EmailGetResponse, String)),
|
||||||
String,
|
ChangesEmail((ChangesEmail, EmailChangesResponse, String)),
|
||||||
),
|
|
||||||
),
|
|
||||||
GetThread((GetThread, GetResponse<Thread>, String)),
|
|
||||||
ChangesThread((ChangesThread, ChangesResponse<()>, String)),
|
|
||||||
GetEmail((GetEmail, GetResponse<Email<Get>>, String)),
|
|
||||||
ChangesEmail((ChangesEmail, ChangesResponse<()>, String)),
|
|
||||||
QueryEmail((QueryEmail, QueryResponse, String)),
|
QueryEmail((QueryEmail, QueryResponse, String)),
|
||||||
QueryChangesEmail((QueryChangesEmail, QueryChangesResponse, String)),
|
QueryChangesEmail((QueryChangesEmail, QueryChangesResponse, String)),
|
||||||
SetEmail((SetEmail, SetResponse<Email<Get>, email::Property>, String)),
|
SetEmail((SetEmail, EmailSetResponse, String)),
|
||||||
CopyEmail((CopyEmail, CopyResponse<Email<Get>, email::Property>, String)),
|
CopyEmail((CopyEmail, EmailCopyResponse, String)),
|
||||||
ImportEmail((ImportEmail, EmailImportResponse, String)),
|
ImportEmail((ImportEmail, EmailImportResponse, String)),
|
||||||
ParseEmail((ParseEmail, EmailParseResponse, String)),
|
ParseEmail((ParseEmail, EmailParseResponse, String)),
|
||||||
GetSearchSnippet((GetSearchSnippet, GetResponse<String>, String)),
|
GetSearchSnippet((GetSearchSnippet, SearchSnippetGetResponse, String)),
|
||||||
GetIdentity((GetIdentity, GetResponse<Identity<Get>>, String)),
|
GetIdentity((GetIdentity, IdentityGetResponse, String)),
|
||||||
ChangesIdentity((ChangesIdentity, ChangesResponse<()>, String)),
|
ChangesIdentity((ChangesIdentity, IdentityChangesResponse, String)),
|
||||||
SetIdentity(
|
SetIdentity((SetIdentity, IdentitySetResponse, String)),
|
||||||
|
GetEmailSubmission((GetEmailSubmission, EmailSubmissionGetResponse, String)),
|
||||||
|
ChangesEmailSubmission(
|
||||||
(
|
(
|
||||||
SetIdentity,
|
ChangesEmailSubmission,
|
||||||
SetResponse<Identity<Get>, identity::Property>,
|
EmailSubmissionChangesResponse,
|
||||||
String,
|
String,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GetEmailSubmission(
|
|
||||||
(
|
|
||||||
GetEmailSubmission,
|
|
||||||
GetResponse<EmailSubmission<Get>>,
|
|
||||||
String,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
ChangesEmailSubmission((ChangesEmailSubmission, ChangesResponse<()>, String)),
|
|
||||||
QueryEmailSubmission((QueryEmailSubmission, QueryResponse, String)),
|
QueryEmailSubmission((QueryEmailSubmission, QueryResponse, String)),
|
||||||
QueryChangesEmailSubmission((QueryChangesEmailSubmission, QueryChangesResponse, String)),
|
QueryChangesEmailSubmission((QueryChangesEmailSubmission, QueryChangesResponse, String)),
|
||||||
SetEmailSubmission(
|
SetEmailSubmission((SetEmailSubmission, EmailSubmissionSetResponse, String)),
|
||||||
(
|
GetVacationResponse((GetVacationResponse, VacationResponseGetResponse, String)),
|
||||||
SetEmailSubmission,
|
SetVacationResponse((SetVacationResponse, VacationResponseSetResponse, String)),
|
||||||
SetResponse<EmailSubmission<Get>, email_submission::Property>,
|
|
||||||
String,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
GetVacationResponse(
|
|
||||||
(
|
|
||||||
GetVacationResponse,
|
|
||||||
GetResponse<VacationResponse<Get>>,
|
|
||||||
String,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SetVacationResponse(
|
|
||||||
(
|
|
||||||
SetVacationResponse,
|
|
||||||
SetResponse<VacationResponse<Get>, vacation_response::Property>,
|
|
||||||
String,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Echo((Echo, serde_json::Value, String)),
|
Echo((Echo, serde_json::Value, String)),
|
||||||
Error((Error, MethodError, String)),
|
Error((Error, MethodError, String)),
|
||||||
}
|
}
|
||||||
|
@ -221,226 +209,243 @@ impl MethodResponse {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_copy_copy(&self) -> Option<&CopyBlobResponse> {
|
pub fn unwrap_copy_blob(self) -> crate::Result<CopyBlobResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::CopyBlob((_, response, _)) => response.into(),
|
Self::CopyBlob((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_get_push_subscription(&self) -> Option<&GetResponse<PushSubscription<Get>>> {
|
pub fn unwrap_get_push_subscription(self) -> crate::Result<PushSubscriptionGetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::GetPushSubscription((_, response, _)) => response.into(),
|
Self::GetPushSubscription((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_set_push_subscription(
|
pub fn unwrap_set_push_subscription(self) -> crate::Result<PushSubscriptionSetResponse> {
|
||||||
&self,
|
|
||||||
) -> Option<&SetResponse<PushSubscription<Get>, push_subscription::Property>> {
|
|
||||||
match self {
|
match self {
|
||||||
Self::SetPushSubscription((_, response, _)) => response.into(),
|
Self::SetPushSubscription((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_get_mailbox(&self) -> Option<&GetResponse<Mailbox<Get>>> {
|
pub fn unwrap_get_mailbox(self) -> crate::Result<MailboxGetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::GetMailbox((_, response, _)) => response.into(),
|
Self::GetMailbox((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_changes_mailbox(&self) -> Option<&ChangesResponse<mailbox::ChangesResponse>> {
|
pub fn unwrap_changes_mailbox(self) -> crate::Result<MaiboxChangesResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::ChangesMailbox((_, response, _)) => response.into(),
|
Self::ChangesMailbox((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_query_mailbox(&self) -> Option<&QueryResponse> {
|
pub fn unwrap_query_mailbox(self) -> crate::Result<QueryResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::QueryMailbox((_, response, _)) => response.into(),
|
Self::QueryMailbox((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_query_changes_mailbox(&self) -> Option<&QueryChangesResponse> {
|
pub fn unwrap_query_changes_mailbox(self) -> crate::Result<QueryChangesResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::QueryChangesMailbox((_, response, _)) => response.into(),
|
Self::QueryChangesMailbox((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_set_mailbox(&self) -> Option<&SetResponse<Mailbox<Get>, mailbox::Property>> {
|
pub fn unwrap_set_mailbox(self) -> crate::Result<MailboxSetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::SetMailbox((_, response, _)) => response.into(),
|
Self::SetMailbox((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_get_thread(&self) -> Option<&GetResponse<Thread>> {
|
pub fn unwrap_get_thread(self) -> crate::Result<ThreadGetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::GetThread((_, response, _)) => response.into(),
|
Self::GetThread((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_changes_thread(&self) -> Option<&ChangesResponse<()>> {
|
pub fn unwrap_changes_thread(self) -> crate::Result<ThreadChangesResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::ChangesThread((_, response, _)) => response.into(),
|
Self::ChangesThread((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_get_email(&self) -> Option<&GetResponse<Email>> {
|
pub fn unwrap_get_email(self) -> crate::Result<EmailGetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::GetEmail((_, response, _)) => response.into(),
|
Self::GetEmail((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_changes_email(&self) -> Option<&ChangesResponse<()>> {
|
pub fn unwrap_changes_email(self) -> crate::Result<EmailChangesResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::ChangesEmail((_, response, _)) => response.into(),
|
Self::ChangesEmail((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_query_email(&self) -> Option<&QueryResponse> {
|
pub fn unwrap_query_email(self) -> crate::Result<QueryResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::QueryEmail((_, response, _)) => response.into(),
|
Self::QueryEmail((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_query_changes_email(&self) -> Option<&QueryChangesResponse> {
|
pub fn unwrap_query_changes_email(self) -> crate::Result<QueryChangesResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::QueryChangesEmail((_, response, _)) => response.into(),
|
Self::QueryChangesEmail((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_set_email(&self) -> Option<&SetResponse<Email, email::Property>> {
|
pub fn unwrap_set_email(self) -> crate::Result<EmailSetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::SetEmail((_, response, _)) => response.into(),
|
Self::SetEmail((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_copy_email(&self) -> Option<&CopyResponse<Email<Get>, email::Property>> {
|
pub fn unwrap_copy_email(self) -> crate::Result<EmailCopyResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::CopyEmail((_, response, _)) => response.into(),
|
Self::CopyEmail((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_import_email(&self) -> Option<&EmailImportResponse> {
|
pub fn unwrap_import_email(self) -> crate::Result<EmailImportResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::ImportEmail((_, response, _)) => response.into(),
|
Self::ImportEmail((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_parse_email(&self) -> Option<&EmailParseResponse> {
|
pub fn unwrap_parse_email(self) -> crate::Result<EmailParseResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::ParseEmail((_, response, _)) => response.into(),
|
Self::ParseEmail((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_get_search_snippet(&self) -> Option<&GetResponse<String>> {
|
pub fn unwrap_get_search_snippet(self) -> crate::Result<SearchSnippetGetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::GetSearchSnippet((_, response, _)) => response.into(),
|
Self::GetSearchSnippet((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_get_identity(&self) -> Option<&GetResponse<Identity>> {
|
pub fn unwrap_get_identity(self) -> crate::Result<IdentityGetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::GetIdentity((_, response, _)) => response.into(),
|
Self::GetIdentity((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_changes_identity(&self) -> Option<&ChangesResponse<()>> {
|
pub fn unwrap_changes_identity(self) -> crate::Result<IdentityChangesResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::ChangesIdentity((_, response, _)) => response.into(),
|
Self::ChangesIdentity((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_set_identity(&self) -> Option<&SetResponse<Identity, identity::Property>> {
|
pub fn unwrap_set_identity(self) -> crate::Result<IdentitySetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::SetIdentity((_, response, _)) => response.into(),
|
Self::SetIdentity((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_get_email_submission(&self) -> Option<&GetResponse<EmailSubmission>> {
|
pub fn unwrap_get_email_submission(self) -> crate::Result<EmailSubmissionGetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::GetEmailSubmission((_, response, _)) => response.into(),
|
Self::GetEmailSubmission((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_changes_email_submission(&self) -> Option<&ChangesResponse<()>> {
|
pub fn unwrap_changes_email_submission(self) -> crate::Result<EmailSubmissionChangesResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::ChangesEmailSubmission((_, response, _)) => response.into(),
|
Self::ChangesEmailSubmission((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_set_email_submission(
|
pub fn unwrap_set_email_submission(self) -> crate::Result<EmailSubmissionSetResponse> {
|
||||||
&self,
|
|
||||||
) -> Option<&SetResponse<EmailSubmission, email_submission::Property>> {
|
|
||||||
match self {
|
match self {
|
||||||
Self::SetEmailSubmission((_, response, _)) => response.into(),
|
Self::SetEmailSubmission((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_query_email_submission(&self) -> Option<&QueryResponse> {
|
pub fn unwrap_query_email_submission(self) -> crate::Result<QueryResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::QueryEmailSubmission((_, response, _)) => response.into(),
|
Self::QueryEmailSubmission((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_query_changes_email_submission(&self) -> Option<&QueryChangesResponse> {
|
pub fn unwrap_query_changes_email_submission(self) -> crate::Result<QueryChangesResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::QueryChangesEmailSubmission((_, response, _)) => response.into(),
|
Self::QueryChangesEmailSubmission((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_get_vacation_response(&self) -> Option<&GetResponse<VacationResponse>> {
|
pub fn unwrap_get_vacation_response(self) -> crate::Result<VacationResponseGetResponse> {
|
||||||
match self {
|
match self {
|
||||||
Self::GetVacationResponse((_, response, _)) => response.into(),
|
Self::GetVacationResponse((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_set_vacation_response(
|
pub fn unwrap_set_vacation_response(self) -> crate::Result<VacationResponseSetResponse> {
|
||||||
&self,
|
|
||||||
) -> Option<&SetResponse<VacationResponse, vacation_response::Property>> {
|
|
||||||
match self {
|
match self {
|
||||||
Self::SetVacationResponse((_, response, _)) => response.into(),
|
Self::SetVacationResponse((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_echo(&self) -> Option<&serde_json::Value> {
|
pub fn unwrap_echo(self) -> crate::Result<serde_json::Value> {
|
||||||
match self {
|
match self {
|
||||||
Self::Echo((_, response, _)) => response.into(),
|
Self::Echo((_, response, _)) => Ok(response),
|
||||||
_ => None,
|
Self::Error((_, err, _)) => Err(err.into()),
|
||||||
}
|
_ => Err("Response type mismatch".into()),
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_error(&self) -> Option<&MethodError> {
|
|
||||||
match self {
|
|
||||||
Self::Error((_, response, _)) => response.into(),
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::email::{MailCapabilities, SubmissionCapabilities};
|
use crate::email::{MailCapabilities, SubmissionCapabilities};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
#[serde(rename = "capabilities")]
|
#[serde(rename = "capabilities")]
|
||||||
capabilities: HashMap<String, Capabilities>,
|
capabilities: HashMap<String, Capabilities>,
|
||||||
|
@ -34,7 +34,7 @@ pub struct Session {
|
||||||
state: String,
|
state: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Account {
|
pub struct Account {
|
||||||
#[serde(rename = "name")]
|
#[serde(rename = "name")]
|
||||||
name: String,
|
name: String,
|
||||||
|
@ -49,7 +49,7 @@ pub struct Account {
|
||||||
account_capabilities: HashMap<String, Capabilities>,
|
account_capabilities: HashMap<String, Capabilities>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum Capabilities {
|
pub enum Capabilities {
|
||||||
Core(CoreCapabilities),
|
Core(CoreCapabilities),
|
||||||
|
@ -59,7 +59,7 @@ pub enum Capabilities {
|
||||||
Other(serde_json::Value),
|
Other(serde_json::Value),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct CoreCapabilities {
|
pub struct CoreCapabilities {
|
||||||
#[serde(rename = "maxSizeUpload")]
|
#[serde(rename = "maxSizeUpload")]
|
||||||
max_size_upload: usize,
|
max_size_upload: usize,
|
||||||
|
@ -86,7 +86,7 @@ pub struct CoreCapabilities {
|
||||||
collation_algorithms: Vec<String>,
|
collation_algorithms: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct EmptyCapabilities {}
|
pub struct EmptyCapabilities {}
|
||||||
|
|
||||||
impl Session {
|
impl Session {
|
||||||
|
@ -235,6 +235,14 @@ impl<T: URLParser> URLPart<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !buf.is_empty() {
|
||||||
|
if !in_parameter {
|
||||||
|
parts.push(URLPart::Value(buf.clone()));
|
||||||
|
} else {
|
||||||
|
return Err(crate::Error::Internal(format!("Invalid URL: {}", url)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(parts)
|
Ok(parts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
177
src/core/set.rs
177
src/core/set.rs
|
@ -1,6 +1,11 @@
|
||||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fmt::{self, Display, Formatter},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::Error;
|
||||||
|
|
||||||
use super::request::ResultReference;
|
use super::request::ResultReference;
|
||||||
|
|
||||||
|
@ -32,7 +37,7 @@ pub struct SetRequest<T: Create, A: Default> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct SetResponse<T, U> {
|
pub struct SetResponse<T, U: Display> {
|
||||||
#[serde(rename = "accountId")]
|
#[serde(rename = "accountId")]
|
||||||
account_id: String,
|
account_id: String,
|
||||||
|
|
||||||
|
@ -62,7 +67,10 @@ pub struct SetResponse<T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct SetError<U> {
|
pub struct SetError<U>
|
||||||
|
where
|
||||||
|
U: Display,
|
||||||
|
{
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
type_: SetErrorType,
|
type_: SetErrorType,
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
|
@ -189,7 +197,7 @@ impl<T: Create, A: Default> SetRequest<T, A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, U> SetResponse<T, U> {
|
impl<T, U: Display> SetResponse<T, U> {
|
||||||
pub fn account_id(&self) -> &str {
|
pub fn account_id(&self) -> &str {
|
||||||
&self.account_id
|
&self.account_id
|
||||||
}
|
}
|
||||||
|
@ -202,52 +210,66 @@ impl<T, U> SetResponse<T, U> {
|
||||||
&self.new_state
|
&self.new_state
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn created(&self) -> Option<impl Iterator<Item = (&String, &T)>> {
|
pub fn created(&mut self, id: &str) -> crate::Result<T> {
|
||||||
self.created.as_ref().map(|map| map.iter())
|
if let Some(result) = self.created.as_mut().and_then(|r| r.remove(id)) {
|
||||||
}
|
Ok(result)
|
||||||
|
} else if let Some(error) = self.not_created.as_mut().and_then(|r| r.remove(id)) {
|
||||||
pub fn updated(&self) -> Option<impl Iterator<Item = (&String, &Option<T>)>> {
|
Err(error.to_string_error().into())
|
||||||
self.updated.as_ref().map(|map| map.iter())
|
} else {
|
||||||
}
|
Err(Error::Internal(format!("Id {} not found.", id)))
|
||||||
|
|
||||||
pub fn destroyed(&self) -> Option<&[String]> {
|
|
||||||
self.destroyed.as_deref()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn not_created(&self) -> Option<impl Iterator<Item = (&String, &SetError<U>)>> {
|
|
||||||
self.not_created.as_ref().map(|map| map.iter())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn not_updated(&self) -> Option<impl Iterator<Item = (&String, &SetError<U>)>> {
|
|
||||||
self.not_updated.as_ref().map(|map| map.iter())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn not_destroyed(&self) -> Option<impl Iterator<Item = (&String, &SetError<U>)>> {
|
|
||||||
self.not_destroyed.as_ref().map(|map| map.iter())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn created_details(&self, id: &str) -> Option<&T> {
|
|
||||||
self.created.as_ref().and_then(|map| map.get(id))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn updated_details(&self, id: &str) -> Option<&T> {
|
|
||||||
self.updated.as_ref().and_then(|map| map.get(id))?.as_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn not_created_details(&self, id: &str) -> Option<&SetError<U>> {
|
|
||||||
self.not_created.as_ref().and_then(|map| map.get(id))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn not_updated_details(&self, id: &str) -> Option<&SetError<U>> {
|
|
||||||
self.not_updated.as_ref().and_then(|map| map.get(id))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn not_destroyed_details(&self, id: &str) -> Option<&SetError<U>> {
|
|
||||||
self.not_destroyed.as_ref().and_then(|map| map.get(id))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<U> SetError<U> {
|
pub fn updated(&mut self, id: &str) -> crate::Result<Option<T>> {
|
||||||
|
if let Some(result) = self.updated.as_mut().and_then(|r| r.remove(id)) {
|
||||||
|
Ok(result)
|
||||||
|
} else if let Some(error) = self.not_updated.as_mut().and_then(|r| r.remove(id)) {
|
||||||
|
Err(error.to_string_error().into())
|
||||||
|
} else {
|
||||||
|
Err(Error::Internal(format!("Id {} not found.", id)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroyed(&mut self, id: &str) -> crate::Result<()> {
|
||||||
|
if self
|
||||||
|
.destroyed
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |r| r.iter().any(|i| i == id))
|
||||||
|
{
|
||||||
|
Ok(())
|
||||||
|
} else if let Some(error) = self.not_destroyed.as_mut().and_then(|r| r.remove(id)) {
|
||||||
|
Err(error.to_string_error().into())
|
||||||
|
} else {
|
||||||
|
Err(Error::Internal(format!("Id {} not found.", id)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn created_ids(&self) -> Option<impl Iterator<Item = &String>> {
|
||||||
|
self.created.as_ref().map(|map| map.keys())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn updated_ids(&self) -> Option<impl Iterator<Item = &String>> {
|
||||||
|
self.updated.as_ref().map(|map| map.keys())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroyed_ids(&self) -> Option<impl Iterator<Item = &String>> {
|
||||||
|
self.destroyed.as_ref().map(|list| list.iter())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn not_created_ids(&self) -> Option<impl Iterator<Item = &String>> {
|
||||||
|
self.not_created.as_ref().map(|map| map.keys())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn not_updated_ids(&self) -> Option<impl Iterator<Item = &String>> {
|
||||||
|
self.not_updated.as_ref().map(|map| map.keys())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn not_destroyed_ids(&self) -> Option<impl Iterator<Item = &String>> {
|
||||||
|
self.not_destroyed.as_ref().map(|map| map.keys())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U: Display> SetError<U> {
|
||||||
pub fn error(&self) -> &SetErrorType {
|
pub fn error(&self) -> &SetErrorType {
|
||||||
&self.type_
|
&self.type_
|
||||||
}
|
}
|
||||||
|
@ -259,6 +281,67 @@ impl<U> SetError<U> {
|
||||||
pub fn properties(&self) -> Option<&[U]> {
|
pub fn properties(&self) -> Option<&[U]> {
|
||||||
self.properties.as_deref()
|
self.properties.as_deref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_string_error(&self) -> SetError<String> {
|
||||||
|
SetError {
|
||||||
|
type_: self.type_.clone(),
|
||||||
|
description: self.description.as_ref().map(|s| s.to_string()),
|
||||||
|
properties: self
|
||||||
|
.properties
|
||||||
|
.as_ref()
|
||||||
|
.map(|s| s.iter().map(|s| s.to_string()).collect()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U: Display> Display for SetError<U> {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
self.type_.fmt(f)?;
|
||||||
|
if let Some(description) = &self.description {
|
||||||
|
write!(f, ": {}", description)?;
|
||||||
|
}
|
||||||
|
if let Some(properties) = &self.properties {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
" (properties: {})",
|
||||||
|
properties
|
||||||
|
.iter()
|
||||||
|
.map(|v| v.to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ")
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for SetErrorType {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
SetErrorType::Forbidden => write!(f, "Forbidden"),
|
||||||
|
SetErrorType::OverQuota => write!(f, "OverQuota"),
|
||||||
|
SetErrorType::TooLarge => write!(f, "TooLarge"),
|
||||||
|
SetErrorType::RateLimit => write!(f, "RateLimit"),
|
||||||
|
SetErrorType::NotFound => write!(f, "NotFound"),
|
||||||
|
SetErrorType::InvalidPatch => write!(f, "InvalidPatch"),
|
||||||
|
SetErrorType::WillDestroy => write!(f, "WillDestroy"),
|
||||||
|
SetErrorType::InvalidProperties => write!(f, "InvalidProperties"),
|
||||||
|
SetErrorType::Singleton => write!(f, "Singleton"),
|
||||||
|
SetErrorType::MailboxHasChild => write!(f, "MailboxHasChild"),
|
||||||
|
SetErrorType::MailboxHasEmail => write!(f, "MailboxHasEmail"),
|
||||||
|
SetErrorType::BlobNotFound => write!(f, "BlobNotFound"),
|
||||||
|
SetErrorType::TooManyKeywords => write!(f, "TooManyKeywords"),
|
||||||
|
SetErrorType::TooManyMailboxes => write!(f, "TooManyMailboxes"),
|
||||||
|
SetErrorType::ForbiddenFrom => write!(f, "ForbiddenFrom"),
|
||||||
|
SetErrorType::InvalidEmail => write!(f, "InvalidEmail"),
|
||||||
|
SetErrorType::TooManyRecipients => write!(f, "TooManyRecipients"),
|
||||||
|
SetErrorType::NoRecipients => write!(f, "NoRecipients"),
|
||||||
|
SetErrorType::InvalidRecipients => write!(f, "InvalidRecipients"),
|
||||||
|
SetErrorType::ForbiddenMailFrom => write!(f, "ForbiddenMailFrom"),
|
||||||
|
SetErrorType::ForbiddenToSend => write!(f, "ForbiddenToSend"),
|
||||||
|
SetErrorType::CannotUnsend => write!(f, "CannotUnsend"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_timestamp(timestamp: i64) -> DateTime<Utc> {
|
pub fn from_timestamp(timestamp: i64) -> DateTime<Utc> {
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
use crate::{
|
||||||
|
client::Client,
|
||||||
|
core::{
|
||||||
|
query::{Comparator, Filter, QueryResponse},
|
||||||
|
response::{EmailGetResponse, EmailSetResponse},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{import::EmailImportResponse, Email, Property};
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
pub async fn email_import<T, U>(
|
||||||
|
&mut self,
|
||||||
|
raw_message: Vec<u8>,
|
||||||
|
mailbox_ids: T,
|
||||||
|
keywords: Option<T>,
|
||||||
|
received_at: Option<i64>,
|
||||||
|
) -> crate::Result<Email>
|
||||||
|
where
|
||||||
|
T: IntoIterator<Item = U>,
|
||||||
|
U: Into<String>,
|
||||||
|
{
|
||||||
|
let blob_id = self
|
||||||
|
.upload(self.default_account_id(), None, raw_message)
|
||||||
|
.await?
|
||||||
|
.unwrap_blob_id();
|
||||||
|
let mut request = self.build();
|
||||||
|
let import_request = request
|
||||||
|
.import_email()
|
||||||
|
.email(blob_id)
|
||||||
|
.mailbox_ids(mailbox_ids);
|
||||||
|
|
||||||
|
if let Some(keywords) = keywords {
|
||||||
|
import_request.keywords(keywords);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(received_at) = received_at {
|
||||||
|
import_request.received_at(received_at);
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = import_request.create_id();
|
||||||
|
request
|
||||||
|
.send_single::<EmailImportResponse>()
|
||||||
|
.await?
|
||||||
|
.created(&id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn email_set_mailbox(
|
||||||
|
&mut self,
|
||||||
|
id: &str,
|
||||||
|
mailbox_id: &str,
|
||||||
|
set: bool,
|
||||||
|
) -> crate::Result<Option<Email>> {
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_email().update(id).mailbox_id(mailbox_id, set);
|
||||||
|
request.send_single::<EmailSetResponse>().await?.updated(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn email_set_mailboxes<T, U>(
|
||||||
|
&mut self,
|
||||||
|
id: &str,
|
||||||
|
mailbox_ids: T,
|
||||||
|
) -> crate::Result<Option<Email>>
|
||||||
|
where
|
||||||
|
T: IntoIterator<Item = U>,
|
||||||
|
U: Into<String>,
|
||||||
|
{
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_email().update(id).mailbox_ids(mailbox_ids);
|
||||||
|
request.send_single::<EmailSetResponse>().await?.updated(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn email_set_keyword(
|
||||||
|
&mut self,
|
||||||
|
id: &str,
|
||||||
|
keyword: &str,
|
||||||
|
set: bool,
|
||||||
|
) -> crate::Result<Option<Email>> {
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_email().update(id).keyword(keyword, set);
|
||||||
|
request.send_single::<EmailSetResponse>().await?.updated(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn email_set_keywords<T, U>(
|
||||||
|
&mut self,
|
||||||
|
id: &str,
|
||||||
|
keywords: T,
|
||||||
|
) -> crate::Result<Option<Email>>
|
||||||
|
where
|
||||||
|
T: IntoIterator<Item = U>,
|
||||||
|
U: Into<String>,
|
||||||
|
{
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_email().update(id).keywords(keywords);
|
||||||
|
request.send_single::<EmailSetResponse>().await?.updated(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn email_destroy(&mut self, id: &str) -> crate::Result<()> {
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_email().destroy([id]);
|
||||||
|
request
|
||||||
|
.send_single::<EmailSetResponse>()
|
||||||
|
.await?
|
||||||
|
.destroyed(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn email_get(
|
||||||
|
&mut self,
|
||||||
|
id: &str,
|
||||||
|
properties: Option<Vec<Property>>,
|
||||||
|
) -> crate::Result<Option<Email>> {
|
||||||
|
let mut request = self.build();
|
||||||
|
let get_request = request.get_email().ids([id]);
|
||||||
|
if let Some(properties) = properties {
|
||||||
|
get_request.properties(properties.into_iter());
|
||||||
|
}
|
||||||
|
request
|
||||||
|
.send_single::<EmailGetResponse>()
|
||||||
|
.await
|
||||||
|
.map(|mut r| r.unwrap_list().pop())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn email_query(
|
||||||
|
&mut self,
|
||||||
|
filter: Option<impl Into<Filter<super::query::Filter>>>,
|
||||||
|
sort: Option<Vec<Comparator<super::query::Comparator>>>,
|
||||||
|
) -> crate::Result<QueryResponse> {
|
||||||
|
let mut request = self.build();
|
||||||
|
let query_request = request.query_email();
|
||||||
|
if let Some(filter) = filter {
|
||||||
|
query_request.filter(filter);
|
||||||
|
}
|
||||||
|
if let Some(sort) = sort {
|
||||||
|
query_request.sort(sort.into_iter());
|
||||||
|
}
|
||||||
|
request.send_single::<QueryResponse>().await
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,13 @@ use std::collections::HashMap;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::core::set::{from_timestamp, SetError};
|
use crate::{
|
||||||
|
core::{
|
||||||
|
request::ResultReference,
|
||||||
|
set::{from_timestamp, SetError},
|
||||||
|
},
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{Email, Property};
|
use super::{Email, Property};
|
||||||
|
|
||||||
|
@ -28,7 +34,13 @@ pub struct EmailImport {
|
||||||
blob_id: String,
|
blob_id: String,
|
||||||
|
|
||||||
#[serde(rename = "mailboxIds")]
|
#[serde(rename = "mailboxIds")]
|
||||||
mailbox_ids: HashMap<String, bool>,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
mailbox_ids: Option<HashMap<String, bool>>,
|
||||||
|
|
||||||
|
#[serde(rename = "#mailboxIds")]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
mailbox_ids_ref: Option<ResultReference>,
|
||||||
|
|
||||||
#[serde(rename = "keywords")]
|
#[serde(rename = "keywords")]
|
||||||
keywords: HashMap<String, bool>,
|
keywords: HashMap<String, bool>,
|
||||||
|
@ -86,19 +98,35 @@ impl EmailImport {
|
||||||
EmailImport {
|
EmailImport {
|
||||||
create_id,
|
create_id,
|
||||||
blob_id,
|
blob_id,
|
||||||
mailbox_ids: HashMap::new(),
|
mailbox_ids: None,
|
||||||
|
mailbox_ids_ref: None,
|
||||||
keywords: HashMap::new(),
|
keywords: HashMap::new(),
|
||||||
received_at: None,
|
received_at: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mailbox_id(&mut self, mailbox_id: impl Into<String>) -> &mut Self {
|
pub fn mailbox_ids<T, U>(&mut self, mailbox_ids: T) -> &mut Self
|
||||||
self.mailbox_ids.insert(mailbox_id.into(), true);
|
where
|
||||||
|
T: IntoIterator<Item = U>,
|
||||||
|
U: Into<String>,
|
||||||
|
{
|
||||||
|
self.mailbox_ids = Some(mailbox_ids.into_iter().map(|s| (s.into(), true)).collect());
|
||||||
|
self.mailbox_ids_ref = None;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keyword(&mut self, keyword: impl Into<String>) -> &mut Self {
|
pub fn mailbox_ids_ref(&mut self, reference: ResultReference) -> &mut Self {
|
||||||
self.keywords.insert(keyword.into(), true);
|
self.mailbox_ids_ref = reference.into();
|
||||||
|
self.mailbox_ids = None;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn keywords<T, U>(&mut self, keywords: T) -> &mut Self
|
||||||
|
where
|
||||||
|
T: IntoIterator<Item = U>,
|
||||||
|
U: Into<String>,
|
||||||
|
{
|
||||||
|
self.keywords = keywords.into_iter().map(|s| (s.into(), true)).collect();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,19 +153,21 @@ impl EmailImportResponse {
|
||||||
&self.new_state
|
&self.new_state
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn created(&self) -> Option<impl Iterator<Item = &String>> {
|
pub fn created(&mut self, id: &str) -> crate::Result<Email> {
|
||||||
|
if let Some(result) = self.created.as_mut().and_then(|r| r.remove(id)) {
|
||||||
|
Ok(result)
|
||||||
|
} else if let Some(error) = self.not_created.as_mut().and_then(|r| r.remove(id)) {
|
||||||
|
Err(error.to_string_error().into())
|
||||||
|
} else {
|
||||||
|
Err(Error::Internal(format!("Id {} not found.", id)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn created_ids(&self) -> Option<impl Iterator<Item = &String>> {
|
||||||
self.created.as_ref().map(|map| map.keys())
|
self.created.as_ref().map(|map| map.keys())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn not_created(&self) -> Option<impl Iterator<Item = &String>> {
|
pub fn not_created_ids(&self) -> Option<impl Iterator<Item = &String>> {
|
||||||
self.not_created.as_ref().map(|map| map.keys())
|
self.not_created.as_ref().map(|map| map.keys())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn created_details(&self, id: &str) -> Option<&Email> {
|
|
||||||
self.created.as_ref().and_then(|map| map.get(id))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn not_created_reason(&self, id: &str) -> Option<&SetError<Property>> {
|
|
||||||
self.not_created.as_ref().and_then(|map| map.get(id))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod get;
|
pub mod get;
|
||||||
|
pub mod helpers;
|
||||||
pub mod import;
|
pub mod import;
|
||||||
pub mod parse;
|
pub mod parse;
|
||||||
pub mod query;
|
pub mod query;
|
||||||
|
@ -7,7 +8,10 @@ pub mod set;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fmt::{self, Display, Formatter},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{core::request::ResultReference, Get};
|
use crate::{core::request::ResultReference, Get};
|
||||||
|
|
||||||
|
@ -318,7 +322,39 @@ pub enum BodyProperty {
|
||||||
SubParts,
|
SubParts,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
impl Display for Property {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Property::Id => write!(f, "id"),
|
||||||
|
Property::BlobId => write!(f, "blobId"),
|
||||||
|
Property::ThreadId => write!(f, "threadId"),
|
||||||
|
Property::MailboxIds => write!(f, "mailboxIds"),
|
||||||
|
Property::Keywords => write!(f, "keywords"),
|
||||||
|
Property::Size => write!(f, "size"),
|
||||||
|
Property::ReceivedAt => write!(f, "receivedAt"),
|
||||||
|
Property::MessageId => write!(f, "messageId"),
|
||||||
|
Property::InReplyTo => write!(f, "inReplyTo"),
|
||||||
|
Property::References => write!(f, "references"),
|
||||||
|
Property::Sender => write!(f, "sender"),
|
||||||
|
Property::From => write!(f, "from"),
|
||||||
|
Property::To => write!(f, "to"),
|
||||||
|
Property::Cc => write!(f, "cc"),
|
||||||
|
Property::Bcc => write!(f, "bcc"),
|
||||||
|
Property::ReplyTo => write!(f, "replyTo"),
|
||||||
|
Property::Subject => write!(f, "subject"),
|
||||||
|
Property::SentAt => write!(f, "sentAt"),
|
||||||
|
Property::BodyStructure => write!(f, "bodyStructure"),
|
||||||
|
Property::BodyValues => write!(f, "bodyValues"),
|
||||||
|
Property::TextBody => write!(f, "textBody"),
|
||||||
|
Property::HtmlBody => write!(f, "htmlBody"),
|
||||||
|
Property::Attachments => write!(f, "attachments"),
|
||||||
|
Property::HasAttachment => write!(f, "hasAttachment"),
|
||||||
|
Property::Preview => write!(f, "preview"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct MailCapabilities {
|
pub struct MailCapabilities {
|
||||||
#[serde(rename = "maxMailboxesPerEmail")]
|
#[serde(rename = "maxMailboxesPerEmail")]
|
||||||
max_mailboxes_per_email: Option<usize>,
|
max_mailboxes_per_email: Option<usize>,
|
||||||
|
@ -339,7 +375,7 @@ pub struct MailCapabilities {
|
||||||
may_create_top_level_mailbox: bool,
|
may_create_top_level_mailbox: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct SubmissionCapabilities {
|
pub struct SubmissionCapabilities {
|
||||||
#[serde(rename = "maxDelayedSend")]
|
#[serde(rename = "maxDelayedSend")]
|
||||||
max_delayed_send: usize,
|
max_delayed_send: usize,
|
||||||
|
|
|
@ -2,7 +2,7 @@ pub mod get;
|
||||||
pub mod query;
|
pub mod query;
|
||||||
pub mod set;
|
pub mod set;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, fmt::Display};
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -149,3 +149,20 @@ pub enum Property {
|
||||||
#[serde(rename = "mdnBlobIds")]
|
#[serde(rename = "mdnBlobIds")]
|
||||||
MdnBlobIds,
|
MdnBlobIds,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Property {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Property::Id => write!(f, "id"),
|
||||||
|
Property::IdentityId => write!(f, "identityId"),
|
||||||
|
Property::EmailId => write!(f, "emailId"),
|
||||||
|
Property::ThreadId => write!(f, "threadId"),
|
||||||
|
Property::Envelope => write!(f, "envelope"),
|
||||||
|
Property::SendAt => write!(f, "sendAt"),
|
||||||
|
Property::UndoStatus => write!(f, "undoStatus"),
|
||||||
|
Property::DeliveryStatus => write!(f, "deliveryStatus"),
|
||||||
|
Property::DsnBlobIds => write!(f, "dsnBlobIds"),
|
||||||
|
Property::MdnBlobIds => write!(f, "mdnBlobIds"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
pub mod get;
|
pub mod get;
|
||||||
pub mod set;
|
pub mod set;
|
||||||
|
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::core::set::list_not_set;
|
use crate::core::set::list_not_set;
|
||||||
use crate::{email::EmailAddress, Get};
|
use crate::{email::EmailAddress, Get};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -65,3 +67,18 @@ pub enum Property {
|
||||||
#[serde(rename = "mayDelete")]
|
#[serde(rename = "mayDelete")]
|
||||||
MayDelete,
|
MayDelete,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Property {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Property::Id => write!(f, "id"),
|
||||||
|
Property::Name => write!(f, "name"),
|
||||||
|
Property::Email => write!(f, "email"),
|
||||||
|
Property::ReplyTo => write!(f, "replyTo"),
|
||||||
|
Property::Bcc => write!(f, "bcc"),
|
||||||
|
Property::TextSignature => write!(f, "textSignature"),
|
||||||
|
Property::HtmlSignature => write!(f, "htmlSignature"),
|
||||||
|
Property::MayDelete => write!(f, "mayDelete"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
29
src/lib.rs
29
src/lib.rs
|
@ -1,4 +1,6 @@
|
||||||
|
use crate::core::error::MethodError;
|
||||||
use crate::core::error::ProblemDetails;
|
use crate::core::error::ProblemDetails;
|
||||||
|
use crate::core::set::SetError;
|
||||||
use std::{collections::HashMap, fmt::Display};
|
use std::{collections::HashMap, fmt::Display};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -130,12 +132,15 @@ pub struct Set;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Transport(reqwest::Error),
|
Transport(reqwest::Error),
|
||||||
Parse(serde_json::Error),
|
Parse(serde_json::Error),
|
||||||
Internal(String),
|
Internal(String),
|
||||||
Problem(ProblemDetails),
|
Problem(ProblemDetails),
|
||||||
ServerError(String),
|
Server(String),
|
||||||
|
Method(MethodError),
|
||||||
|
Set(SetError<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<reqwest::Error> for Error {
|
impl From<reqwest::Error> for Error {
|
||||||
|
@ -150,6 +155,24 @@ impl From<serde_json::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<MethodError> for Error {
|
||||||
|
fn from(e: MethodError) -> Self {
|
||||||
|
Error::Method(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SetError<String>> for Error {
|
||||||
|
fn from(e: SetError<String>) -> Self {
|
||||||
|
Error::Set(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Error {
|
||||||
|
fn from(s: &str) -> Self {
|
||||||
|
Error::Internal(s.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for Error {
|
impl Display for Error {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -157,7 +180,9 @@ impl Display for Error {
|
||||||
Error::Parse(e) => write!(f, "Parse error: {}", e),
|
Error::Parse(e) => write!(f, "Parse error: {}", e),
|
||||||
Error::Internal(e) => write!(f, "Internal error: {}", e),
|
Error::Internal(e) => write!(f, "Internal error: {}", e),
|
||||||
Error::Problem(e) => write!(f, "Problem details: {}", e),
|
Error::Problem(e) => write!(f, "Problem details: {}", e),
|
||||||
Error::ServerError(e) => write!(f, "Server error: {}", e),
|
Error::Server(e) => write!(f, "Server error: {}", e),
|
||||||
|
Error::Method(e) => write!(f, "Method error: {}", e),
|
||||||
|
Error::Set(e) => write!(f, "Set error: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
use crate::{
|
||||||
|
client::Client,
|
||||||
|
core::{
|
||||||
|
query::{Comparator, Filter, QueryResponse},
|
||||||
|
response::{MailboxGetResponse, MailboxSetResponse},
|
||||||
|
set::Create,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{Mailbox, Property, Role};
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
pub async fn mailbox_create(
|
||||||
|
&mut self,
|
||||||
|
name: impl Into<String>,
|
||||||
|
parent_id: Option<impl Into<String>>,
|
||||||
|
role: Role,
|
||||||
|
) -> crate::Result<Mailbox> {
|
||||||
|
let mut request = self.build();
|
||||||
|
let id = request
|
||||||
|
.set_mailbox()
|
||||||
|
.create()
|
||||||
|
.name(name)
|
||||||
|
.role(role)
|
||||||
|
.parent_id(parent_id)
|
||||||
|
.create_id()
|
||||||
|
.unwrap();
|
||||||
|
request
|
||||||
|
.send_single::<MailboxSetResponse>()
|
||||||
|
.await?
|
||||||
|
.created(&id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn mailbox_rename(
|
||||||
|
&mut self,
|
||||||
|
id: &str,
|
||||||
|
name: impl Into<String>,
|
||||||
|
) -> crate::Result<Option<Mailbox>> {
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_mailbox().update(id).name(name);
|
||||||
|
request
|
||||||
|
.send_single::<MailboxSetResponse>()
|
||||||
|
.await?
|
||||||
|
.updated(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn mailbox_move(
|
||||||
|
&mut self,
|
||||||
|
id: &str,
|
||||||
|
parent_id: Option<impl Into<String>>,
|
||||||
|
) -> crate::Result<Option<Mailbox>> {
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_mailbox().update(id).parent_id(parent_id);
|
||||||
|
request
|
||||||
|
.send_single::<MailboxSetResponse>()
|
||||||
|
.await?
|
||||||
|
.updated(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn mailbox_update_role(
|
||||||
|
&mut self,
|
||||||
|
id: &str,
|
||||||
|
role: Role,
|
||||||
|
) -> crate::Result<Option<Mailbox>> {
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_mailbox().update(id).role(role);
|
||||||
|
request
|
||||||
|
.send_single::<MailboxSetResponse>()
|
||||||
|
.await?
|
||||||
|
.updated(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn mailbox_update_sort_order(
|
||||||
|
&mut self,
|
||||||
|
id: &str,
|
||||||
|
sort_order: u32,
|
||||||
|
) -> crate::Result<Option<Mailbox>> {
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_mailbox().update(id).sort_order(sort_order);
|
||||||
|
request
|
||||||
|
.send_single::<MailboxSetResponse>()
|
||||||
|
.await?
|
||||||
|
.updated(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn mailbox_destroy(&mut self, id: &str, delete_emails: bool) -> crate::Result<()> {
|
||||||
|
let mut request = self.build();
|
||||||
|
request
|
||||||
|
.set_mailbox()
|
||||||
|
.destroy([id])
|
||||||
|
.arguments()
|
||||||
|
.on_destroy_remove_emails(delete_emails);
|
||||||
|
request
|
||||||
|
.send_single::<MailboxSetResponse>()
|
||||||
|
.await?
|
||||||
|
.destroyed(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn mailbox_get(
|
||||||
|
&mut self,
|
||||||
|
id: &str,
|
||||||
|
properties: Option<Vec<Property>>,
|
||||||
|
) -> crate::Result<Option<Mailbox>> {
|
||||||
|
let mut request = self.build();
|
||||||
|
let get_request = request.get_mailbox().ids([id]);
|
||||||
|
if let Some(properties) = properties {
|
||||||
|
get_request.properties(properties.into_iter());
|
||||||
|
}
|
||||||
|
request
|
||||||
|
.send_single::<MailboxGetResponse>()
|
||||||
|
.await
|
||||||
|
.map(|mut r| r.unwrap_list().pop())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn mailbox_query(
|
||||||
|
&mut self,
|
||||||
|
filter: Option<impl Into<Filter<super::query::Filter>>>,
|
||||||
|
sort: Option<Vec<Comparator<super::query::Comparator>>>,
|
||||||
|
) -> crate::Result<QueryResponse> {
|
||||||
|
let mut request = self.build();
|
||||||
|
let query_request = request.query_mailbox();
|
||||||
|
if let Some(filter) = filter {
|
||||||
|
query_request.filter(filter);
|
||||||
|
}
|
||||||
|
if let Some(sort) = sort {
|
||||||
|
query_request.sort(sort.into_iter());
|
||||||
|
}
|
||||||
|
request.send_single::<QueryResponse>().await
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,10 @@
|
||||||
pub mod get;
|
pub mod get;
|
||||||
|
pub mod helpers;
|
||||||
pub mod query;
|
pub mod query;
|
||||||
pub mod set;
|
pub mod set;
|
||||||
|
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::core::set::string_not_set;
|
use crate::core::set::string_not_set;
|
||||||
use crate::mailbox::set::role_not_set;
|
use crate::mailbox::set::role_not_set;
|
||||||
use crate::Get;
|
use crate::Get;
|
||||||
|
@ -10,7 +13,8 @@ use serde::{Deserialize, Serialize};
|
||||||
#[derive(Debug, Clone, Serialize, Default)]
|
#[derive(Debug, Clone, Serialize, Default)]
|
||||||
pub struct SetArguments {
|
pub struct SetArguments {
|
||||||
#[serde(rename = "onDestroyRemoveEmails")]
|
#[serde(rename = "onDestroyRemoveEmails")]
|
||||||
on_destroy_remove_emails: bool,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
on_destroy_remove_emails: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Default)]
|
#[derive(Debug, Clone, Serialize, Default)]
|
||||||
|
@ -149,6 +153,24 @@ pub enum Property {
|
||||||
IsSubscribed,
|
IsSubscribed,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Property {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Property::Id => write!(f, "id"),
|
||||||
|
Property::Name => write!(f, "name"),
|
||||||
|
Property::ParentId => write!(f, "parentId"),
|
||||||
|
Property::Role => write!(f, "role"),
|
||||||
|
Property::SortOrder => write!(f, "sortOrder"),
|
||||||
|
Property::TotalEmails => write!(f, "totalEmails"),
|
||||||
|
Property::UnreadEmails => write!(f, "unreadEmails"),
|
||||||
|
Property::TotalThreads => write!(f, "totalThreads"),
|
||||||
|
Property::UnreadThreads => write!(f, "unreadThreads"),
|
||||||
|
Property::MyRights => write!(f, "myRights"),
|
||||||
|
Property::IsSubscribed => write!(f, "isSubscribed"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ChangesResponse {
|
impl ChangesResponse {
|
||||||
pub fn updated_properties(&self) -> Option<&[Property]> {
|
pub fn updated_properties(&self) -> Option<&[Property]> {
|
||||||
self.updated_properties.as_deref()
|
self.updated_properties.as_deref()
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl Create for Mailbox<Set> {
|
||||||
|
|
||||||
impl SetArguments {
|
impl SetArguments {
|
||||||
pub fn on_destroy_remove_emails(&mut self, value: bool) -> &mut Self {
|
pub fn on_destroy_remove_emails(&mut self, value: bool) -> &mut Self {
|
||||||
self.on_destroy_remove_emails = value;
|
self.on_destroy_remove_emails = value.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
pub mod get;
|
pub mod get;
|
||||||
pub mod set;
|
pub mod set;
|
||||||
|
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -62,6 +64,20 @@ pub enum Property {
|
||||||
Types,
|
Types,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Property {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Property::Id => write!(f, "id"),
|
||||||
|
Property::DeviceClientId => write!(f, "deviceClientId"),
|
||||||
|
Property::Url => write!(f, "url"),
|
||||||
|
Property::Keys => write!(f, "keys"),
|
||||||
|
Property::VerificationCode => write!(f, "verificationCode"),
|
||||||
|
Property::Expires => write!(f, "expires"),
|
||||||
|
Property::Types => write!(f, "types"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Keys {
|
pub struct Keys {
|
||||||
p256dh: String,
|
p256dh: String,
|
||||||
|
|
|
@ -64,9 +64,4 @@ impl Keys {
|
||||||
auth: base64::encode_config(&auth, base64::URL_SAFE),
|
auth: base64::encode_config(&auth, base64::URL_SAFE),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate() -> Option<Self> {
|
|
||||||
let (p256dh, auth) = ece::generate_keypair_and_auth_secret().ok()?;
|
|
||||||
Self::new(&p256dh.pub_as_raw().ok()?, &auth).into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
pub mod get;
|
pub mod get;
|
||||||
pub mod set;
|
pub mod set;
|
||||||
|
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::core::set::date_not_set;
|
use crate::core::set::date_not_set;
|
||||||
use crate::core::set::string_not_set;
|
use crate::core::set::string_not_set;
|
||||||
use crate::Get;
|
use crate::Get;
|
||||||
|
@ -61,3 +63,17 @@ pub enum Property {
|
||||||
#[serde(rename = "htmlBody")]
|
#[serde(rename = "htmlBody")]
|
||||||
HtmlBody,
|
HtmlBody,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Property {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Property::Id => write!(f, "id"),
|
||||||
|
Property::IsEnabled => write!(f, "isEnabled"),
|
||||||
|
Property::FromDate => write!(f, "fromDate"),
|
||||||
|
Property::ToDate => write!(f, "toDate"),
|
||||||
|
Property::Subject => write!(f, "subject"),
|
||||||
|
Property::TextBody => write!(f, "textBody"),
|
||||||
|
Property::HtmlBody => write!(f, "htmlBody"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue