JMAP Sharing Principals

main
Mauro D 2022-06-13 15:24:32 +00:00
parent 867a19d211
commit 66b70ee79e
9 changed files with 760 additions and 3 deletions

View File

@ -9,6 +9,7 @@ use crate::{
email_submission::EmailSubmission, email_submission::EmailSubmission,
identity::Identity, identity::Identity,
mailbox::Mailbox, mailbox::Mailbox,
principal::Principal,
push_subscription::PushSubscription, push_subscription::PushSubscription,
thread::Thread, thread::Thread,
vacation_response::VacationResponse, vacation_response::VacationResponse,
@ -78,6 +79,10 @@ pub enum Arguments {
EmailSubmissionSet(SetRequest<EmailSubmission<Set>>), EmailSubmissionSet(SetRequest<EmailSubmission<Set>>),
VacationResponseGet(GetRequest<VacationResponse<Set>>), VacationResponseGet(GetRequest<VacationResponse<Set>>),
VacationResponseSet(SetRequest<VacationResponse<Set>>), VacationResponseSet(SetRequest<VacationResponse<Set>>),
PrincipalGet(GetRequest<Principal<Set>>),
PrincipalQuery(QueryRequest<Principal<Set>>),
PrincipalQueryChanges(QueryChangesRequest<Principal<Set>>),
PrincipalSet(SetRequest<Principal<Set>>),
} }
impl Arguments { impl Arguments {
@ -180,6 +185,22 @@ impl Arguments {
Arguments::VacationResponseSet(SetRequest::new(params)) Arguments::VacationResponseSet(SetRequest::new(params))
} }
pub fn principal_get(params: RequestParams) -> Self {
Arguments::PrincipalGet(GetRequest::new(params))
}
pub fn principal_query(params: RequestParams) -> Self {
Arguments::PrincipalQuery(QueryRequest::new(params))
}
pub fn principal_query_changes(params: RequestParams, since_query_state: String) -> Self {
Arguments::PrincipalQueryChanges(QueryChangesRequest::new(params, since_query_state))
}
pub fn principal_set(params: RequestParams) -> Self {
Arguments::PrincipalSet(SetRequest::new(params))
}
pub fn changes_mut(&mut self) -> &mut ChangesRequest { pub fn changes_mut(&mut self) -> &mut ChangesRequest {
match self { match self {
Arguments::Changes(ref mut r) => r, Arguments::Changes(ref mut r) => r,
@ -349,6 +370,34 @@ impl Arguments {
_ => unreachable!(), _ => unreachable!(),
} }
} }
pub fn principal_get_mut(&mut self) -> &mut GetRequest<Principal<Set>> {
match self {
Arguments::PrincipalGet(ref mut r) => r,
_ => unreachable!(),
}
}
pub fn principal_query_mut(&mut self) -> &mut QueryRequest<Principal<Set>> {
match self {
Arguments::PrincipalQuery(ref mut r) => r,
_ => unreachable!(),
}
}
pub fn principal_query_changes_mut(&mut self) -> &mut QueryChangesRequest<Principal<Set>> {
match self {
Arguments::PrincipalQueryChanges(ref mut r) => r,
_ => unreachable!(),
}
}
pub fn principal_set_mut(&mut self) -> &mut SetRequest<Principal<Set>> {
match self {
Arguments::PrincipalSet(ref mut r) => r,
_ => unreachable!(),
}
}
} }
impl<'x> Request<'x> { impl<'x> Request<'x> {

View File

@ -8,6 +8,7 @@ use crate::{
email_submission::EmailSubmission, email_submission::EmailSubmission,
identity::Identity, identity::Identity,
mailbox::Mailbox, mailbox::Mailbox,
principal::Principal,
push_subscription::PushSubscription, push_subscription::PushSubscription,
thread::Thread, thread::Thread,
vacation_response::VacationResponse, vacation_response::VacationResponse,
@ -100,7 +101,7 @@ pub enum Error {
pub type PushSubscriptionSetResponse = SetResponse<PushSubscription<Get>>; pub type PushSubscriptionSetResponse = SetResponse<PushSubscription<Get>>;
pub type PushSubscriptionGetResponse = GetResponse<PushSubscription<Get>>; pub type PushSubscriptionGetResponse = GetResponse<PushSubscription<Get>>;
pub type MaiboxChangesResponse = ChangesResponse<Mailbox<Get>>; pub type MailboxChangesResponse = ChangesResponse<Mailbox<Get>>;
pub type MailboxSetResponse = SetResponse<Mailbox<Get>>; pub type MailboxSetResponse = SetResponse<Mailbox<Get>>;
pub type MailboxGetResponse = GetResponse<Mailbox<Get>>; pub type MailboxGetResponse = GetResponse<Mailbox<Get>>;
pub type ThreadGetResponse = GetResponse<Thread>; pub type ThreadGetResponse = GetResponse<Thread>;
@ -118,6 +119,9 @@ pub type EmailSubmissionGetResponse = GetResponse<EmailSubmission<Get>>;
pub type EmailSubmissionChangesResponse = ChangesResponse<EmailSubmission<Get>>; pub type EmailSubmissionChangesResponse = ChangesResponse<EmailSubmission<Get>>;
pub type VacationResponseGetResponse = GetResponse<VacationResponse<Get>>; pub type VacationResponseGetResponse = GetResponse<VacationResponse<Get>>;
pub type VacationResponseSetResponse = SetResponse<VacationResponse<Get>>; pub type VacationResponseSetResponse = SetResponse<VacationResponse<Get>>;
pub type PrincipalChangesResponse = ChangesResponse<Principal<Get>>;
pub type PrincipalSetResponse = SetResponse<Principal<Get>>;
pub type PrincipalGetResponse = GetResponse<Principal<Get>>;
#[derive(Debug)] #[derive(Debug)]
pub struct TaggedMethodResponse { pub struct TaggedMethodResponse {
@ -131,7 +135,7 @@ pub enum MethodResponse {
GetPushSubscription(PushSubscriptionGetResponse), GetPushSubscription(PushSubscriptionGetResponse),
SetPushSubscription(PushSubscriptionSetResponse), SetPushSubscription(PushSubscriptionSetResponse),
GetMailbox(MailboxGetResponse), GetMailbox(MailboxGetResponse),
ChangesMailbox(MaiboxChangesResponse), ChangesMailbox(MailboxChangesResponse),
QueryMailbox(QueryResponse), QueryMailbox(QueryResponse),
QueryChangesMailbox(QueryChangesResponse), QueryChangesMailbox(QueryChangesResponse),
SetMailbox(MailboxSetResponse), SetMailbox(MailboxSetResponse),
@ -156,6 +160,13 @@ pub enum MethodResponse {
SetEmailSubmission(EmailSubmissionSetResponse), SetEmailSubmission(EmailSubmissionSetResponse),
GetVacationResponse(VacationResponseGetResponse), GetVacationResponse(VacationResponseGetResponse),
SetVacationResponse(VacationResponseSetResponse), SetVacationResponse(VacationResponseSetResponse),
GetPrincipal(PrincipalGetResponse),
ChangesPrincipal(PrincipalChangesResponse),
QueryPrincipal(QueryResponse),
QueryChangesPrincipal(QueryChangesResponse),
SetPrincipal(PrincipalSetResponse),
Echo(serde_json::Value), Echo(serde_json::Value),
Error(MethodError), Error(MethodError),
} }
@ -233,6 +244,17 @@ impl TaggedMethodResponse {
MethodResponse::SetVacationResponse(_), MethodResponse::SetVacationResponse(_),
Method::SetVacationResponse Method::SetVacationResponse
) )
| (MethodResponse::GetPrincipal(_), Method::GetPrincipal)
| (
MethodResponse::ChangesPrincipal(_),
Method::ChangesPrincipal
)
| (MethodResponse::QueryPrincipal(_), Method::QueryPrincipal)
| (
MethodResponse::QueryChangesPrincipal(_),
Method::QueryChangesPrincipal
)
| (MethodResponse::SetPrincipal(_), Method::SetPrincipal)
| (MethodResponse::Echo(_), Method::Echo) | (MethodResponse::Echo(_), Method::Echo)
| (MethodResponse::Error(_), Method::Error) | (MethodResponse::Error(_), Method::Error)
) )
@ -270,7 +292,7 @@ impl TaggedMethodResponse {
} }
} }
pub fn unwrap_changes_mailbox(self) -> crate::Result<MaiboxChangesResponse> { pub fn unwrap_changes_mailbox(self) -> crate::Result<MailboxChangesResponse> {
match self.response { match self.response {
MethodResponse::ChangesMailbox(response) => Ok(response), MethodResponse::ChangesMailbox(response) => Ok(response),
MethodResponse::Error(err) => Err(err.into()), MethodResponse::Error(err) => Err(err.into()),
@ -470,6 +492,46 @@ impl TaggedMethodResponse {
} }
} }
pub fn unwrap_get_principal(self) -> crate::Result<PrincipalGetResponse> {
match self.response {
MethodResponse::GetPrincipal(response) => Ok(response),
MethodResponse::Error(err) => Err(err.into()),
_ => Err("Response type mismatch".into()),
}
}
pub fn unwrap_changes_principal(self) -> crate::Result<PrincipalChangesResponse> {
match self.response {
MethodResponse::ChangesPrincipal(response) => Ok(response),
MethodResponse::Error(err) => Err(err.into()),
_ => Err("Response type mismatch".into()),
}
}
pub fn unwrap_query_principal(self) -> crate::Result<QueryResponse> {
match self.response {
MethodResponse::QueryPrincipal(response) => Ok(response),
MethodResponse::Error(err) => Err(err.into()),
_ => Err("Response type mismatch".into()),
}
}
pub fn unwrap_query_changes_principal(self) -> crate::Result<QueryChangesResponse> {
match self.response {
MethodResponse::QueryChangesPrincipal(response) => Ok(response),
MethodResponse::Error(err) => Err(err.into()),
_ => Err("Response type mismatch".into()),
}
}
pub fn unwrap_set_principal(self) -> crate::Result<PrincipalSetResponse> {
match self.response {
MethodResponse::SetPrincipal(response) => Ok(response),
MethodResponse::Error(err) => Err(err.into()),
_ => Err("Response type mismatch".into()),
}
}
pub fn unwrap_echo(self) -> crate::Result<serde_json::Value> { pub fn unwrap_echo(self) -> crate::Result<serde_json::Value> {
match self.response { match self.response {
MethodResponse::Echo(response) => Ok(response), MethodResponse::Echo(response) => Ok(response),
@ -629,6 +691,26 @@ impl<'de> Visitor<'de> for TaggedMethodResponseVisitor {
seq.next_element()? seq.next_element()?
.ok_or_else(|| serde::de::Error::custom("Expected a method response"))?, .ok_or_else(|| serde::de::Error::custom("Expected a method response"))?,
), ),
Method::GetPrincipal => MethodResponse::GetPrincipal(
seq.next_element()?
.ok_or_else(|| serde::de::Error::custom("Expected a method response"))?,
),
Method::ChangesPrincipal => MethodResponse::ChangesPrincipal(
seq.next_element()?
.ok_or_else(|| serde::de::Error::custom("Expected a method response"))?,
),
Method::QueryPrincipal => MethodResponse::QueryPrincipal(
seq.next_element()?
.ok_or_else(|| serde::de::Error::custom("Expected a method response"))?,
),
Method::QueryChangesPrincipal => MethodResponse::QueryChangesPrincipal(
seq.next_element()?
.ok_or_else(|| serde::de::Error::custom("Expected a method response"))?,
),
Method::SetPrincipal => MethodResponse::SetPrincipal(
seq.next_element()?
.ok_or_else(|| serde::de::Error::custom("Expected a method response"))?,
),
Method::Error => MethodResponse::Error( Method::Error => MethodResponse::Error(
seq.next_element()? seq.next_element()?
.ok_or_else(|| serde::de::Error::custom("Expected a method response"))?, .ok_or_else(|| serde::de::Error::custom("Expected a method response"))?,

View File

@ -383,3 +383,7 @@ pub fn date_not_set(date: &Option<DateTime<Utc>>) -> bool {
pub fn list_not_set<O>(list: &Option<Vec<O>>) -> bool { pub fn list_not_set<O>(list: &Option<Vec<O>>) -> bool {
matches!(list, Some(list) if list.is_empty() ) matches!(list, Some(list) if list.is_empty() )
} }
pub fn map_not_set<K, V>(list: &Option<HashMap<K, V>>) -> bool {
matches!(list, Some(list) if list.is_empty() )
}

View File

@ -13,6 +13,7 @@ pub mod email_submission;
pub mod event_source; pub mod event_source;
pub mod identity; pub mod identity;
pub mod mailbox; pub mod mailbox;
pub mod principal;
pub mod push_subscription; pub mod push_subscription;
pub mod thread; pub mod thread;
pub mod vacation_response; pub mod vacation_response;
@ -36,6 +37,10 @@ pub enum URI {
Calendars, Calendars,
#[serde(rename = "urn:ietf:params:jmap:websocket")] #[serde(rename = "urn:ietf:params:jmap:websocket")]
WebSocket, WebSocket,
#[serde(rename = "urn:ietf:params:jmap:principals")]
Principals,
#[serde(rename = "urn:ietf:params:jmap:principals:owner")]
PrincipalsOwner,
} }
impl AsRef<str> for URI { impl AsRef<str> for URI {
@ -48,6 +53,8 @@ impl AsRef<str> for URI {
URI::Contacts => "urn:ietf:params:jmap:contacts", URI::Contacts => "urn:ietf:params:jmap:contacts",
URI::Calendars => "urn:ietf:params:jmap:calendars", URI::Calendars => "urn:ietf:params:jmap:calendars",
URI::WebSocket => "urn:ietf:params:jmap:websocket", URI::WebSocket => "urn:ietf:params:jmap:websocket",
URI::Principals => "urn:ietf:params:jmap:principals",
URI::PrincipalsOwner => "urn:ietf:params:jmap:principals:owner",
} }
} }
} }
@ -114,6 +121,16 @@ pub enum Method {
GetVacationResponse, GetVacationResponse,
#[serde(rename = "VacationResponse/set")] #[serde(rename = "VacationResponse/set")]
SetVacationResponse, SetVacationResponse,
#[serde(rename = "Principal/get")]
GetPrincipal,
#[serde(rename = "Principal/changes")]
ChangesPrincipal,
#[serde(rename = "Principal/query")]
QueryPrincipal,
#[serde(rename = "Principal/queryChanges")]
QueryChangesPrincipal,
#[serde(rename = "Principal/set")]
SetPrincipal,
#[serde(rename = "error")] #[serde(rename = "error")]
Error, Error,
} }

71
src/principal/get.rs Normal file
View File

@ -0,0 +1,71 @@
use std::collections::HashMap;
use crate::{core::get::GetObject, Get, Set};
use super::{Principal, Type, ACL, DKIM};
impl Principal<Get> {
pub fn id(&self) -> &str {
self.id.as_ref().unwrap()
}
pub fn unwrap_id(self) -> String {
self.id.unwrap()
}
pub fn ptype(&self) -> Option<&Type> {
self.ptype.as_ref()
}
pub fn name(&self) -> Option<&str> {
self.name.as_deref()
}
pub fn email(&self) -> Option<&str> {
self.email.as_deref()
}
pub fn description(&self) -> Option<&str> {
self.description.as_deref()
}
pub fn secret(&self) -> Option<&str> {
self.secret.as_deref()
}
pub fn picture(&self) -> Option<&str> {
self.picture.as_deref()
}
pub fn quota(&self) -> Option<u32> {
self.quota
}
pub fn capabilities(&self) -> Option<&[String]> {
self.capabilities.as_deref()
}
pub fn aliases(&self) -> Option<&[String]> {
self.aliases.as_deref()
}
pub fn members(&self) -> Option<&[String]> {
self.members.as_deref()
}
pub fn dkim(&self) -> Option<&DKIM> {
self.dkim.as_ref()
}
pub fn acl(&self) -> Option<&HashMap<String, Vec<ACL>>> {
self.acl.as_ref()
}
}
impl GetObject for Principal<Set> {
type GetArguments = ();
}
impl GetObject for Principal<Get> {
type GetArguments = ();
}

106
src/principal/helpers.rs Normal file
View File

@ -0,0 +1,106 @@
use crate::{
client::Client,
core::{
changes::{ChangesRequest, ChangesResponse},
get::GetRequest,
query::{QueryRequest, QueryResponse},
query_changes::{QueryChangesRequest, QueryChangesResponse},
request::{Arguments, Request},
response::{PrincipalGetResponse, PrincipalSetResponse},
set::SetRequest,
},
Get, Method, Set,
};
use super::Principal;
impl Client {
pub async fn individual_create(
&mut self,
name: impl Into<String>,
parent_id: Option<impl Into<String>>,
) -> crate::Result<Principal> {
/*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)*/
todo!()
}
}
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 async fn send_get_principal(self) -> crate::Result<PrincipalGetResponse> {
self.send_single().await
}
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 async fn send_changes_principal(self) -> crate::Result<ChangesResponse<Principal<Get>>> {
self.send_single().await
}
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 async fn send_query_principal(self) -> crate::Result<QueryResponse> {
self.send_single().await
}
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 async fn send_query_principal_changes(self) -> crate::Result<QueryChangesResponse> {
self.send_single().await
}
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 async fn send_set_principal(self) -> crate::Result<PrincipalSetResponse> {
self.send_single().await
}
}

184
src/principal/mod.rs Normal file
View File

@ -0,0 +1,184 @@
pub mod get;
pub mod helpers;
pub mod query;
pub mod set;
use crate::core::set::{list_not_set, map_not_set, string_not_set};
use std::{collections::HashMap, fmt::Display};
use serde::{Deserialize, Serialize};
use crate::{
core::{changes::ChangesObject, Object},
Get, Set,
};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Principal<State = Get> {
#[serde(skip)]
_create_id: Option<usize>,
#[serde(skip)]
_state: std::marker::PhantomData<State>,
#[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<HashMap<String, Vec<ACL>>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Copy)]
pub enum Property {
#[serde(rename = "id")]
Id = 0,
#[serde(rename = "type")]
Type = 1,
#[serde(rename = "name")]
Name = 2,
#[serde(rename = "description")]
Description = 3,
#[serde(rename = "email")]
Email = 4,
#[serde(rename = "timezone")]
Timezone = 5,
#[serde(rename = "capabilities")]
Capabilities = 6,
#[serde(rename = "aliases")]
Aliases = 7,
#[serde(rename = "secret")]
Secret = 8,
#[serde(rename = "dkim")]
DKIM = 9,
#[serde(rename = "quota")]
Quota = 10,
#[serde(rename = "picture")]
Picture = 11,
#[serde(rename = "members")]
Members = 12,
#[serde(rename = "acl")]
ACL = 13,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Copy)]
pub enum ACL {
#[serde(rename = "read")]
Read = 0,
#[serde(rename = "modify")]
Modify = 1,
#[serde(rename = "delete")]
Delete = 2,
#[serde(rename = "readItems")]
ReadItems = 3,
#[serde(rename = "addItems")]
AddItems = 4,
#[serde(rename = "modifyItems")]
ModifyItems = 5,
#[serde(rename = "removeItems")]
RemoveItems = 6,
#[serde(rename = "createChild")]
CreateChild = 7,
#[serde(rename = "administer")]
Administer = 8,
#[serde(rename = "setSeen")]
SetSeen = 9,
#[serde(rename = "setKeywords")]
SetKeywords = 10,
#[serde(rename = "submit")]
Submit = 11,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Type {
#[serde(rename = "individual")]
Individual,
#[serde(rename = "group")]
Group,
#[serde(rename = "resource")]
Resource,
#[serde(rename = "location")]
Location,
#[serde(rename = "domain")]
Domain,
#[serde(rename = "list")]
List,
#[serde(rename = "other")]
Other,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DKIM {
#[serde(rename = "dkimSelector")]
pub dkim_selector: Option<String>,
#[serde(rename = "dkimExpiration")]
pub dkim_expiration: Option<i64>,
}
impl Display for Property {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Property::Id => write!(f, "id"),
Property::Type => write!(f, "type"),
Property::Name => write!(f, "name"),
Property::Description => write!(f, "description"),
Property::Email => write!(f, "email"),
Property::Timezone => write!(f, "timezone"),
Property::Capabilities => write!(f, "capabilities"),
Property::Aliases => write!(f, "aliases"),
Property::Secret => write!(f, "secret"),
Property::DKIM => write!(f, "dkim"),
Property::Quota => write!(f, "quota"),
Property::Picture => write!(f, "picture"),
Property::Members => write!(f, "members"),
Property::ACL => write!(f, "acl"),
}
}
}
impl Object for Principal<Set> {
type Property = Property;
fn requires_account_id() -> bool {
true
}
}
impl Object for Principal<Get> {
type Property = Property;
fn requires_account_id() -> bool {
true
}
}
impl ChangesObject for Principal<Set> {
type ChangesResponse = ();
}
impl ChangesObject for Principal<Get> {
type ChangesResponse = ();
}

119
src/principal/query.rs Normal file
View File

@ -0,0 +1,119 @@
use serde::Serialize;
use crate::{
core::query::{self, QueryObject},
Set,
};
use super::{Principal, Type};
#[derive(Serialize, Clone, Debug)]
#[serde(untagged)]
pub enum Filter {
Email {
#[serde(rename = "email")]
value: String,
},
Name {
#[serde(rename = "name")]
value: String,
},
Text {
#[serde(rename = "text")]
value: String,
},
Type {
#[serde(rename = "type")]
value: Type,
},
Timezone {
#[serde(rename = "timezone")]
value: String,
},
Members {
#[serde(rename = "members")]
value: String,
},
QuotaLt {
#[serde(rename = "quotaLowerThan")]
value: u32,
},
QuotaGt {
#[serde(rename = "quotaGreaterThan")]
value: u32,
},
}
#[derive(Serialize, Debug, Clone)]
#[serde(tag = "property")]
pub enum Comparator {
#[serde(rename = "type")]
Type,
#[serde(rename = "name")]
Name,
#[serde(rename = "email")]
Email,
}
impl Filter {
pub fn name(value: impl Into<String>) -> Self {
Filter::Name {
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(),
}
}
pub fn members(value: impl Into<String>) -> Self {
Filter::Members {
value: value.into(),
}
}
pub fn ptype(value: Type) -> Self {
Filter::Type { value }
}
pub fn quota_lower_than(value: u32) -> Self {
Filter::QuotaLt { value }
}
pub fn quota_greater_than(value: u32) -> Self {
Filter::QuotaGt { value }
}
}
impl Comparator {
pub fn name() -> query::Comparator<Comparator> {
query::Comparator::new(Comparator::Name)
}
pub fn email() -> query::Comparator<Comparator> {
query::Comparator::new(Comparator::Email)
}
pub fn ptype() -> query::Comparator<Comparator> {
query::Comparator::new(Comparator::Type)
}
}
impl QueryObject for Principal<Set> {
type QueryArguments = ();
type Filter = Filter;
type Sort = Comparator;
}

125
src/principal/set.rs Normal file
View File

@ -0,0 +1,125 @@
use std::collections::HashMap;
use crate::{core::set::SetObject, Get, Set};
use super::{Principal, Type, ACL, DKIM};
impl Principal<Set> {
pub fn name(&mut self, name: Option<impl Into<String>>) -> &mut Self {
self.name = name.map(|s| s.into());
self
}
pub fn description(&mut self, description: Option<impl Into<String>>) -> &mut Self {
self.description = description.map(|s| s.into());
self
}
pub fn email(&mut self, email: Option<impl Into<String>>) -> &mut Self {
self.email = email.map(|s| s.into());
self
}
pub fn secret(&mut self, secret: Option<impl Into<String>>) -> &mut Self {
self.secret = secret.map(|s| s.into());
self
}
pub fn timezone(&mut self, timezone: Option<impl Into<String>>) -> &mut Self {
self.timezone = timezone.map(|s| s.into());
self
}
pub fn picture(&mut self, picture: Option<impl Into<String>>) -> &mut Self {
self.picture = picture.map(|s| s.into());
self
}
pub fn quota(&mut self, quota: Option<u32>) -> &mut Self {
self.quota = quota;
self
}
pub fn ptype(&mut self, ptype: Type) -> &mut Self {
self.ptype = ptype.into();
self
}
pub fn dkim(&mut self, dkim: DKIM) -> &mut Self {
self.dkim = dkim.into();
self
}
pub fn acl(&mut self, acl: Option<HashMap<String, Vec<ACL>>>) -> &mut Self {
self.acl = acl;
self
}
pub fn aliases<T, U>(&mut self, aliases: Option<T>) -> &mut Self
where
T: IntoIterator<Item = U>,
U: Into<String>,
{
self.aliases = aliases.map(|l| l.into_iter().map(|v| v.into()).collect());
self
}
pub fn capabilities<T, U>(&mut self, capabilities: Option<T>) -> &mut Self
where
T: IntoIterator<Item = U>,
U: Into<String>,
{
self.capabilities = capabilities.map(|l| l.into_iter().map(|v| v.into()).collect());
self
}
pub fn members<T, U>(&mut self, members: Option<T>) -> &mut Self
where
T: IntoIterator<Item = U>,
U: Into<String>,
{
self.members = members.map(|l| l.into_iter().map(|v| v.into()).collect());
self
}
}
impl SetObject for Principal<Set> {
type SetArguments = ();
fn new(_create_id: Option<usize>) -> Self {
Principal {
_create_id,
_state: Default::default(),
id: None,
ptype: None,
name: "".to_string().into(),
description: "".to_string().into(),
email: "".to_string().into(),
timezone: "".to_string().into(),
capabilities: Vec::with_capacity(0).into(),
aliases: Vec::with_capacity(0).into(),
secret: "".to_string().into(),
dkim: None,
quota: None,
picture: "".to_string().into(),
members: Vec::with_capacity(0).into(),
acl: HashMap::with_capacity(0).into(),
}
}
fn create_id(&self) -> Option<String> {
self._create_id.map(|id| format!("c{}", id))
}
}
impl SetObject for Principal<Get> {
type SetArguments = ();
fn new(_create_id: Option<usize>) -> Self {
unimplemented!()
}
fn create_id(&self) -> Option<String> {
None
}
}