Fixes and use of rustls.

main
Mauro D 2022-05-16 17:24:27 +00:00
parent 2549d96703
commit 53abec1222
15 changed files with 211 additions and 27 deletions

View File

@ -15,7 +15,7 @@ readme = "README.md"
serde = { version = "1.0", features = ["derive"]}
serde_json = "1.0"
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"
async-stream = "0.3.3"
base64 = "0.13"

View File

@ -4,15 +4,16 @@ use serde::{Deserialize, Serialize};
use crate::Method;
use super::{request::ResultReference, RequestParams};
use super::{request::ResultReference, RequestParams, Type};
#[derive(Debug, Clone, Serialize)]
pub struct GetRequest<T: Display, A: Default> {
pub struct GetRequest<T: Display + Type, A: Default> {
#[serde(skip)]
method: (Method, usize),
#[serde(rename = "accountId")]
account_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
account_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
ids: Option<Vec<String>>,
@ -32,7 +33,7 @@ pub struct GetRequest<T: Display, A: Default> {
#[derive(Debug, Clone, Deserialize)]
pub struct GetResponse<T> {
#[serde(rename = "accountId")]
account_id: String,
account_id: Option<String>,
state: String,
@ -42,10 +43,14 @@ pub struct GetResponse<T> {
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 {
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),
ids: 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 {
self.account_id = account_id.into();
if T::requires_account_id() {
self.account_id = Some(account_id.into());
}
self
}
@ -95,7 +102,7 @@ impl<T: Display, A: Default> GetRequest<T, A> {
impl<T> GetResponse<T> {
pub fn account_id(&self) -> &str {
&self.account_id
self.account_id.as_ref().unwrap()
}
pub fn state(&self) -> &str {

View File

@ -26,3 +26,7 @@ impl RequestParams {
}
}
}
pub trait Type {
fn requires_account_id() -> bool;
}

View File

@ -7,12 +7,13 @@ use std::{
use crate::Error;
use super::{request::ResultReference, RequestParams};
use super::{request::ResultReference, RequestParams, Type};
#[derive(Debug, Clone, Serialize)]
pub struct SetRequest<T: Create, A: Default> {
pub struct SetRequest<T: Create + Type, A: Default> {
#[serde(rename = "accountId")]
account_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
account_id: Option<String>,
#[serde(rename = "ifInState")]
#[serde(skip_serializing_if = "Option::is_none")]
@ -39,13 +40,13 @@ pub struct SetRequest<T: Create, A: Default> {
#[derive(Debug, Clone, Deserialize)]
pub struct SetResponse<T, U: Display> {
#[serde(rename = "accountId")]
account_id: String,
account_id: Option<String>,
#[serde(rename = "oldState")]
old_state: Option<String>,
#[serde(rename = "newState")]
new_state: String,
new_state: Option<String>,
#[serde(rename = "created")]
created: Option<HashMap<String, T>>,
@ -130,10 +131,14 @@ pub trait Create: Sized {
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 {
Self {
account_id: params.account_id,
account_id: if T::requires_account_id() {
params.account_id.into()
} else {
None
},
if_in_state: None,
create: 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 {
self.account_id = account_id.into();
if T::requires_account_id() {
self.account_id = Some(account_id.into());
}
self
}
@ -214,7 +221,7 @@ impl<T: Create, A: Default> SetRequest<T, A> {
impl<T, U: Display> SetResponse<T, U> {
pub fn account_id(&self) -> &str {
&self.account_id
self.account_id.as_ref().unwrap()
}
pub fn old_state(&self) -> Option<&str> {
@ -222,7 +229,7 @@ impl<T, U: Display> SetResponse<T, U> {
}
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> {

View File

@ -13,7 +13,10 @@ use std::{
fmt::{self, Display, Formatter},
};
use crate::{core::request::ResultReference, Get};
use crate::{
core::{request::ResultReference, Type},
Get, Set,
};
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
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")]
use std::collections::BTreeMap;

View File

@ -8,7 +8,7 @@ use std::{collections::HashMap, fmt::Display};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::{email::Email, Get};
use crate::{core::Type, email::Email, Get, Set};
#[derive(Debug, Clone, Serialize, Default)]
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
}
}

View File

@ -26,10 +26,15 @@ impl URLParser for URLParameter {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Changes {
id: Option<String>,
changes: HashMap<String, HashMap<TypeState, String>>,
}
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>> {
self.changes.remove(account_id)
}
@ -38,7 +43,11 @@ impl Changes {
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
}
}

View File

@ -63,10 +63,16 @@ impl EventParser {
Ok(Event {
event: EventType::State,
data,
id,
..
}) => {
return match serde_json::from_slice::<StateChange>(&data) {
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,
})),
Err(err) => Some(Err(err.into())),
@ -74,12 +80,19 @@ impl EventParser {
}
Ok(Event {
event: EventType::Ping,
#[cfg(feature = "debug")]
id,
..
}) => {
#[cfg(feature = "debug")]
use std::iter::FromIterator;
#[cfg(feature = "debug")]
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([(
"ping".to_string(),
std::collections::HashMap::new(),

View File

@ -5,6 +5,8 @@ pub mod set;
use std::fmt::Display;
use crate::core::set::list_not_set;
use crate::core::Type;
use crate::Set;
use crate::{email::EmailAddress, Get};
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
}
}

View File

@ -5,9 +5,9 @@ pub mod set;
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::Get;
use crate::{Get, Set};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Default)]
@ -183,3 +183,15 @@ impl ChangesResponse {
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
}
}

View File

@ -7,6 +7,10 @@ impl PushSubscription<Get> {
self.id.as_ref().unwrap()
}
pub fn unwrap_id(self) -> String {
self.id.unwrap()
}
pub fn device_client_id(&self) -> &str {
self.device_client_id.as_ref().unwrap()
}

View File

@ -1,14 +1,66 @@
use crate::{
client::Client,
core::{
get::GetRequest,
request::{Arguments, Request},
response::{PushSubscriptionGetResponse, PushSubscriptionSetResponse},
set::SetRequest,
set::{Create, SetRequest},
},
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<'_> {
pub fn get_push_subscription(&mut self) -> &mut GetRequest<super::Property, ()> {

View File

@ -8,7 +8,8 @@ use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
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)]
pub struct PushSubscription<State = Get> {
@ -84,3 +85,15 @@ pub struct Keys {
p256dh: String,
auth: String,
}
impl Type for PushSubscription<Set> {
fn requires_account_id() -> bool {
false
}
}
impl Type for Property {
fn requires_account_id() -> bool {
false
}
}

View File

@ -5,6 +5,8 @@ use std::fmt::Display;
use serde::{Deserialize, Serialize};
use crate::core::Type;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Thread {
id: String,
@ -20,6 +22,12 @@ pub enum Property {
EmailIds,
}
impl Type for Property {
fn requires_account_id() -> bool {
true
}
}
impl Display for Property {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {

View File

@ -6,7 +6,9 @@ use std::fmt::Display;
use crate::core::set::date_not_set;
use crate::core::set::string_not_set;
use crate::core::Type;
use crate::Get;
use crate::Set;
use chrono::{DateTime, Utc};
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
}
}