use chrono::{DateTime, NaiveDateTime, Utc}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Debug, Clone, Serialize)] pub struct SetRequest { #[serde(rename = "accountId")] account_id: String, #[serde(rename = "ifInState")] if_in_state: Option, create: Option>, update: Option>, destroy: Option>, #[serde(flatten)] arguments: A, } #[derive(Debug, Clone, Deserialize)] pub struct SetResponse { #[serde(rename = "accountId")] account_id: String, #[serde(rename = "oldState")] old_state: Option, #[serde(rename = "newState")] new_state: String, #[serde(rename = "created")] created: Option>, #[serde(rename = "updated")] updated: Option>>, #[serde(rename = "destroyed")] destroyed: Option>, #[serde(rename = "notCreated")] not_created: Option>>, #[serde(rename = "notUpdated")] not_updated: Option>>, #[serde(rename = "notDestroyed")] not_destroyed: Option>>, } #[derive(Debug, Clone, Deserialize)] pub struct SetError { #[serde(rename = "type")] type_: SetErrorType, description: Option, properties: Option>, } #[derive(Debug, Clone, Deserialize)] pub enum SetErrorType { #[serde(rename = "forbidden")] Forbidden, #[serde(rename = "overQuota")] OverQuota, #[serde(rename = "tooLarge")] TooLarge, #[serde(rename = "rateLimit")] RateLimit, #[serde(rename = "notFound")] NotFound, #[serde(rename = "invalidPatch")] InvalidPatch, #[serde(rename = "willDestroy")] WillDestroy, #[serde(rename = "invalidProperties")] InvalidProperties, #[serde(rename = "singleton")] Singleton, #[serde(rename = "mailboxHasChild")] MailboxHasChild, #[serde(rename = "mailboxHasEmail")] MailboxHasEmail, #[serde(rename = "blobNotFound")] BlobNotFound, #[serde(rename = "tooManyKeywords")] TooManyKeywords, #[serde(rename = "tooManyMailboxes")] TooManyMailboxes, #[serde(rename = "forbiddenFrom")] ForbiddenFrom, #[serde(rename = "invalidEmail")] InvalidEmail, #[serde(rename = "tooManyRecipients")] TooManyRecipients, #[serde(rename = "noRecipients")] NoRecipients, #[serde(rename = "invalidRecipients")] InvalidRecipients, #[serde(rename = "forbiddenMailFrom")] ForbiddenMailFrom, #[serde(rename = "forbiddenToSend")] ForbiddenToSend, #[serde(rename = "cannotUnsend")] CannotUnsend, } pub fn from_timestamp(timestamp: i64) -> DateTime { DateTime::::from_utc(NaiveDateTime::from_timestamp(timestamp, 0), Utc) } pub fn string_not_set(string: &Option) -> bool { matches!(string, Some(string) if string.is_empty()) } pub fn date_not_set(date: &Option>) -> bool { matches!(date, Some(date) if date.timestamp() == 0) } pub fn list_not_set(list: &Option>) -> bool { matches!(list, Some(list) if list.is_empty() ) } impl SetRequest { pub fn new(account_id: String) -> Self { Self { account_id, if_in_state: None, create: None, update: None, destroy: None, arguments: Default::default(), } } pub fn account_id(&mut self, account_id: impl Into) -> &mut Self { self.account_id = account_id.into(); self } pub fn if_in_state(&mut self, if_in_state: impl Into) -> &mut Self { self.if_in_state = Some(if_in_state.into()); self } pub fn create(&mut self, id: impl Into, value: T) -> &mut Self { self.create .get_or_insert_with(HashMap::new) .insert(id.into(), value); self } pub fn update(&mut self, id: impl Into, value: T) -> &mut Self { self.update .get_or_insert_with(HashMap::new) .insert(id.into(), value); self } pub fn destroy(&mut self, id: impl Into) -> &mut Self { self.destroy.get_or_insert_with(Vec::new).push(id.into()); self } pub fn arguments(&mut self) -> &mut A { &mut self.arguments } } impl SetResponse { pub fn account_id(&self) -> &str { &self.account_id } pub fn old_state(&self) -> Option<&str> { self.old_state.as_deref() } pub fn new_state(&self) -> &str { &self.new_state } pub fn created(&self) -> Option> { self.created.as_ref().map(|map| map.keys()) } pub fn updated(&self) -> Option> { self.updated.as_ref().map(|map| map.keys()) } pub fn destroyed(&self) -> Option<&[String]> { self.destroyed.as_deref() } pub fn not_created(&self) -> Option> { self.not_created.as_ref().map(|map| map.keys()) } pub fn not_updated(&self) -> Option> { self.not_updated.as_ref().map(|map| map.keys()) } pub fn not_destroyed(&self) -> Option> { self.not_destroyed.as_ref().map(|map| map.keys()) } pub fn not_created_reason(&self, id: &str) -> Option<&SetError> { self.not_created.as_ref().and_then(|map| map.get(id)) } pub fn not_updated_reason(&self, id: &str) -> Option<&SetError> { self.not_updated.as_ref().and_then(|map| map.get(id)) } pub fn not_destroyed_reason(&self, id: &str) -> Option<&SetError> { self.not_destroyed.as_ref().and_then(|map| map.get(id)) } 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() } } impl SetError { pub fn error(&self) -> &SetErrorType { &self.type_ } pub fn description(&self) -> Option<&str> { self.description.as_deref() } pub fn properties(&self) -> Option<&[U]> { self.properties.as_deref() } }