JMAP Sharing Principals
This commit is contained in:
71
src/principal/get.rs
Normal file
71
src/principal/get.rs
Normal 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
106
src/principal/helpers.rs
Normal 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
184
src/principal/mod.rs
Normal 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
119
src/principal/query.rs
Normal 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
125
src/principal/set.rs
Normal 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user