diff --git a/src/blob/copy.rs b/src/blob/copy.rs index 8ea6bed..0eb98f5 100644 --- a/src/blob/copy.rs +++ b/src/blob/copy.rs @@ -2,7 +2,10 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; -use crate::core::{set::SetError, RequestParams}; +use crate::{ + core::{set::SetError, RequestParams}, + Error, +}; #[derive(Debug, Clone, Serialize)] pub struct CopyBlobRequest { @@ -27,16 +30,16 @@ pub struct CopyBlobResponse { } impl CopyBlobRequest { - pub fn new(params: RequestParams, from_account_id: String) -> Self { + pub fn new(params: RequestParams, from_account_id: impl Into) -> Self { CopyBlobRequest { - from_account_id, + from_account_id: from_account_id.into(), account_id: params.account_id, blob_ids: vec![], } } - pub fn blob_id(&mut self, blob_id: String) -> &mut Self { - self.blob_ids.push(blob_id); + pub fn blob_id(&mut self, blob_id: impl Into) -> &mut Self { + self.blob_ids.push(blob_id.into()); self } } @@ -50,17 +53,21 @@ impl CopyBlobResponse { &self.account_id } - pub fn copied(&self) -> Option> { + pub fn copied(&mut self, id: &str) -> crate::Result { + if let Some(result) = self.copied.as_mut().and_then(|r| r.remove(id)) { + Ok(result) + } else if let Some(error) = self.not_copied.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 copied_ids(&self) -> Option> { self.copied.as_ref().map(|map| map.keys()) } - pub fn copied_details(&self, id: &str) -> Option<&str> { - self.copied - .as_ref() - .and_then(|map| map.get(id).map(|s| s.as_str())) - } - - pub fn not_copied(&self) -> Option> { + pub fn not_copied_ids(&self) -> Option> { self.not_copied.as_ref().map(|map| map.keys()) } diff --git a/src/blob/helpers.rs b/src/blob/helpers.rs index 76a65bd..24a0b2c 100644 --- a/src/blob/helpers.rs +++ b/src/blob/helpers.rs @@ -1,10 +1,27 @@ use crate::{ + client::Client, core::request::{Arguments, Request}, Method, }; use super::copy::{CopyBlobRequest, CopyBlobResponse}; +impl Client { + pub async fn blob_copy( + &self, + from_account_id: impl Into, + blob_id: impl Into, + ) -> crate::Result { + let blob_id = blob_id.into(); + let mut request = self.build(); + request.copy_blob(from_account_id).blob_id(&blob_id); + request + .send_single::() + .await? + .copied(&blob_id) + } +} + impl Request<'_> { pub fn copy_blob(&mut self, from_account_id: impl Into) -> &mut CopyBlobRequest { self.add_method_call( diff --git a/src/core/request.rs b/src/core/request.rs index 37e478c..c54451e 100644 --- a/src/core/request.rs +++ b/src/core/request.rs @@ -5,7 +5,10 @@ use serde::{de::DeserializeOwned, Serialize}; use crate::{ blob::copy::CopyBlobRequest, client::Client, - email::{import::EmailImportRequest, parse::EmailParseRequest, Email}, + email::{ + import::EmailImportRequest, parse::EmailParseRequest, + search_snippet::SearchSnippetGetRequest, Email, + }, email_submission::EmailSubmission, identity::Identity, mailbox::Mailbox, @@ -71,6 +74,7 @@ pub enum Arguments { EmailCopy(CopyRequest>), EmailImport(EmailImportRequest), EmailParse(EmailParseRequest), + SearchSnippetGet(SearchSnippetGetRequest), IdentityGet(GetRequest>), IdentitySet(SetRequest>), EmailSubmissionGet(GetRequest>), @@ -150,6 +154,10 @@ impl Arguments { Arguments::EmailParse(EmailParseRequest::new(params)) } + pub fn search_snippet_get(params: RequestParams) -> Self { + Arguments::SearchSnippetGet(SearchSnippetGetRequest::new(params)) + } + pub fn identity_get(params: RequestParams) -> Self { Arguments::IdentityGet(GetRequest::new(params)) } @@ -313,6 +321,13 @@ impl Arguments { } } + pub fn search_snippet_get_mut(&mut self) -> &mut SearchSnippetGetRequest { + match self { + Arguments::SearchSnippetGet(ref mut r) => r, + _ => unreachable!(), + } + } + pub fn identity_get_mut(&mut self) -> &mut GetRequest> { match self { Arguments::IdentityGet(ref mut r) => r, diff --git a/src/core/response.rs b/src/core/response.rs index 683793b..fbcba70 100644 --- a/src/core/response.rs +++ b/src/core/response.rs @@ -4,7 +4,10 @@ use serde::{de::Visitor, Deserialize}; use crate::{ blob::copy::CopyBlobResponse, - email::{import::EmailImportResponse, parse::EmailParseResponse, Email}, + email::{ + import::EmailImportResponse, parse::EmailParseResponse, + search_snippet::SearchSnippetGetResponse, Email, + }, email_submission::EmailSubmission, identity::Identity, mailbox::Mailbox, @@ -110,7 +113,6 @@ pub type EmailGetResponse = GetResponse>; pub type EmailSetResponse = SetResponse>; pub type EmailCopyResponse = CopyResponse>; pub type EmailChangesResponse = ChangesResponse>; -pub type SearchSnippetGetResponse = GetResponse; pub type IdentitySetResponse = SetResponse>; pub type IdentityGetResponse = GetResponse>; pub type IdentityChangesResponse = ChangesResponse>; diff --git a/src/email/copy.rs b/src/email/copy.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/email/helpers.rs b/src/email/helpers.rs index 391959d..c148b60 100644 --- a/src/email/helpers.rs +++ b/src/email/helpers.rs @@ -16,6 +16,7 @@ use crate::{ use super::{ import::{EmailImportRequest, EmailImportResponse}, parse::{EmailParseRequest, EmailParseResponse}, + search_snippet::{SearchSnippetGetRequest, SearchSnippetGetResponse}, BodyProperty, Email, Property, }; @@ -219,6 +220,20 @@ impl Client { .await? .created(&id) } + + pub async fn search_snippet_get( + &self, + filter: Option>>, + email_ids: impl IntoIterator>, + ) -> crate::Result { + 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::().await + } } impl Request<'_> { @@ -326,4 +341,16 @@ impl Request<'_> { pub async fn send_parse_email(self) -> crate::Result { self.send_single().await } + + 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 async fn send_get_search_snippet(self) -> crate::Result { + self.send_single().await + } } diff --git a/src/email/search_snippet.rs b/src/email/search_snippet.rs index e69de29..0008f14 100644 --- a/src/email/search_snippet.rs +++ b/src/email/search_snippet.rs @@ -0,0 +1,112 @@ +use serde::{Deserialize, Serialize}; + +use crate::core::{query::Filter, request::ResultReference, RequestParams}; + +#[derive(Deserialize, Clone, Debug)] +pub struct SearchSnippet { + #[serde(rename = "emailId")] + email_id: String, + subject: Option, + preview: Option, +} + +#[derive(Debug, Clone, Serialize)] +pub struct SearchSnippetGetRequest { + #[serde(rename = "accountId")] + account_id: String, + + #[serde(rename = "filter")] + #[serde(skip_serializing_if = "Option::is_none")] + filter: Option>, + + #[serde(rename = "emailIds")] + #[serde(skip_serializing_if = "Option::is_none")] + email_ids: Option>, + + #[serde(rename = "#emailIds")] + #[serde(skip_serializing_if = "Option::is_none")] + email_ids_ref: Option, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct SearchSnippetGetResponse { + #[serde(rename = "accountId")] + account_id: String, + + #[serde(rename = "list")] + list: Vec, + + #[serde(rename = "notFound")] + not_found: Option>, +} + +impl SearchSnippetGetRequest { + pub fn new(params: RequestParams) -> Self { + SearchSnippetGetRequest { + account_id: params.account_id, + filter: None, + email_ids: None, + email_ids_ref: None, + } + } + + pub fn filter(&mut self, filter: impl Into>) -> &mut Self { + self.filter = Some(filter.into()); + self + } + + pub fn email_id(&mut self, email_id: impl Into) -> &mut Self { + self.email_ids + .get_or_insert_with(Vec::new) + .push(email_id.into()); + self + } + + pub fn email_ids( + &mut self, + email_ids: impl IntoIterator>, + ) -> &mut Self { + self.email_ids + .get_or_insert_with(Vec::new) + .extend(email_ids.into_iter().map(|id| id.into())); + self + } + + pub fn email_ids_ref(&mut self, reference: ResultReference) -> &mut Self { + self.email_ids_ref = reference.into(); + self.email_ids = None; + self + } +} + +impl SearchSnippet { + pub fn email_id(&self) -> &str { + &self.email_id + } + + pub fn subject(&self) -> Option<&str> { + self.subject.as_deref() + } + + pub fn preview(&self) -> Option<&str> { + self.preview.as_deref() + } +} + +impl SearchSnippetGetResponse { + pub fn account_id(&self) -> &str { + &self.account_id + } + + pub fn id(&self, id: &str) -> Option<&SearchSnippet> { + self.list.iter().find(|snippet| snippet.email_id == id) + } + + pub fn list(&self) -> &[SearchSnippet] { + &self.list + } + + pub fn not_found(&self) -> Option<&[String]> { + self.not_found.as_deref() + } +}