Blocking client and patch support on Principals.
parent
76fe0331a2
commit
b0ba1737b1
19
Cargo.toml
19
Cargo.toml
|
@ -12,22 +12,23 @@ categories = ["email"]
|
|||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
reqwest = { git = "https://github.com/stalwartlabs/reqwest.git", default-features = false, features = ["rustls-tls"]}
|
||||
tokio-tungstenite = { version = "0.17", features = ["rustls-tls-webpki-roots"], optional = true}
|
||||
tokio = { version = "1.16", default-features = false, features = ["io-util"], optional = true }
|
||||
futures-util = { version = "0.3", optional = true}
|
||||
async-stream = { version = "0.3", optional = true}
|
||||
serde = { version = "1.0", features = ["derive"]}
|
||||
serde_json = "1.0"
|
||||
chrono = { version = "0.4", features = ["serde"]}
|
||||
#reqwest = { version = "0.11", default-features = false, features = ["stream", "rustls-tls"]}
|
||||
reqwest = { git = "https://github.com/stalwartlabs/reqwest.git", default-features = false, features = ["stream", "rustls-tls"]}
|
||||
futures-util = "0.3"
|
||||
async-stream = "0.3"
|
||||
base64 = "0.13"
|
||||
tokio-tungstenite = { version = "0.17", features = ["rustls-tls-webpki-roots"], optional = true}
|
||||
tokio = { version = "1.16", default-features = false, features = ["io-util"], optional = true }
|
||||
parking_lot = "0.12.0"
|
||||
ahash = {version = "0.7.6", features = ["serde"]}
|
||||
parking_lot = "0.12.0"
|
||||
base64 = "0.13"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = ["async"]
|
||||
async = ["futures-util", "async-stream", "reqwest/stream"]
|
||||
websockets = ["tokio", "tokio-tungstenite"]
|
||||
blocking = ["reqwest/blocking"]
|
||||
debug = []
|
||||
|
||||
[profile.bench]
|
||||
|
|
|
@ -5,6 +5,7 @@ use reqwest::header::CONTENT_TYPE;
|
|||
use crate::{client::Client, core::session::URLPart};
|
||||
|
||||
impl Client {
|
||||
#[cfg(feature = "async")]
|
||||
pub async fn download(&self, blob_id: &str) -> crate::Result<Vec<u8>> {
|
||||
let account_id = self.default_account_id();
|
||||
let mut download_url = String::with_capacity(
|
||||
|
@ -52,4 +53,50 @@ impl Client {
|
|||
.map(|bytes| bytes.to_vec())
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
pub fn download(&self, blob_id: &str) -> crate::Result<Vec<u8>> {
|
||||
let account_id = self.default_account_id();
|
||||
let mut download_url = String::with_capacity(
|
||||
self.session().download_url().len() + account_id.len() + blob_id.len(),
|
||||
);
|
||||
|
||||
for part in self.download_url() {
|
||||
match part {
|
||||
URLPart::Value(value) => {
|
||||
download_url.push_str(value);
|
||||
}
|
||||
URLPart::Parameter(param) => match param {
|
||||
super::URLParameter::AccountId => {
|
||||
download_url.push_str(account_id);
|
||||
}
|
||||
super::URLParameter::BlobId => {
|
||||
download_url.push_str(blob_id);
|
||||
}
|
||||
super::URLParameter::Name => {
|
||||
download_url.push_str("none");
|
||||
}
|
||||
super::URLParameter::Type => {
|
||||
download_url.push_str("application/octet-stream");
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let mut headers = self.headers().clone();
|
||||
headers.remove(CONTENT_TYPE);
|
||||
|
||||
Client::handle_error(
|
||||
reqwest::blocking::Client::builder()
|
||||
.timeout(Duration::from_millis(self.timeout()))
|
||||
.redirect(self.redirect_policy())
|
||||
.default_headers(headers)
|
||||
.build()?
|
||||
.get(download_url)
|
||||
.send()?,
|
||||
)?
|
||||
.bytes()
|
||||
.map(|bytes| bytes.to_vec())
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
use crate::{
|
||||
client::Client,
|
||||
core::request::{Arguments, Request},
|
||||
Method,
|
||||
};
|
||||
|
||||
use super::copy::{CopyBlobRequest, CopyBlobResponse};
|
||||
|
||||
impl Client {
|
||||
pub fn blob_copy(
|
||||
&self,
|
||||
from_account_id: impl Into<String>,
|
||||
blob_id: impl Into<String>,
|
||||
) -> crate::Result<String> {
|
||||
let blob_id = blob_id.into();
|
||||
let mut request = self.build();
|
||||
request.copy_blob(from_account_id).blob_id(&blob_id);
|
||||
request.send_single::<CopyBlobResponse>()?.copied(&blob_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl Request<'_> {
|
||||
pub fn copy_blob(&mut self, from_account_id: impl Into<String>) -> &mut CopyBlobRequest {
|
||||
self.add_method_call(
|
||||
Method::CopyBlob,
|
||||
Arguments::blob_copy(self.params(Method::CopyBlob), from_account_id.into()),
|
||||
)
|
||||
.blob_copy_mut()
|
||||
}
|
||||
|
||||
pub fn send_copy_blob(self) -> crate::Result<CopyBlobResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
}
|
|
@ -2,7 +2,10 @@ use crate::core::session::URLParser;
|
|||
|
||||
pub mod copy;
|
||||
pub mod download;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod helpers;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub mod helpers_blocking;
|
||||
pub mod upload;
|
||||
|
||||
pub enum URLParameter {
|
||||
|
|
|
@ -21,6 +21,7 @@ pub struct UploadResponse {
|
|||
}
|
||||
|
||||
impl Client {
|
||||
#[cfg(feature = "async")]
|
||||
pub async fn upload(
|
||||
&self,
|
||||
account_id: Option<&str>,
|
||||
|
@ -66,6 +67,50 @@ impl Client {
|
|||
)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
pub fn upload(
|
||||
&self,
|
||||
account_id: Option<&str>,
|
||||
blob: Vec<u8>,
|
||||
content_type: Option<&str>,
|
||||
) -> crate::Result<UploadResponse> {
|
||||
let account_id = account_id.unwrap_or_else(|| self.default_account_id());
|
||||
let mut upload_url =
|
||||
String::with_capacity(self.session().upload_url().len() + account_id.len());
|
||||
|
||||
for part in self.upload_url() {
|
||||
match part {
|
||||
URLPart::Value(value) => {
|
||||
upload_url.push_str(value);
|
||||
}
|
||||
URLPart::Parameter(param) => {
|
||||
if let super::URLParameter::AccountId = param {
|
||||
upload_url.push_str(account_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serde_json::from_slice::<UploadResponse>(
|
||||
&Client::handle_error(
|
||||
reqwest::blocking::Client::builder()
|
||||
.timeout(Duration::from_millis(self.timeout()))
|
||||
.redirect(self.redirect_policy())
|
||||
.default_headers(self.headers().clone())
|
||||
.build()?
|
||||
.post(upload_url)
|
||||
.header(
|
||||
CONTENT_TYPE,
|
||||
content_type.unwrap_or("application/octet-stream"),
|
||||
)
|
||||
.body(blob)
|
||||
.send()?,
|
||||
)?
|
||||
.bytes()?,
|
||||
)
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl UploadResponse {
|
||||
|
|
156
src/client.rs
156
src/client.rs
|
@ -9,7 +9,7 @@ use std::{
|
|||
use ahash::AHashSet;
|
||||
use reqwest::{
|
||||
header::{self},
|
||||
redirect, Response,
|
||||
redirect,
|
||||
};
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
|
@ -20,7 +20,7 @@ use crate::{
|
|||
response,
|
||||
session::{Session, URLPart},
|
||||
},
|
||||
event_source, Error,
|
||||
Error,
|
||||
};
|
||||
|
||||
const DEFAULT_TIMEOUT_MS: u64 = 10 * 1000;
|
||||
|
@ -41,7 +41,8 @@ pub struct Client {
|
|||
|
||||
upload_url: Vec<URLPart<blob::URLParameter>>,
|
||||
download_url: Vec<URLPart<blob::URLParameter>>,
|
||||
event_source_url: Vec<URLPart<event_source::URLParameter>>,
|
||||
#[cfg(feature = "async")]
|
||||
event_source_url: Vec<URLPart<crate::event_source::URLParameter>>,
|
||||
|
||||
headers: header::HeaderMap,
|
||||
default_account_id: String,
|
||||
|
@ -92,6 +93,7 @@ impl ClientBuilder {
|
|||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub async fn connect(self, url: &str) -> crate::Result<Client> {
|
||||
let authorization = match self.credentials.expect("Missing credentials") {
|
||||
Credentials::Basic(s) => format!("Basic {}", s),
|
||||
|
@ -153,6 +155,84 @@ impl ClientBuilder {
|
|||
Ok(Client {
|
||||
download_url: URLPart::parse(session.download_url())?,
|
||||
upload_url: URLPart::parse(session.upload_url())?,
|
||||
#[cfg(feature = "async")]
|
||||
event_source_url: URLPart::parse(session.event_source_url())?,
|
||||
api_url: session.api_url().to_string(),
|
||||
session: parking_lot::Mutex::new(Arc::new(session)),
|
||||
session_url: url.to_string(),
|
||||
session_updated: true.into(),
|
||||
trusted_hosts,
|
||||
#[cfg(feature = "websockets")]
|
||||
authorization,
|
||||
timeout: self.timeout,
|
||||
headers,
|
||||
default_account_id,
|
||||
#[cfg(feature = "websockets")]
|
||||
ws: None.into(),
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
pub fn connect(self, url: &str) -> crate::Result<Client> {
|
||||
let authorization = match self.credentials.expect("Missing credentials") {
|
||||
Credentials::Basic(s) => format!("Basic {}", s),
|
||||
Credentials::Bearer(s) => format!("Bearer {}", s),
|
||||
};
|
||||
let mut headers = header::HeaderMap::new();
|
||||
headers.insert(
|
||||
header::USER_AGENT,
|
||||
header::HeaderValue::from_static(USER_AGENT),
|
||||
);
|
||||
headers.insert(
|
||||
header::AUTHORIZATION,
|
||||
header::HeaderValue::from_str(&authorization).unwrap(),
|
||||
);
|
||||
|
||||
let trusted_hosts = Arc::new(self.trusted_hosts);
|
||||
|
||||
let trusted_hosts_ = trusted_hosts.clone();
|
||||
let session: Session = serde_json::from_slice(
|
||||
&Client::handle_error(
|
||||
reqwest::blocking::Client::builder()
|
||||
.timeout(Duration::from_millis(self.timeout))
|
||||
.redirect(redirect::Policy::custom(move |attempt| {
|
||||
if attempt.previous().len() > 5 {
|
||||
attempt.error("Too many redirects.")
|
||||
} else if matches!( attempt.url().host_str(), Some(host) if trusted_hosts_.contains(host) )
|
||||
{
|
||||
attempt.follow_trusted()
|
||||
} else {
|
||||
let message = format!(
|
||||
"Aborting redirect request to unknown host '{}'.",
|
||||
attempt.url().host_str().unwrap_or("")
|
||||
);
|
||||
attempt.error(message)
|
||||
}
|
||||
}))
|
||||
.default_headers(headers.clone())
|
||||
.build()?
|
||||
.get(url)
|
||||
.send()
|
||||
?,
|
||||
)?
|
||||
.bytes()?,
|
||||
)?;
|
||||
|
||||
let default_account_id = session
|
||||
.primary_accounts()
|
||||
.next()
|
||||
.map(|a| a.1.to_string())
|
||||
.unwrap_or_default();
|
||||
|
||||
headers.insert(
|
||||
header::CONTENT_TYPE,
|
||||
header::HeaderValue::from_static("application/json"),
|
||||
);
|
||||
|
||||
Ok(Client {
|
||||
download_url: URLPart::parse(session.download_url())?,
|
||||
upload_url: URLPart::parse(session.upload_url())?,
|
||||
#[cfg(feature = "async")]
|
||||
event_source_url: URLPart::parse(session.event_source_url())?,
|
||||
api_url: session.api_url().to_string(),
|
||||
session: parking_lot::Mutex::new(Arc::new(session)),
|
||||
|
@ -223,6 +303,7 @@ impl Client {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub async fn send<R>(
|
||||
&self,
|
||||
request: &request::Request<'_>,
|
||||
|
@ -254,6 +335,33 @@ impl Client {
|
|||
Ok(response)
|
||||
}
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
pub fn send<R>(&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::blocking::Client::builder()
|
||||
.redirect(self.redirect_policy())
|
||||
.timeout(Duration::from_millis(self.timeout))
|
||||
.default_headers(self.headers.clone())
|
||||
.build()?
|
||||
.post(&self.api_url)
|
||||
.body(serde_json::to_string(&request)?)
|
||||
.send()?,
|
||||
)?
|
||||
.bytes()?,
|
||||
)?;
|
||||
|
||||
if response.session_state() != self.session.lock().state() {
|
||||
self.session_updated.store(false, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub async fn refresh_session(&self) -> crate::Result<()> {
|
||||
let session: Session = serde_json::from_slice(
|
||||
&Client::handle_error(
|
||||
|
@ -275,6 +383,25 @@ impl Client {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
pub async fn refresh_session(&self) -> crate::Result<()> {
|
||||
let session: Session = serde_json::from_slice(
|
||||
&Client::handle_error(
|
||||
reqwest::blocking::Client::builder()
|
||||
.timeout(Duration::from_millis(DEFAULT_TIMEOUT_MS))
|
||||
.redirect(self.redirect_policy())
|
||||
.default_headers(self.headers.clone())
|
||||
.build()?
|
||||
.get(&self.session_url)
|
||||
.send()?,
|
||||
)?
|
||||
.bytes()?,
|
||||
)?;
|
||||
*self.session.lock() = Arc::new(session);
|
||||
self.session_updated.store(true, Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_session_updated(&self) -> bool {
|
||||
self.session_updated.load(Ordering::Relaxed)
|
||||
}
|
||||
|
@ -300,11 +427,13 @@ impl Client {
|
|||
&self.upload_url
|
||||
}
|
||||
|
||||
pub fn event_source_url(&self) -> &[URLPart<event_source::URLParameter>] {
|
||||
#[cfg(feature = "async")]
|
||||
pub fn event_source_url(&self) -> &[URLPart<crate::event_source::URLParameter>] {
|
||||
&self.event_source_url
|
||||
}
|
||||
|
||||
pub async fn handle_error(response: Response) -> crate::Result<Response> {
|
||||
#[cfg(feature = "async")]
|
||||
pub async fn handle_error(response: reqwest::Response) -> crate::Result<reqwest::Response> {
|
||||
if response.status().is_success() {
|
||||
Ok(response)
|
||||
} else if let Some(b"application/problem+json") = response
|
||||
|
@ -319,6 +448,23 @@ impl Client {
|
|||
Err(Error::Server(format!("{}", response.status())))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
pub fn handle_error(
|
||||
response: reqwest::blocking::Response,
|
||||
) -> crate::Result<reqwest::blocking::Response> {
|
||||
if response.status().is_success() {
|
||||
Ok(response)
|
||||
} else if let Some(b"application/problem+json") = response
|
||||
.headers()
|
||||
.get(header::CONTENT_TYPE)
|
||||
.map(|h| h.as_bytes())
|
||||
{
|
||||
Err(Error::Problem(serde_json::from_slice(&response.bytes()?)?))
|
||||
} else {
|
||||
Err(Error::Server(format!("{}", response.status())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Credentials {
|
||||
|
|
|
@ -429,15 +429,22 @@ impl<'x> Request<'x> {
|
|||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub async fn send(self) -> crate::Result<Response<TaggedMethodResponse>> {
|
||||
self.client.send(&self).await
|
||||
}
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
pub fn send(self) -> crate::Result<Response<TaggedMethodResponse>> {
|
||||
self.client.send(&self)
|
||||
}
|
||||
|
||||
#[cfg(feature = "websockets")]
|
||||
pub async fn send_ws(self) -> crate::Result<String> {
|
||||
self.client.send_ws(self).await
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
pub async fn send_single<T>(self) -> crate::Result<T>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
|
@ -453,6 +460,22 @@ impl<'x> Request<'x> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
pub fn send_single<T>(self) -> crate::Result<T>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
let response: Response<SingleMethodResponse<T>> = self.client.send(&self)?;
|
||||
match response
|
||||
.unwrap_method_responses()
|
||||
.pop()
|
||||
.ok_or_else(|| Error::Internal("Server returned no results".to_string()))?
|
||||
{
|
||||
SingleMethodResponse::Ok((_, response, _)) => Ok(response),
|
||||
SingleMethodResponse::Error((_, err, _)) => Err(err.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn params(&self, method: Method) -> RequestParams {
|
||||
RequestParams {
|
||||
account_id: self.account_id.clone(),
|
||||
|
|
|
@ -0,0 +1,381 @@
|
|||
use crate::{
|
||||
client::Client,
|
||||
core::{
|
||||
changes::{ChangesRequest, ChangesResponse},
|
||||
copy::CopyRequest,
|
||||
get::GetRequest,
|
||||
query::{Comparator, Filter, QueryRequest, QueryResponse},
|
||||
query_changes::{QueryChangesRequest, QueryChangesResponse},
|
||||
request::{Arguments, Request},
|
||||
response::{EmailCopyResponse, EmailGetResponse, EmailSetResponse},
|
||||
set::SetRequest,
|
||||
},
|
||||
Get, Method, Set,
|
||||
};
|
||||
|
||||
use super::{
|
||||
import::{EmailImportRequest, EmailImportResponse},
|
||||
parse::{EmailParseRequest, EmailParseResponse},
|
||||
search_snippet::{SearchSnippetGetRequest, SearchSnippetGetResponse},
|
||||
BodyProperty, Email, Property,
|
||||
};
|
||||
|
||||
impl Client {
|
||||
pub fn email_import<T, U, V, W>(
|
||||
&self,
|
||||
raw_message: Vec<u8>,
|
||||
mailbox_ids: T,
|
||||
keywords: Option<V>,
|
||||
received_at: Option<i64>,
|
||||
) -> crate::Result<Email>
|
||||
where
|
||||
T: IntoIterator<Item = U>,
|
||||
U: Into<String>,
|
||||
V: IntoIterator<Item = W>,
|
||||
W: Into<String>,
|
||||
{
|
||||
self.email_import_account(
|
||||
self.default_account_id(),
|
||||
raw_message,
|
||||
mailbox_ids,
|
||||
keywords,
|
||||
received_at,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn email_import_account<T, U, V, W>(
|
||||
&self,
|
||||
account_id: &str,
|
||||
raw_message: Vec<u8>,
|
||||
mailbox_ids: T,
|
||||
keywords: Option<V>,
|
||||
received_at: Option<i64>,
|
||||
) -> crate::Result<Email>
|
||||
where
|
||||
T: IntoIterator<Item = U>,
|
||||
U: Into<String>,
|
||||
V: IntoIterator<Item = W>,
|
||||
W: Into<String>,
|
||||
{
|
||||
let blob_id = self.upload(None, raw_message, None)?.take_blob_id();
|
||||
let mut request = self.build();
|
||||
let import_request = request
|
||||
.import_email()
|
||||
.account_id(account_id)
|
||||
.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>()?.created(&id)
|
||||
}
|
||||
|
||||
pub fn email_set_mailbox(
|
||||
&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>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn email_set_mailboxes<T, U>(
|
||||
&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>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn email_set_keyword(
|
||||
&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>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn email_set_keywords<T, U>(&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>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn email_destroy(&self, id: &str) -> crate::Result<()> {
|
||||
let mut request = self.build();
|
||||
request.set_email().destroy([id]);
|
||||
request.send_single::<EmailSetResponse>()?.destroyed(id)
|
||||
}
|
||||
|
||||
pub fn email_get(
|
||||
&self,
|
||||
id: &str,
|
||||
properties: Option<impl IntoIterator<Item = Property>>,
|
||||
) -> crate::Result<Option<Email<Get>>> {
|
||||
let mut request = self.build();
|
||||
let get_request = request.get_email().ids([id]);
|
||||
if let Some(properties) = properties {
|
||||
get_request.properties(properties);
|
||||
}
|
||||
request
|
||||
.send_single::<EmailGetResponse>()
|
||||
.map(|mut r| r.take_list().pop())
|
||||
}
|
||||
|
||||
pub fn email_changes(
|
||||
&self,
|
||||
since_state: impl Into<String>,
|
||||
max_changes: Option<usize>,
|
||||
) -> crate::Result<ChangesResponse<Email<Get>>> {
|
||||
let mut request = self.build();
|
||||
let changes_request = request.changes_email(since_state);
|
||||
if let Some(max_changes) = max_changes {
|
||||
changes_request.max_changes(max_changes);
|
||||
}
|
||||
request.send_single()
|
||||
}
|
||||
|
||||
pub fn email_query(
|
||||
&self,
|
||||
filter: Option<impl Into<Filter<super::query::Filter>>>,
|
||||
sort: Option<impl IntoIterator<Item = 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>()
|
||||
}
|
||||
|
||||
pub fn email_query_changes(
|
||||
&self,
|
||||
since_query_state: impl Into<String>,
|
||||
filter: Option<impl Into<Filter<super::query::Filter>>>,
|
||||
) -> crate::Result<QueryChangesResponse> {
|
||||
let mut request = self.build();
|
||||
let query_request = request.query_email_changes(since_query_state);
|
||||
if let Some(filter) = filter {
|
||||
query_request.filter(filter);
|
||||
}
|
||||
request.send_single::<QueryChangesResponse>()
|
||||
}
|
||||
|
||||
pub fn email_parse(
|
||||
&self,
|
||||
blob_id: &str,
|
||||
properties: Option<impl IntoIterator<Item = Property>>,
|
||||
body_properties: Option<impl IntoIterator<Item = BodyProperty>>,
|
||||
max_body_value_bytes: Option<usize>,
|
||||
) -> crate::Result<Email> {
|
||||
let mut request = self.build();
|
||||
let parse_request = request.parse_email().blob_ids([blob_id]);
|
||||
if let Some(properties) = properties {
|
||||
parse_request.properties(properties);
|
||||
}
|
||||
|
||||
if let Some(body_properties) = body_properties {
|
||||
parse_request.body_properties(body_properties);
|
||||
}
|
||||
|
||||
if let Some(max_body_value_bytes) = max_body_value_bytes {
|
||||
parse_request
|
||||
.fetch_all_body_values(true)
|
||||
.max_body_value_bytes(max_body_value_bytes);
|
||||
}
|
||||
|
||||
request
|
||||
.send_single::<EmailParseResponse>()
|
||||
.and_then(|mut r| r.parsed(blob_id))
|
||||
}
|
||||
|
||||
pub fn email_copy<T, U, V, W>(
|
||||
&self,
|
||||
from_account_id: impl Into<String>,
|
||||
id: impl Into<String>,
|
||||
mailbox_ids: T,
|
||||
keywords: Option<V>,
|
||||
received_at: Option<i64>,
|
||||
) -> crate::Result<Email>
|
||||
where
|
||||
T: IntoIterator<Item = U>,
|
||||
U: Into<String>,
|
||||
V: IntoIterator<Item = W>,
|
||||
W: Into<String>,
|
||||
{
|
||||
let id = id.into();
|
||||
let mut request = self.build();
|
||||
let email = request
|
||||
.copy_email(from_account_id)
|
||||
.create(id.clone())
|
||||
.mailbox_ids(mailbox_ids);
|
||||
|
||||
if let Some(keywords) = keywords {
|
||||
email.keywords(keywords);
|
||||
}
|
||||
|
||||
if let Some(received_at) = received_at {
|
||||
email.received_at(received_at);
|
||||
}
|
||||
|
||||
request.send_single::<EmailCopyResponse>()?.created(&id)
|
||||
}
|
||||
|
||||
pub fn search_snippet_get(
|
||||
&self,
|
||||
filter: Option<impl Into<Filter<super::query::Filter>>>,
|
||||
email_ids: impl IntoIterator<Item = impl Into<String>>,
|
||||
) -> crate::Result<SearchSnippetGetResponse> {
|
||||
let mut request = self.build();
|
||||
let snippet_request = request.get_search_snippet();
|
||||
if let Some(filter) = filter {
|
||||
snippet_request.filter(filter);
|
||||
}
|
||||
snippet_request.email_ids(email_ids);
|
||||
request.send_single::<SearchSnippetGetResponse>()
|
||||
}
|
||||
}
|
||||
|
||||
impl Request<'_> {
|
||||
pub fn get_email(&mut self) -> &mut GetRequest<Email<Set>> {
|
||||
self.add_method_call(
|
||||
Method::GetEmail,
|
||||
Arguments::email_get(self.params(Method::GetEmail)),
|
||||
)
|
||||
.email_get_mut()
|
||||
}
|
||||
|
||||
pub fn send_get_email(self) -> crate::Result<EmailGetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn changes_email(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
||||
self.add_method_call(
|
||||
Method::ChangesEmail,
|
||||
Arguments::changes(self.params(Method::ChangesEmail), since_state.into()),
|
||||
)
|
||||
.changes_mut()
|
||||
}
|
||||
|
||||
pub fn send_changes_email(self) -> crate::Result<ChangesResponse<Email<Get>>> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn query_email(&mut self) -> &mut QueryRequest<Email<Set>> {
|
||||
self.add_method_call(
|
||||
Method::QueryEmail,
|
||||
Arguments::email_query(self.params(Method::QueryEmail)),
|
||||
)
|
||||
.email_query_mut()
|
||||
}
|
||||
|
||||
pub fn send_query_email(self) -> crate::Result<QueryResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn query_email_changes(
|
||||
&mut self,
|
||||
since_query_state: impl Into<String>,
|
||||
) -> &mut QueryChangesRequest<Email<Set>> {
|
||||
self.add_method_call(
|
||||
Method::QueryChangesEmail,
|
||||
Arguments::email_query_changes(
|
||||
self.params(Method::QueryChangesEmail),
|
||||
since_query_state.into(),
|
||||
),
|
||||
)
|
||||
.email_query_changes_mut()
|
||||
}
|
||||
|
||||
pub fn send_query_email_changes(self) -> crate::Result<QueryChangesResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn set_email(&mut self) -> &mut SetRequest<Email<Set>> {
|
||||
self.add_method_call(
|
||||
Method::SetEmail,
|
||||
Arguments::email_set(self.params(Method::SetEmail)),
|
||||
)
|
||||
.email_set_mut()
|
||||
}
|
||||
|
||||
pub fn send_set_email(self) -> crate::Result<EmailSetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn copy_email(
|
||||
&mut self,
|
||||
from_account_id: impl Into<String>,
|
||||
) -> &mut CopyRequest<Email<Set>> {
|
||||
self.add_method_call(
|
||||
Method::CopyEmail,
|
||||
Arguments::email_copy(self.params(Method::CopyEmail), from_account_id.into()),
|
||||
)
|
||||
.email_copy_mut()
|
||||
}
|
||||
|
||||
pub fn send_copy_email(self) -> crate::Result<EmailCopyResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn import_email(&mut self) -> &mut EmailImportRequest {
|
||||
self.add_method_call(
|
||||
Method::ImportEmail,
|
||||
Arguments::email_import(self.params(Method::ImportEmail)),
|
||||
)
|
||||
.email_import_mut()
|
||||
}
|
||||
|
||||
pub fn send_import_email(self) -> crate::Result<EmailImportResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn parse_email(&mut self) -> &mut EmailParseRequest {
|
||||
self.add_method_call(
|
||||
Method::ParseEmail,
|
||||
Arguments::email_parse(self.params(Method::ParseEmail)),
|
||||
)
|
||||
.email_parse_mut()
|
||||
}
|
||||
|
||||
pub fn send_parse_email(self) -> crate::Result<EmailParseResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn get_search_snippet(&mut self) -> &mut SearchSnippetGetRequest {
|
||||
self.add_method_call(
|
||||
Method::GetSearchSnippet,
|
||||
Arguments::search_snippet_get(self.params(Method::GetSearchSnippet)),
|
||||
)
|
||||
.search_snippet_get_mut()
|
||||
}
|
||||
|
||||
pub fn send_get_search_snippet(self) -> crate::Result<SearchSnippetGetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
pub mod get;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod helpers;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub mod helpers_blocking;
|
||||
pub mod import;
|
||||
pub mod parse;
|
||||
pub mod query;
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
use crate::{
|
||||
client::Client,
|
||||
core::{
|
||||
changes::{ChangesRequest, ChangesResponse},
|
||||
get::GetRequest,
|
||||
query::{Comparator, Filter, QueryRequest, QueryResponse},
|
||||
query_changes::{QueryChangesRequest, QueryChangesResponse},
|
||||
request::{Arguments, Request},
|
||||
response::{EmailSubmissionGetResponse, EmailSubmissionSetResponse},
|
||||
set::{SetObject, SetRequest},
|
||||
},
|
||||
Get, Method, Set, URI,
|
||||
};
|
||||
|
||||
use super::{Address, EmailSubmission, Property, UndoStatus};
|
||||
|
||||
impl Client {
|
||||
pub fn email_submission_create(
|
||||
&self,
|
||||
email_id: impl Into<String>,
|
||||
identity_id: impl Into<String>,
|
||||
) -> crate::Result<EmailSubmission<Get>> {
|
||||
let mut request = self.build();
|
||||
let id = request
|
||||
.set_email_submission()
|
||||
.create()
|
||||
.email_id(email_id)
|
||||
.identity_id(identity_id)
|
||||
.create_id()
|
||||
.unwrap();
|
||||
request
|
||||
.send_single::<EmailSubmissionSetResponse>()?
|
||||
.created(&id)
|
||||
}
|
||||
|
||||
pub fn email_submission_create_envelope<S, T, U>(
|
||||
&self,
|
||||
email_id: impl Into<String>,
|
||||
identity_id: impl Into<String>,
|
||||
mail_from: S,
|
||||
rcpt_to: T,
|
||||
) -> crate::Result<EmailSubmission<Get>>
|
||||
where
|
||||
S: Into<Address>,
|
||||
T: IntoIterator<Item = U>,
|
||||
U: Into<Address>,
|
||||
{
|
||||
let mut request = self.build();
|
||||
let id = request
|
||||
.set_email_submission()
|
||||
.create()
|
||||
.email_id(email_id)
|
||||
.identity_id(identity_id)
|
||||
.envelope(mail_from, rcpt_to)
|
||||
.create_id()
|
||||
.unwrap();
|
||||
request
|
||||
.send_single::<EmailSubmissionSetResponse>()?
|
||||
.created(&id)
|
||||
}
|
||||
|
||||
pub fn email_submission_change_status(
|
||||
&self,
|
||||
id: &str,
|
||||
undo_status: UndoStatus,
|
||||
) -> crate::Result<Option<EmailSubmission>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.set_email_submission()
|
||||
.update(id)
|
||||
.undo_status(undo_status);
|
||||
request
|
||||
.send_single::<EmailSubmissionSetResponse>()?
|
||||
.updated(id)
|
||||
}
|
||||
|
||||
pub fn email_submission_destroy(&self, id: &str) -> crate::Result<()> {
|
||||
let mut request = self.build();
|
||||
request.set_email_submission().destroy([id]);
|
||||
request
|
||||
.send_single::<EmailSubmissionSetResponse>()?
|
||||
.destroyed(id)
|
||||
}
|
||||
|
||||
pub fn email_submission_get(
|
||||
&self,
|
||||
id: &str,
|
||||
properties: Option<Vec<Property>>,
|
||||
) -> crate::Result<Option<EmailSubmission>> {
|
||||
let mut request = self.build();
|
||||
let get_request = request.get_email_submission().ids([id]);
|
||||
if let Some(properties) = properties {
|
||||
get_request.properties(properties.into_iter());
|
||||
}
|
||||
request
|
||||
.send_single::<EmailSubmissionGetResponse>()
|
||||
.map(|mut r| r.take_list().pop())
|
||||
}
|
||||
|
||||
pub fn email_submission_query(
|
||||
&self,
|
||||
filter: Option<impl Into<Filter<super::query::Filter>>>,
|
||||
sort: Option<impl IntoIterator<Item = Comparator<super::query::Comparator>>>,
|
||||
) -> crate::Result<QueryResponse> {
|
||||
let mut request = self.build();
|
||||
let query_request = request.query_email_submission();
|
||||
if let Some(filter) = filter {
|
||||
query_request.filter(filter);
|
||||
}
|
||||
if let Some(sort) = sort {
|
||||
query_request.sort(sort.into_iter());
|
||||
}
|
||||
request.send_single::<QueryResponse>()
|
||||
}
|
||||
|
||||
pub fn email_submission_changes(
|
||||
&self,
|
||||
since_state: impl Into<String>,
|
||||
max_changes: usize,
|
||||
) -> crate::Result<ChangesResponse<EmailSubmission<Get>>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.changes_email_submission(since_state)
|
||||
.max_changes(max_changes);
|
||||
request.send_single()
|
||||
}
|
||||
}
|
||||
|
||||
impl Request<'_> {
|
||||
pub fn get_email_submission(&mut self) -> &mut GetRequest<EmailSubmission<Set>> {
|
||||
self.add_capability(URI::Submission);
|
||||
self.add_method_call(
|
||||
Method::GetEmailSubmission,
|
||||
Arguments::email_submission_get(self.params(Method::GetEmailSubmission)),
|
||||
)
|
||||
.email_submission_get_mut()
|
||||
}
|
||||
|
||||
pub fn send_get_email_submission(self) -> crate::Result<EmailSubmissionGetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn changes_email_submission(
|
||||
&mut self,
|
||||
since_state: impl Into<String>,
|
||||
) -> &mut ChangesRequest {
|
||||
self.add_capability(URI::Submission);
|
||||
self.add_method_call(
|
||||
Method::ChangesEmailSubmission,
|
||||
Arguments::changes(
|
||||
self.params(Method::ChangesEmailSubmission),
|
||||
since_state.into(),
|
||||
),
|
||||
)
|
||||
.changes_mut()
|
||||
}
|
||||
|
||||
pub fn send_changes_email_submission(
|
||||
self,
|
||||
) -> crate::Result<ChangesResponse<EmailSubmission<Get>>> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn query_email_submission(&mut self) -> &mut QueryRequest<EmailSubmission<Set>> {
|
||||
self.add_capability(URI::Submission);
|
||||
self.add_method_call(
|
||||
Method::QueryEmailSubmission,
|
||||
Arguments::email_submission_query(self.params(Method::QueryEmailSubmission)),
|
||||
)
|
||||
.email_submission_query_mut()
|
||||
}
|
||||
|
||||
pub fn send_query_email_submission(self) -> crate::Result<QueryResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn query_email_submission_changes(
|
||||
&mut self,
|
||||
since_query_state: impl Into<String>,
|
||||
) -> &mut QueryChangesRequest<EmailSubmission<Set>> {
|
||||
self.add_capability(URI::Submission);
|
||||
self.add_method_call(
|
||||
Method::QueryChangesEmailSubmission,
|
||||
Arguments::email_submission_query_changes(
|
||||
self.params(Method::QueryChangesEmailSubmission),
|
||||
since_query_state.into(),
|
||||
),
|
||||
)
|
||||
.email_submission_query_changes_mut()
|
||||
}
|
||||
|
||||
pub fn send_query_email_submission_changes(self) -> crate::Result<QueryChangesResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn set_email_submission(&mut self) -> &mut SetRequest<EmailSubmission<Set>> {
|
||||
self.add_capability(URI::Submission);
|
||||
self.add_method_call(
|
||||
Method::SetEmailSubmission,
|
||||
Arguments::email_submission_set(self.params(Method::SetEmailSubmission)),
|
||||
)
|
||||
.email_submission_set_mut()
|
||||
}
|
||||
|
||||
pub fn send_set_email_submission(self) -> crate::Result<EmailSubmissionSetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
pub mod get;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod helpers;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub mod helpers_blocking;
|
||||
pub mod query;
|
||||
pub mod set;
|
||||
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
use crate::{
|
||||
client::Client,
|
||||
core::{
|
||||
changes::{ChangesRequest, ChangesResponse},
|
||||
get::GetRequest,
|
||||
request::{Arguments, Request},
|
||||
response::{IdentityGetResponse, IdentitySetResponse},
|
||||
set::{SetObject, SetRequest},
|
||||
},
|
||||
Get, Method, Set,
|
||||
};
|
||||
|
||||
use super::{Identity, Property};
|
||||
|
||||
impl Client {
|
||||
pub fn identity_create(
|
||||
&self,
|
||||
name: impl Into<String>,
|
||||
email: impl Into<String>,
|
||||
) -> crate::Result<Identity> {
|
||||
let mut request = self.build();
|
||||
let id = request
|
||||
.set_identity()
|
||||
.create()
|
||||
.name(name)
|
||||
.email(email)
|
||||
.create_id()
|
||||
.unwrap();
|
||||
request.send_single::<IdentitySetResponse>()?.created(&id)
|
||||
}
|
||||
|
||||
pub fn identity_destroy(&self, id: &str) -> crate::Result<()> {
|
||||
let mut request = self.build();
|
||||
request.set_identity().destroy([id]);
|
||||
request.send_single::<IdentitySetResponse>()?.destroyed(id)
|
||||
}
|
||||
|
||||
pub fn identity_get(
|
||||
&self,
|
||||
id: &str,
|
||||
properties: Option<Vec<Property>>,
|
||||
) -> crate::Result<Option<Identity>> {
|
||||
let mut request = self.build();
|
||||
let get_request = request.get_identity().ids([id]);
|
||||
if let Some(properties) = properties {
|
||||
get_request.properties(properties.into_iter());
|
||||
}
|
||||
request
|
||||
.send_single::<IdentityGetResponse>()
|
||||
.map(|mut r| r.take_list().pop())
|
||||
}
|
||||
|
||||
pub fn identity_changes(
|
||||
&self,
|
||||
since_state: impl Into<String>,
|
||||
max_changes: usize,
|
||||
) -> crate::Result<ChangesResponse<Identity<Get>>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.changes_identity(since_state)
|
||||
.max_changes(max_changes);
|
||||
request.send_single()
|
||||
}
|
||||
}
|
||||
|
||||
impl Request<'_> {
|
||||
pub fn get_identity(&mut self) -> &mut GetRequest<Identity<Set>> {
|
||||
self.add_method_call(
|
||||
Method::GetIdentity,
|
||||
Arguments::identity_get(self.params(Method::GetIdentity)),
|
||||
)
|
||||
.identity_get_mut()
|
||||
}
|
||||
|
||||
pub fn send_get_identity(self) -> crate::Result<IdentityGetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn set_identity(&mut self) -> &mut SetRequest<Identity<Set>> {
|
||||
self.add_method_call(
|
||||
Method::SetIdentity,
|
||||
Arguments::identity_set(self.params(Method::SetIdentity)),
|
||||
)
|
||||
.identity_set_mut()
|
||||
}
|
||||
|
||||
pub fn send_set_identity(self) -> crate::Result<IdentitySetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn changes_identity(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
||||
self.add_method_call(
|
||||
Method::ChangesIdentity,
|
||||
Arguments::changes(self.params(Method::ChangesIdentity), since_state.into()),
|
||||
)
|
||||
.changes_mut()
|
||||
}
|
||||
|
||||
pub fn send_changes_identity(self) -> crate::Result<ChangesResponse<Identity<Get>>> {
|
||||
self.send_single()
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
pub mod get;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod helpers;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub mod helpers_blocking;
|
||||
pub mod set;
|
||||
|
||||
use std::fmt::Display;
|
||||
|
|
|
@ -10,6 +10,7 @@ pub mod client;
|
|||
pub mod core;
|
||||
pub mod email;
|
||||
pub mod email_submission;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod event_source;
|
||||
pub mod identity;
|
||||
pub mod mailbox;
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
use crate::{
|
||||
client::Client,
|
||||
core::{
|
||||
changes::{ChangesRequest, ChangesResponse},
|
||||
get::GetRequest,
|
||||
query::{Comparator, Filter, QueryRequest, QueryResponse},
|
||||
query_changes::{QueryChangesRequest, QueryChangesResponse},
|
||||
request::{Arguments, Request},
|
||||
response::{MailboxGetResponse, MailboxSetResponse},
|
||||
set::{SetObject, SetRequest},
|
||||
},
|
||||
principal::ACL,
|
||||
Get, Method, Set,
|
||||
};
|
||||
|
||||
use super::{Mailbox, Property, Role};
|
||||
|
||||
impl Client {
|
||||
pub fn mailbox_create(
|
||||
&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>()?.created(&id)
|
||||
}
|
||||
|
||||
pub fn mailbox_rename(
|
||||
&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>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn mailbox_move(
|
||||
&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>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn mailbox_update_role(&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>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn mailbox_update_acl(
|
||||
&self,
|
||||
id: &str,
|
||||
account_id: &str,
|
||||
acl: impl IntoIterator<Item = ACL>,
|
||||
) -> crate::Result<Option<Mailbox>> {
|
||||
let mut request = self.build();
|
||||
request.set_mailbox().update(id).acl(account_id, acl);
|
||||
request.send_single::<MailboxSetResponse>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn mailbox_update_sort_order(
|
||||
&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>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn mailbox_subscribe(
|
||||
&self,
|
||||
id: &str,
|
||||
is_subscribed: bool,
|
||||
) -> crate::Result<Option<Mailbox>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.set_mailbox()
|
||||
.update(id)
|
||||
.is_subscribed(is_subscribed);
|
||||
request.send_single::<MailboxSetResponse>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn mailbox_destroy(&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>()?.destroyed(id)
|
||||
}
|
||||
|
||||
pub fn mailbox_get(
|
||||
&self,
|
||||
id: &str,
|
||||
properties: Option<impl IntoIterator<Item = 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>()
|
||||
.map(|mut r| r.take_list().pop())
|
||||
}
|
||||
|
||||
pub fn mailbox_query(
|
||||
&self,
|
||||
filter: Option<impl Into<Filter<super::query::Filter>>>,
|
||||
sort: Option<impl IntoIterator<Item = 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>()
|
||||
}
|
||||
|
||||
pub fn mailbox_changes(
|
||||
&self,
|
||||
since_state: impl Into<String>,
|
||||
max_changes: usize,
|
||||
) -> crate::Result<ChangesResponse<Mailbox<Get>>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.changes_mailbox(since_state)
|
||||
.max_changes(max_changes);
|
||||
request.send_single()
|
||||
}
|
||||
}
|
||||
|
||||
impl Request<'_> {
|
||||
pub fn get_mailbox(&mut self) -> &mut GetRequest<Mailbox<Set>> {
|
||||
self.add_method_call(
|
||||
Method::GetMailbox,
|
||||
Arguments::mailbox_get(self.params(Method::GetMailbox)),
|
||||
)
|
||||
.mailbox_get_mut()
|
||||
}
|
||||
|
||||
pub fn send_get_mailbox(self) -> crate::Result<MailboxGetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn changes_mailbox(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
||||
self.add_method_call(
|
||||
Method::ChangesMailbox,
|
||||
Arguments::changes(self.params(Method::ChangesMailbox), since_state.into()),
|
||||
)
|
||||
.changes_mut()
|
||||
}
|
||||
|
||||
pub fn send_changes_mailbox(self) -> crate::Result<ChangesResponse<Mailbox<Get>>> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn query_mailbox(&mut self) -> &mut QueryRequest<Mailbox<Set>> {
|
||||
self.add_method_call(
|
||||
Method::QueryMailbox,
|
||||
Arguments::mailbox_query(self.params(Method::QueryMailbox)),
|
||||
)
|
||||
.mailbox_query_mut()
|
||||
}
|
||||
|
||||
pub fn send_query_mailbox(self) -> crate::Result<QueryResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn query_mailbox_changes(
|
||||
&mut self,
|
||||
since_query_state: impl Into<String>,
|
||||
) -> &mut QueryChangesRequest<Mailbox<Set>> {
|
||||
self.add_method_call(
|
||||
Method::QueryChangesMailbox,
|
||||
Arguments::mailbox_query_changes(
|
||||
self.params(Method::QueryChangesMailbox),
|
||||
since_query_state.into(),
|
||||
),
|
||||
)
|
||||
.mailbox_query_changes_mut()
|
||||
}
|
||||
|
||||
pub fn send_query_mailbox_changes(self) -> crate::Result<QueryChangesResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn set_mailbox(&mut self) -> &mut SetRequest<Mailbox<Set>> {
|
||||
self.add_method_call(
|
||||
Method::SetMailbox,
|
||||
Arguments::mailbox_set(self.params(Method::SetMailbox)),
|
||||
)
|
||||
.mailbox_set_mut()
|
||||
}
|
||||
|
||||
pub fn send_set_mailbox(self) -> crate::Result<MailboxSetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
pub mod get;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod helpers;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub mod helpers_blocking;
|
||||
pub mod query;
|
||||
pub mod set;
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@ impl Principal<Get> {
|
|||
self.description.as_deref()
|
||||
}
|
||||
|
||||
pub fn timezone(&self) -> Option<&str> {
|
||||
self.timezone.as_deref()
|
||||
}
|
||||
|
||||
pub fn secret(&self) -> Option<&str> {
|
||||
self.secret.as_deref()
|
||||
}
|
||||
|
|
|
@ -202,7 +202,7 @@ impl Client {
|
|||
pub async fn principal_get(
|
||||
&self,
|
||||
id: &str,
|
||||
properties: Option<Vec<Property>>,
|
||||
properties: Option<impl IntoIterator<Item = Property>>,
|
||||
) -> crate::Result<Option<Principal>> {
|
||||
let mut request = self.build();
|
||||
let get_request = request.get_principal().ids([id]);
|
||||
|
|
|
@ -0,0 +1,276 @@
|
|||
use crate::{
|
||||
client::Client,
|
||||
core::{
|
||||
changes::{ChangesRequest, ChangesResponse},
|
||||
get::GetRequest,
|
||||
query::{Comparator, Filter, QueryRequest, QueryResponse},
|
||||
query_changes::{QueryChangesRequest, QueryChangesResponse},
|
||||
request::{Arguments, Request},
|
||||
response::{PrincipalGetResponse, PrincipalSetResponse},
|
||||
set::{SetObject, SetRequest},
|
||||
},
|
||||
Get, Method, Set,
|
||||
};
|
||||
|
||||
use super::{Principal, Property, Type};
|
||||
|
||||
impl Client {
|
||||
pub fn individual_create(
|
||||
&self,
|
||||
email: impl Into<String>,
|
||||
secret: impl Into<String>,
|
||||
name: impl Into<String>,
|
||||
) -> crate::Result<Principal> {
|
||||
let mut request = self.build();
|
||||
let id = request
|
||||
.set_principal()
|
||||
.create()
|
||||
.name(name)
|
||||
.secret(secret)
|
||||
.email(email)
|
||||
.ptype(Type::Individual)
|
||||
.create_id()
|
||||
.unwrap();
|
||||
request.send_single::<PrincipalSetResponse>()?.created(&id)
|
||||
}
|
||||
|
||||
pub fn domain_create(&self, name: impl Into<String>) -> crate::Result<Principal> {
|
||||
let mut request = self.build();
|
||||
let id = request
|
||||
.set_principal()
|
||||
.create()
|
||||
.name(name)
|
||||
.ptype(Type::Domain)
|
||||
.create_id()
|
||||
.unwrap();
|
||||
request.send_single::<PrincipalSetResponse>()?.created(&id)
|
||||
}
|
||||
|
||||
pub fn list_create(
|
||||
&self,
|
||||
email: impl Into<String>,
|
||||
name: impl Into<String>,
|
||||
members: impl IntoIterator<Item = impl Into<String>>,
|
||||
) -> crate::Result<Principal> {
|
||||
let mut request = self.build();
|
||||
let id = request
|
||||
.set_principal()
|
||||
.create()
|
||||
.name(name)
|
||||
.email(email)
|
||||
.ptype(Type::List)
|
||||
.members(members.into())
|
||||
.create_id()
|
||||
.unwrap();
|
||||
request.send_single::<PrincipalSetResponse>()?.created(&id)
|
||||
}
|
||||
|
||||
pub fn group_create(
|
||||
&self,
|
||||
email: impl Into<String>,
|
||||
name: impl Into<String>,
|
||||
members: impl IntoIterator<Item = impl Into<String>>,
|
||||
) -> crate::Result<Principal> {
|
||||
let mut request = self.build();
|
||||
let id = request
|
||||
.set_principal()
|
||||
.create()
|
||||
.name(name)
|
||||
.email(email)
|
||||
.ptype(Type::Group)
|
||||
.members(members.into())
|
||||
.create_id()
|
||||
.unwrap();
|
||||
request.send_single::<PrincipalSetResponse>()?.created(&id)
|
||||
}
|
||||
|
||||
pub fn principal_set_name(
|
||||
&self,
|
||||
id: &str,
|
||||
name: impl Into<String>,
|
||||
) -> crate::Result<Option<Principal>> {
|
||||
let mut request = self.build();
|
||||
request.set_principal().update(id).name(name);
|
||||
request.send_single::<PrincipalSetResponse>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn principal_set_secret(
|
||||
&self,
|
||||
id: &str,
|
||||
secret: impl Into<String>,
|
||||
) -> crate::Result<Option<Principal>> {
|
||||
let mut request = self.build();
|
||||
request.set_principal().update(id).secret(secret);
|
||||
request.send_single::<PrincipalSetResponse>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn principal_set_email(
|
||||
&self,
|
||||
id: &str,
|
||||
email: impl Into<String>,
|
||||
) -> crate::Result<Option<Principal>> {
|
||||
let mut request = self.build();
|
||||
request.set_principal().update(id).email(email);
|
||||
request.send_single::<PrincipalSetResponse>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn principal_set_timezone(
|
||||
&self,
|
||||
id: &str,
|
||||
timezone: Option<impl Into<String>>,
|
||||
) -> crate::Result<Option<Principal>> {
|
||||
let mut request = self.build();
|
||||
request.set_principal().update(id).timezone(timezone);
|
||||
request.send_single::<PrincipalSetResponse>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn principal_set_members(
|
||||
&self,
|
||||
id: &str,
|
||||
members: Option<impl IntoIterator<Item = impl Into<String>>>,
|
||||
) -> crate::Result<Option<Principal>> {
|
||||
let mut request = self.build();
|
||||
request.set_principal().update(id).members(members);
|
||||
request.send_single::<PrincipalSetResponse>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn principal_set_aliases(
|
||||
&self,
|
||||
id: &str,
|
||||
aliases: Option<impl IntoIterator<Item = impl Into<String>>>,
|
||||
) -> crate::Result<Option<Principal>> {
|
||||
let mut request = self.build();
|
||||
request.set_principal().update(id).aliases(aliases);
|
||||
request.send_single::<PrincipalSetResponse>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn principal_set_capabilities(
|
||||
&self,
|
||||
id: &str,
|
||||
capabilities: Option<impl IntoIterator<Item = impl Into<String>>>,
|
||||
) -> crate::Result<Option<Principal>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.set_principal()
|
||||
.update(id)
|
||||
.capabilities(capabilities);
|
||||
request.send_single::<PrincipalSetResponse>()?.updated(id)
|
||||
}
|
||||
|
||||
pub fn principal_destroy(&self, id: &str) -> crate::Result<()> {
|
||||
let mut request = self.build();
|
||||
request.set_principal().destroy([id]).arguments();
|
||||
request.send_single::<PrincipalSetResponse>()?.destroyed(id)
|
||||
}
|
||||
|
||||
pub fn principal_get(
|
||||
&self,
|
||||
id: &str,
|
||||
properties: Option<impl IntoIterator<Item = Property>>,
|
||||
) -> crate::Result<Option<Principal>> {
|
||||
let mut request = self.build();
|
||||
let get_request = request.get_principal().ids([id]);
|
||||
if let Some(properties) = properties {
|
||||
get_request.properties(properties.into_iter());
|
||||
}
|
||||
request
|
||||
.send_single::<PrincipalGetResponse>()
|
||||
.map(|mut r| r.take_list().pop())
|
||||
}
|
||||
|
||||
pub fn principal_query(
|
||||
&self,
|
||||
filter: Option<impl Into<Filter<super::query::Filter>>>,
|
||||
sort: Option<impl IntoIterator<Item = Comparator<super::query::Comparator>>>,
|
||||
) -> crate::Result<QueryResponse> {
|
||||
let mut request = self.build();
|
||||
let query_request = request.query_principal();
|
||||
if let Some(filter) = filter {
|
||||
query_request.filter(filter);
|
||||
}
|
||||
if let Some(sort) = sort {
|
||||
query_request.sort(sort.into_iter());
|
||||
}
|
||||
request.send_single::<QueryResponse>()
|
||||
}
|
||||
|
||||
pub fn principal_changes(
|
||||
&self,
|
||||
since_state: impl Into<String>,
|
||||
max_changes: usize,
|
||||
) -> crate::Result<ChangesResponse<Principal<Get>>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.changes_principal(since_state)
|
||||
.max_changes(max_changes);
|
||||
request.send_single()
|
||||
}
|
||||
}
|
||||
|
||||
impl Request<'_> {
|
||||
pub fn get_principal(&mut self) -> &mut GetRequest<Principal<Set>> {
|
||||
self.add_method_call(
|
||||
Method::GetPrincipal,
|
||||
Arguments::principal_get(self.params(Method::GetPrincipal)),
|
||||
)
|
||||
.principal_get_mut()
|
||||
}
|
||||
|
||||
pub fn send_get_principal(self) -> crate::Result<PrincipalGetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn changes_principal(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
||||
self.add_method_call(
|
||||
Method::ChangesPrincipal,
|
||||
Arguments::changes(self.params(Method::ChangesPrincipal), since_state.into()),
|
||||
)
|
||||
.changes_mut()
|
||||
}
|
||||
|
||||
pub fn send_changes_principal(self) -> crate::Result<ChangesResponse<Principal<Get>>> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn query_principal(&mut self) -> &mut QueryRequest<Principal<Set>> {
|
||||
self.add_method_call(
|
||||
Method::QueryPrincipal,
|
||||
Arguments::principal_query(self.params(Method::QueryPrincipal)),
|
||||
)
|
||||
.principal_query_mut()
|
||||
}
|
||||
|
||||
pub fn send_query_principal(self) -> crate::Result<QueryResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn query_principal_changes(
|
||||
&mut self,
|
||||
since_query_state: impl Into<String>,
|
||||
) -> &mut QueryChangesRequest<Principal<Set>> {
|
||||
self.add_method_call(
|
||||
Method::QueryChangesPrincipal,
|
||||
Arguments::principal_query_changes(
|
||||
self.params(Method::QueryChangesPrincipal),
|
||||
since_query_state.into(),
|
||||
),
|
||||
)
|
||||
.principal_query_changes_mut()
|
||||
}
|
||||
|
||||
pub fn send_query_principal_changes(self) -> crate::Result<QueryChangesResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn set_principal(&mut self) -> &mut SetRequest<Principal<Set>> {
|
||||
self.add_method_call(
|
||||
Method::SetPrincipal,
|
||||
Arguments::principal_set(self.params(Method::SetPrincipal)),
|
||||
)
|
||||
.principal_set_mut()
|
||||
}
|
||||
|
||||
pub fn send_set_principal(self) -> crate::Result<PrincipalSetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
pub mod get;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod helpers;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub mod helpers_blocking;
|
||||
pub mod query;
|
||||
pub mod set;
|
||||
|
||||
|
@ -23,33 +26,51 @@ pub struct Principal<State = Get> {
|
|||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
id: Option<String>,
|
||||
|
||||
#[serde(rename = "type")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
ptype: Option<Type>,
|
||||
|
||||
#[serde(skip_serializing_if = "string_not_set")]
|
||||
name: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "string_not_set")]
|
||||
description: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "string_not_set")]
|
||||
email: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "string_not_set")]
|
||||
timezone: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "list_not_set")]
|
||||
capabilities: Option<Vec<String>>,
|
||||
|
||||
#[serde(skip_serializing_if = "list_not_set")]
|
||||
aliases: Option<Vec<String>>,
|
||||
|
||||
#[serde(skip_serializing_if = "string_not_set")]
|
||||
secret: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
dkim: Option<DKIM>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
quota: Option<u32>,
|
||||
|
||||
#[serde(skip_serializing_if = "string_not_set")]
|
||||
picture: Option<String>,
|
||||
|
||||
#[serde(skip_serializing_if = "list_not_set")]
|
||||
members: Option<Vec<String>>,
|
||||
|
||||
#[serde(skip_serializing_if = "map_not_set")]
|
||||
acl: Option<AHashMap<String, Vec<ACL>>>,
|
||||
|
||||
#[serde(flatten)]
|
||||
#[serde(skip_deserializing)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
property_patch: Option<AHashMap<String, bool>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Copy)]
|
||||
|
@ -129,9 +150,26 @@ pub enum Type {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct DKIM {
|
||||
#[serde(rename = "dkimSelector")]
|
||||
pub dkim_selector: Option<String>,
|
||||
dkim_selector: Option<String>,
|
||||
#[serde(rename = "dkimExpiration")]
|
||||
pub dkim_expiration: Option<i64>,
|
||||
dkim_expiration: Option<i64>,
|
||||
}
|
||||
|
||||
impl DKIM {
|
||||
pub fn new(dkim_selector: Option<String>, dkim_expiration: Option<i64>) -> DKIM {
|
||||
DKIM {
|
||||
dkim_selector,
|
||||
dkim_expiration,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn selector(&self) -> Option<&str> {
|
||||
self.dkim_selector.as_deref()
|
||||
}
|
||||
|
||||
pub fn expiration(&self) -> Option<i64> {
|
||||
self.dkim_expiration
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Property {
|
||||
|
|
|
@ -18,6 +18,10 @@ pub enum Filter {
|
|||
#[serde(rename = "name")]
|
||||
value: String,
|
||||
},
|
||||
DomainName {
|
||||
#[serde(rename = "domainName")]
|
||||
value: String,
|
||||
},
|
||||
Text {
|
||||
#[serde(rename = "text")]
|
||||
value: String,
|
||||
|
@ -61,16 +65,25 @@ impl Filter {
|
|||
value: value.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn domain_name(value: impl Into<String>) -> Self {
|
||||
Filter::DomainName {
|
||||
value: value.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn email(value: impl Into<String>) -> Self {
|
||||
Filter::Email {
|
||||
value: value.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn text(value: impl Into<String>) -> Self {
|
||||
Filter::Text {
|
||||
value: value.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn timezone(value: impl Into<String>) -> Self {
|
||||
Filter::Timezone {
|
||||
value: value.into(),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::{Principal, Type, ACL, DKIM};
|
||||
use super::{Principal, Property, Type, ACL, DKIM};
|
||||
use crate::{core::set::SetObject, Get, Set};
|
||||
use ahash::AHashMap;
|
||||
|
||||
|
@ -62,6 +62,13 @@ impl Principal<Set> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn alias(&mut self, alias: &str, set: bool) -> &mut Self {
|
||||
self.property_patch
|
||||
.get_or_insert_with(AHashMap::new)
|
||||
.insert(format!("{}/{}", Property::Aliases, alias), set);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn capabilities<T, U>(&mut self, capabilities: Option<T>) -> &mut Self
|
||||
where
|
||||
T: IntoIterator<Item = U>,
|
||||
|
@ -79,6 +86,13 @@ impl Principal<Set> {
|
|||
self.members = members.map(|l| l.into_iter().map(|v| v.into()).collect());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn member(&mut self, member: &str, set: bool) -> &mut Self {
|
||||
self.property_patch
|
||||
.get_or_insert_with(AHashMap::new)
|
||||
.insert(format!("{}/{}", Property::Members, member), set);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl SetObject for Principal<Set> {
|
||||
|
@ -102,6 +116,7 @@ impl SetObject for Principal<Set> {
|
|||
picture: "".to_string().into(),
|
||||
members: Vec::with_capacity(0).into(),
|
||||
acl: AHashMap::with_capacity(0).into(),
|
||||
property_patch: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
use crate::{
|
||||
client::Client,
|
||||
core::{
|
||||
get::GetRequest,
|
||||
request::{Arguments, Request},
|
||||
response::{PushSubscriptionGetResponse, PushSubscriptionSetResponse},
|
||||
set::{SetObject, SetRequest},
|
||||
},
|
||||
Method, Set, TypeState,
|
||||
};
|
||||
|
||||
use super::{Keys, PushSubscription};
|
||||
|
||||
impl Client {
|
||||
pub fn push_subscription_create(
|
||||
&self,
|
||||
device_client_id: impl Into<String>,
|
||||
url: impl Into<String>,
|
||||
keys: Option<Keys>,
|
||||
) -> crate::Result<PushSubscription> {
|
||||
let mut request = self.build();
|
||||
let create_req = request
|
||||
.set_push_subscription()
|
||||
.create()
|
||||
.device_client_id(device_client_id)
|
||||
.url(url);
|
||||
|
||||
if let Some(keys) = keys {
|
||||
create_req.keys(keys);
|
||||
}
|
||||
|
||||
let id = create_req.create_id().unwrap();
|
||||
request
|
||||
.send_single::<PushSubscriptionSetResponse>()?
|
||||
.created(&id)
|
||||
}
|
||||
|
||||
pub fn push_subscription_verify(
|
||||
&self,
|
||||
id: &str,
|
||||
verification_code: impl Into<String>,
|
||||
) -> crate::Result<Option<PushSubscription>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.set_push_subscription()
|
||||
.update(id)
|
||||
.verification_code(verification_code);
|
||||
request
|
||||
.send_single::<PushSubscriptionSetResponse>()?
|
||||
.updated(id)
|
||||
}
|
||||
|
||||
pub fn push_subscription_update_types(
|
||||
&self,
|
||||
id: &str,
|
||||
types: Option<impl IntoIterator<Item = TypeState>>,
|
||||
) -> crate::Result<Option<PushSubscription>> {
|
||||
let mut request = self.build();
|
||||
request.set_push_subscription().update(id).types(types);
|
||||
request
|
||||
.send_single::<PushSubscriptionSetResponse>()?
|
||||
.updated(id)
|
||||
}
|
||||
|
||||
pub fn push_subscription_destroy(&self, id: &str) -> crate::Result<()> {
|
||||
let mut request = self.build();
|
||||
request.set_push_subscription().destroy([id]);
|
||||
request
|
||||
.send_single::<PushSubscriptionSetResponse>()?
|
||||
.destroyed(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl Request<'_> {
|
||||
pub fn get_push_subscription(&mut self) -> &mut GetRequest<PushSubscription<Set>> {
|
||||
self.add_method_call(
|
||||
Method::GetPushSubscription,
|
||||
Arguments::push_get(self.params(Method::GetPushSubscription)),
|
||||
)
|
||||
.push_get_mut()
|
||||
}
|
||||
|
||||
pub fn send_get_push_subscription(self) -> crate::Result<PushSubscriptionGetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn set_push_subscription(&mut self) -> &mut SetRequest<PushSubscription<Set>> {
|
||||
self.add_method_call(
|
||||
Method::SetPushSubscription,
|
||||
Arguments::push_set(self.params(Method::SetPushSubscription)),
|
||||
)
|
||||
.push_set_mut()
|
||||
}
|
||||
|
||||
pub fn send_set_push_subscription(self) -> crate::Result<PushSubscriptionSetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
pub mod get;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod helpers;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub mod helpers_blocking;
|
||||
pub mod set;
|
||||
|
||||
use std::fmt::Display;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use crate::core::get::GetObject;
|
||||
|
||||
use super::Thread;
|
||||
|
||||
impl Thread {
|
||||
|
@ -9,3 +11,7 @@ impl Thread {
|
|||
&self.email_ids
|
||||
}
|
||||
}
|
||||
|
||||
impl GetObject for Thread {
|
||||
type GetArguments = ();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||
client::Client,
|
||||
core::{
|
||||
changes::{ChangesRequest, ChangesResponse},
|
||||
get::{GetObject, GetRequest},
|
||||
get::GetRequest,
|
||||
request::{Arguments, Request},
|
||||
response::ThreadGetResponse,
|
||||
},
|
||||
|
@ -47,7 +47,3 @@ impl Request<'_> {
|
|||
self.send_single().await
|
||||
}
|
||||
}
|
||||
|
||||
impl GetObject for Thread {
|
||||
type GetArguments = ();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
use crate::{
|
||||
client::Client,
|
||||
core::{
|
||||
changes::{ChangesRequest, ChangesResponse},
|
||||
get::GetRequest,
|
||||
request::{Arguments, Request},
|
||||
response::ThreadGetResponse,
|
||||
},
|
||||
Method,
|
||||
};
|
||||
|
||||
use super::Thread;
|
||||
|
||||
impl Client {
|
||||
pub fn thread_get(&self, id: &str) -> crate::Result<Option<Thread>> {
|
||||
let mut request = self.build();
|
||||
request.get_thread().ids([id]);
|
||||
request
|
||||
.send_single::<ThreadGetResponse>()
|
||||
.map(|mut r| r.take_list().pop())
|
||||
}
|
||||
}
|
||||
|
||||
impl Request<'_> {
|
||||
pub fn get_thread(&mut self) -> &mut GetRequest<Thread> {
|
||||
self.add_method_call(
|
||||
Method::GetThread,
|
||||
Arguments::thread_get(self.params(Method::GetThread)),
|
||||
)
|
||||
.thread_get_mut()
|
||||
}
|
||||
|
||||
pub fn send_get_thread(self) -> crate::Result<ThreadGetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn changes_thread(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
|
||||
self.add_method_call(
|
||||
Method::ChangesThread,
|
||||
Arguments::changes(self.params(Method::ChangesThread), since_state.into()),
|
||||
)
|
||||
.changes_mut()
|
||||
}
|
||||
|
||||
pub fn send_changes_thread(self) -> crate::Result<ChangesResponse<Thread>> {
|
||||
self.send_single()
|
||||
}
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
pub mod get;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod helpers;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub mod helpers_blocking;
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::core::{Object, changes::ChangesObject};
|
||||
use crate::core::{changes::ChangesObject, Object};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Thread {
|
||||
|
@ -42,4 +45,3 @@ impl Display for Property {
|
|||
impl ChangesObject for Thread {
|
||||
type ChangesResponse = ();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
use crate::{
|
||||
client::Client,
|
||||
core::{
|
||||
get::GetRequest,
|
||||
request::{Arguments, Request},
|
||||
response::{VacationResponseGetResponse, VacationResponseSetResponse},
|
||||
set::{SetObject, SetRequest},
|
||||
},
|
||||
Method, Set, URI,
|
||||
};
|
||||
|
||||
use super::{Property, VacationResponse};
|
||||
|
||||
impl Client {
|
||||
pub fn vacation_response_create(
|
||||
&self,
|
||||
subject: impl Into<String>,
|
||||
text_body: Option<impl Into<String>>,
|
||||
html_body: Option<impl Into<String>>,
|
||||
) -> crate::Result<VacationResponse> {
|
||||
let mut request = self.build();
|
||||
let created_id = request
|
||||
.set_vacation_response()
|
||||
.create()
|
||||
.is_enabled(true)
|
||||
.subject(Some(subject))
|
||||
.text_body(text_body)
|
||||
.html_body(html_body)
|
||||
.create_id()
|
||||
.unwrap();
|
||||
|
||||
request
|
||||
.send_single::<VacationResponseSetResponse>()?
|
||||
.created(&created_id)
|
||||
}
|
||||
|
||||
pub fn vacation_response_enable(
|
||||
&self,
|
||||
subject: impl Into<String>,
|
||||
text_body: Option<impl Into<String>>,
|
||||
html_body: Option<impl Into<String>>,
|
||||
) -> crate::Result<Option<VacationResponse>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.set_vacation_response()
|
||||
.update("singleton")
|
||||
.is_enabled(true)
|
||||
.subject(Some(subject))
|
||||
.text_body(text_body)
|
||||
.html_body(html_body);
|
||||
|
||||
request
|
||||
.send_single::<VacationResponseSetResponse>()?
|
||||
.updated("singleton")
|
||||
}
|
||||
|
||||
pub fn vacation_response_disable(&self) -> crate::Result<Option<VacationResponse>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.set_vacation_response()
|
||||
.update("singleton")
|
||||
.is_enabled(false);
|
||||
|
||||
request
|
||||
.send_single::<VacationResponseSetResponse>()?
|
||||
.updated("singleton")
|
||||
}
|
||||
|
||||
pub fn vacation_response_set_dates(
|
||||
&self,
|
||||
from_date: Option<i64>,
|
||||
to_date: Option<i64>,
|
||||
) -> crate::Result<Option<VacationResponse>> {
|
||||
let mut request = self.build();
|
||||
request
|
||||
.set_vacation_response()
|
||||
.update("singleton")
|
||||
.is_enabled(true)
|
||||
.from_date(from_date)
|
||||
.to_date(to_date);
|
||||
|
||||
request
|
||||
.send_single::<VacationResponseSetResponse>()?
|
||||
.updated("singleton")
|
||||
}
|
||||
|
||||
pub fn vacation_response_get(
|
||||
&self,
|
||||
properties: Option<Vec<Property>>,
|
||||
) -> crate::Result<Option<VacationResponse>> {
|
||||
let mut request = self.build();
|
||||
let get_request = request.get_vacation_response().ids(["singleton"]);
|
||||
if let Some(properties) = properties {
|
||||
get_request.properties(properties.into_iter());
|
||||
}
|
||||
request
|
||||
.send_single::<VacationResponseGetResponse>()
|
||||
.map(|mut r| r.take_list().pop())
|
||||
}
|
||||
|
||||
pub fn vacation_response_destroy(&self) -> crate::Result<()> {
|
||||
let mut request = self.build();
|
||||
request.set_vacation_response().destroy(["singleton"]);
|
||||
request
|
||||
.send_single::<VacationResponseSetResponse>()?
|
||||
.destroyed("singleton")
|
||||
}
|
||||
}
|
||||
|
||||
impl Request<'_> {
|
||||
pub fn get_vacation_response(&mut self) -> &mut GetRequest<VacationResponse<Set>> {
|
||||
self.add_capability(URI::VacationResponse);
|
||||
self.add_method_call(
|
||||
Method::GetVacationResponse,
|
||||
Arguments::vacation_response_get(self.params(Method::GetVacationResponse)),
|
||||
)
|
||||
.vacation_response_get_mut()
|
||||
}
|
||||
|
||||
pub fn send_get_vacation_response(self) -> crate::Result<VacationResponseGetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
|
||||
pub fn set_vacation_response(&mut self) -> &mut SetRequest<VacationResponse<Set>> {
|
||||
self.add_capability(URI::VacationResponse);
|
||||
self.add_method_call(
|
||||
Method::SetVacationResponse,
|
||||
Arguments::vacation_response_set(self.params(Method::GetVacationResponse)),
|
||||
)
|
||||
.vacation_response_set_mut()
|
||||
}
|
||||
|
||||
pub fn send_set_vacation_response(self) -> crate::Result<VacationResponseSetResponse> {
|
||||
self.send_single()
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
pub mod get;
|
||||
#[cfg(feature = "async")]
|
||||
pub mod helpers;
|
||||
#[cfg(feature = "blocking")]
|
||||
pub mod helpers_blocking;
|
||||
pub mod set;
|
||||
|
||||
use std::fmt::Display;
|
||||
|
|
Loading…
Reference in New Issue