Fixes and use of rustls.
parent
2549d96703
commit
53abec1222
|
@ -15,7 +15,7 @@ readme = "README.md"
|
||||||
serde = { version = "1.0", features = ["derive"]}
|
serde = { version = "1.0", features = ["derive"]}
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
chrono = { version = "0.4", features = ["serde"]}
|
chrono = { version = "0.4", features = ["serde"]}
|
||||||
reqwest = { version = "0.11", features = ["stream"]}
|
reqwest = { version = "0.11", default-features = false, features = ["stream", "rustls-tls"]}
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
async-stream = "0.3.3"
|
async-stream = "0.3.3"
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
|
|
|
@ -4,15 +4,16 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::Method;
|
use crate::Method;
|
||||||
|
|
||||||
use super::{request::ResultReference, RequestParams};
|
use super::{request::ResultReference, RequestParams, Type};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct GetRequest<T: Display, A: Default> {
|
pub struct GetRequest<T: Display + Type, A: Default> {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
method: (Method, usize),
|
method: (Method, usize),
|
||||||
|
|
||||||
#[serde(rename = "accountId")]
|
#[serde(rename = "accountId")]
|
||||||
account_id: String,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
account_id: Option<String>,
|
||||||
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
ids: Option<Vec<String>>,
|
ids: Option<Vec<String>>,
|
||||||
|
@ -32,7 +33,7 @@ pub struct GetRequest<T: Display, A: Default> {
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct GetResponse<T> {
|
pub struct GetResponse<T> {
|
||||||
#[serde(rename = "accountId")]
|
#[serde(rename = "accountId")]
|
||||||
account_id: String,
|
account_id: Option<String>,
|
||||||
|
|
||||||
state: String,
|
state: String,
|
||||||
|
|
||||||
|
@ -42,10 +43,14 @@ pub struct GetResponse<T> {
|
||||||
not_found: Vec<String>,
|
not_found: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Display, A: Default> GetRequest<T, A> {
|
impl<T: Display + Type, A: Default> GetRequest<T, A> {
|
||||||
pub fn new(params: RequestParams) -> Self {
|
pub fn new(params: RequestParams) -> Self {
|
||||||
GetRequest {
|
GetRequest {
|
||||||
account_id: params.account_id,
|
account_id: if T::requires_account_id() {
|
||||||
|
params.account_id.into()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
method: (params.method, params.call_id),
|
method: (params.method, params.call_id),
|
||||||
ids: None,
|
ids: None,
|
||||||
ids_ref: None,
|
ids_ref: None,
|
||||||
|
@ -55,7 +60,9 @@ impl<T: Display, A: Default> GetRequest<T, A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn account_id(&mut self, account_id: impl Into<String>) -> &mut Self {
|
pub fn account_id(&mut self, account_id: impl Into<String>) -> &mut Self {
|
||||||
self.account_id = account_id.into();
|
if T::requires_account_id() {
|
||||||
|
self.account_id = Some(account_id.into());
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +102,7 @@ impl<T: Display, A: Default> GetRequest<T, A> {
|
||||||
|
|
||||||
impl<T> GetResponse<T> {
|
impl<T> GetResponse<T> {
|
||||||
pub fn account_id(&self) -> &str {
|
pub fn account_id(&self) -> &str {
|
||||||
&self.account_id
|
self.account_id.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn state(&self) -> &str {
|
pub fn state(&self) -> &str {
|
||||||
|
|
|
@ -26,3 +26,7 @@ impl RequestParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Type {
|
||||||
|
fn requires_account_id() -> bool;
|
||||||
|
}
|
||||||
|
|
|
@ -7,12 +7,13 @@ use std::{
|
||||||
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
use super::{request::ResultReference, RequestParams};
|
use super::{request::ResultReference, RequestParams, Type};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct SetRequest<T: Create, A: Default> {
|
pub struct SetRequest<T: Create + Type, A: Default> {
|
||||||
#[serde(rename = "accountId")]
|
#[serde(rename = "accountId")]
|
||||||
account_id: String,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
account_id: Option<String>,
|
||||||
|
|
||||||
#[serde(rename = "ifInState")]
|
#[serde(rename = "ifInState")]
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
@ -39,13 +40,13 @@ pub struct SetRequest<T: Create, A: Default> {
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct SetResponse<T, U: Display> {
|
pub struct SetResponse<T, U: Display> {
|
||||||
#[serde(rename = "accountId")]
|
#[serde(rename = "accountId")]
|
||||||
account_id: String,
|
account_id: Option<String>,
|
||||||
|
|
||||||
#[serde(rename = "oldState")]
|
#[serde(rename = "oldState")]
|
||||||
old_state: Option<String>,
|
old_state: Option<String>,
|
||||||
|
|
||||||
#[serde(rename = "newState")]
|
#[serde(rename = "newState")]
|
||||||
new_state: String,
|
new_state: Option<String>,
|
||||||
|
|
||||||
#[serde(rename = "created")]
|
#[serde(rename = "created")]
|
||||||
created: Option<HashMap<String, T>>,
|
created: Option<HashMap<String, T>>,
|
||||||
|
@ -130,10 +131,14 @@ pub trait Create: Sized {
|
||||||
fn create_id(&self) -> Option<String>;
|
fn create_id(&self) -> Option<String>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Create, A: Default> SetRequest<T, A> {
|
impl<T: Create + Type, A: Default> SetRequest<T, A> {
|
||||||
pub fn new(params: RequestParams) -> Self {
|
pub fn new(params: RequestParams) -> Self {
|
||||||
Self {
|
Self {
|
||||||
account_id: params.account_id,
|
account_id: if T::requires_account_id() {
|
||||||
|
params.account_id.into()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
if_in_state: None,
|
if_in_state: None,
|
||||||
create: None,
|
create: None,
|
||||||
update: None,
|
update: None,
|
||||||
|
@ -144,7 +149,9 @@ impl<T: Create, A: Default> SetRequest<T, A> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn account_id(&mut self, account_id: impl Into<String>) -> &mut Self {
|
pub fn account_id(&mut self, account_id: impl Into<String>) -> &mut Self {
|
||||||
self.account_id = account_id.into();
|
if T::requires_account_id() {
|
||||||
|
self.account_id = Some(account_id.into());
|
||||||
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +221,7 @@ impl<T: Create, A: Default> SetRequest<T, A> {
|
||||||
|
|
||||||
impl<T, U: Display> SetResponse<T, U> {
|
impl<T, U: Display> SetResponse<T, U> {
|
||||||
pub fn account_id(&self) -> &str {
|
pub fn account_id(&self) -> &str {
|
||||||
&self.account_id
|
self.account_id.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn old_state(&self) -> Option<&str> {
|
pub fn old_state(&self) -> Option<&str> {
|
||||||
|
@ -222,7 +229,7 @@ impl<T, U: Display> SetResponse<T, U> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_state(&self) -> &str {
|
pub fn new_state(&self) -> &str {
|
||||||
&self.new_state
|
self.new_state.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn created(&mut self, id: &str) -> crate::Result<T> {
|
pub fn created(&mut self, id: &str) -> crate::Result<T> {
|
||||||
|
|
|
@ -13,7 +13,10 @@ use std::{
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{core::request::ResultReference, Get};
|
use crate::{
|
||||||
|
core::{request::ResultReference, Type},
|
||||||
|
Get, Set,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
pub struct Email<State = Get> {
|
pub struct Email<State = Get> {
|
||||||
|
@ -813,6 +816,18 @@ impl SubmissionCapabilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Type for Email<Set> {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Type for Property {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::{collections::HashMap, fmt::Display};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{email::Email, Get};
|
use crate::{core::Type, email::Email, Get, Set};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Default)]
|
#[derive(Debug, Clone, Serialize, Default)]
|
||||||
pub struct SetArguments {
|
pub struct SetArguments {
|
||||||
|
@ -167,3 +167,15 @@ impl Display for Property {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Type for EmailSubmission<Set> {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Type for Property {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,10 +26,15 @@ impl URLParser for URLParameter {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct Changes {
|
pub struct Changes {
|
||||||
|
id: Option<String>,
|
||||||
changes: HashMap<String, HashMap<TypeState, String>>,
|
changes: HashMap<String, HashMap<TypeState, String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Changes {
|
impl Changes {
|
||||||
|
pub fn id(&self) -> Option<&str> {
|
||||||
|
self.id.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn account_changes(&mut self, account_id: &str) -> Option<HashMap<TypeState, String>> {
|
pub fn account_changes(&mut self, account_id: &str) -> Option<HashMap<TypeState, String>> {
|
||||||
self.changes.remove(account_id)
|
self.changes.remove(account_id)
|
||||||
}
|
}
|
||||||
|
@ -38,7 +43,11 @@ impl Changes {
|
||||||
self.changes.keys()
|
self.changes.keys()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_innter(self) -> HashMap<String, HashMap<TypeState, String>> {
|
pub fn changes(&self, account_id: &str) -> Option<impl Iterator<Item = (&TypeState, &String)>> {
|
||||||
|
self.changes.get(account_id).map(|changes| changes.iter())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_inner(self) -> HashMap<String, HashMap<TypeState, String>> {
|
||||||
self.changes
|
self.changes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,16 @@ impl EventParser {
|
||||||
Ok(Event {
|
Ok(Event {
|
||||||
event: EventType::State,
|
event: EventType::State,
|
||||||
data,
|
data,
|
||||||
|
id,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
return match serde_json::from_slice::<StateChange>(&data) {
|
return match serde_json::from_slice::<StateChange>(&data) {
|
||||||
Ok(state_change) => Some(Ok(Changes {
|
Ok(state_change) => Some(Ok(Changes {
|
||||||
|
id: if !id.is_empty() {
|
||||||
|
Some(String::from_utf8(id).unwrap_or_default())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
changes: state_change.changed,
|
changes: state_change.changed,
|
||||||
})),
|
})),
|
||||||
Err(err) => Some(Err(err.into())),
|
Err(err) => Some(Err(err.into())),
|
||||||
|
@ -74,12 +80,19 @@ impl EventParser {
|
||||||
}
|
}
|
||||||
Ok(Event {
|
Ok(Event {
|
||||||
event: EventType::Ping,
|
event: EventType::Ping,
|
||||||
|
#[cfg(feature = "debug")]
|
||||||
|
id,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
#[cfg(feature = "debug")]
|
#[cfg(feature = "debug")]
|
||||||
return Some(Ok(Changes {
|
return Some(Ok(Changes {
|
||||||
|
id: if !id.is_empty() {
|
||||||
|
Some(String::from_utf8(id).unwrap_or_default())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
changes: std::collections::HashMap::from_iter([(
|
changes: std::collections::HashMap::from_iter([(
|
||||||
"ping".to_string(),
|
"ping".to_string(),
|
||||||
std::collections::HashMap::new(),
|
std::collections::HashMap::new(),
|
||||||
|
|
|
@ -5,6 +5,8 @@ pub mod set;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::core::set::list_not_set;
|
use crate::core::set::list_not_set;
|
||||||
|
use crate::core::Type;
|
||||||
|
use crate::Set;
|
||||||
use crate::{email::EmailAddress, Get};
|
use crate::{email::EmailAddress, Get};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -83,3 +85,15 @@ impl Display for Property {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Type for Identity<Set> {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Type for Property {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ pub mod set;
|
||||||
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::core::set::string_not_set;
|
use crate::core::{set::string_not_set, Type};
|
||||||
use crate::mailbox::set::role_not_set;
|
use crate::mailbox::set::role_not_set;
|
||||||
use crate::Get;
|
use crate::{Get, Set};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Default)]
|
#[derive(Debug, Clone, Serialize, Default)]
|
||||||
|
@ -183,3 +183,15 @@ impl ChangesResponse {
|
||||||
self.updated_properties.as_deref()
|
self.updated_properties.as_deref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Type for Mailbox<Set> {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Type for Property {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,10 @@ impl PushSubscription<Get> {
|
||||||
self.id.as_ref().unwrap()
|
self.id.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_id(self) -> String {
|
||||||
|
self.id.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn device_client_id(&self) -> &str {
|
pub fn device_client_id(&self) -> &str {
|
||||||
self.device_client_id.as_ref().unwrap()
|
self.device_client_id.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,66 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
|
client::Client,
|
||||||
core::{
|
core::{
|
||||||
get::GetRequest,
|
get::GetRequest,
|
||||||
request::{Arguments, Request},
|
request::{Arguments, Request},
|
||||||
response::{PushSubscriptionGetResponse, PushSubscriptionSetResponse},
|
response::{PushSubscriptionGetResponse, PushSubscriptionSetResponse},
|
||||||
set::SetRequest,
|
set::{Create, SetRequest},
|
||||||
},
|
},
|
||||||
Method, Set,
|
Method, Set,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::PushSubscription;
|
use super::{Keys, PushSubscription};
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
pub async fn push_subscription_create(
|
||||||
|
&mut 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>()
|
||||||
|
.await?
|
||||||
|
.created(&id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn push_subscription_verify(
|
||||||
|
&mut 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>()
|
||||||
|
.await?
|
||||||
|
.updated(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn push_subscription_destroy(&mut self, id: &str) -> crate::Result<()> {
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_push_subscription().destroy([id]);
|
||||||
|
request
|
||||||
|
.send_single::<PushSubscriptionSetResponse>()
|
||||||
|
.await?
|
||||||
|
.destroyed(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Request<'_> {
|
impl Request<'_> {
|
||||||
pub fn get_push_subscription(&mut self) -> &mut GetRequest<super::Property, ()> {
|
pub fn get_push_subscription(&mut self) -> &mut GetRequest<super::Property, ()> {
|
||||||
|
|
|
@ -8,7 +8,8 @@ use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::core::set::list_not_set;
|
use crate::core::set::list_not_set;
|
||||||
use crate::{Get, TypeState};
|
use crate::core::Type;
|
||||||
|
use crate::{Get, Set, TypeState};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct PushSubscription<State = Get> {
|
pub struct PushSubscription<State = Get> {
|
||||||
|
@ -84,3 +85,15 @@ pub struct Keys {
|
||||||
p256dh: String,
|
p256dh: String,
|
||||||
auth: String,
|
auth: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Type for PushSubscription<Set> {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Type for Property {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ use std::fmt::Display;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::core::Type;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Thread {
|
pub struct Thread {
|
||||||
id: String,
|
id: String,
|
||||||
|
@ -20,6 +22,12 @@ pub enum Property {
|
||||||
EmailIds,
|
EmailIds,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Type for Property {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for Property {
|
impl Display for Property {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
@ -6,7 +6,9 @@ use std::fmt::Display;
|
||||||
|
|
||||||
use crate::core::set::date_not_set;
|
use crate::core::set::date_not_set;
|
||||||
use crate::core::set::string_not_set;
|
use crate::core::set::string_not_set;
|
||||||
|
use crate::core::Type;
|
||||||
use crate::Get;
|
use crate::Get;
|
||||||
|
use crate::Set;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -78,3 +80,15 @@ impl Display for Property {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Type for VacationResponse<Set> {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Type for Property {
|
||||||
|
fn requires_account_id() -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue