diff --git a/Cargo.toml b/Cargo.toml index 0018c5b0..66426a6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,10 +15,11 @@ edition = "2018" [dependencies] http = "0.2.1" js_int = { version = "0.1.4", features = ["serde"] } -ruma-api = "0.15.0" -ruma-events = "0.18.0" -ruma-identifiers = "0.14.1" -serde = { version = "1.0.105", features = ["derive"] } -serde_json = "1.0.50" +ruma-api = "0.16.0-rc.1" +ruma-events = "0.19.0-rc.1" +ruma-identifiers = "0.15.1" +ruma-serde = "0.1.0" +serde = { version = "1.0.106", features = ["derive"] } +serde_json = "1.0.51" strum = { version = "0.18.0", features = ["derive"] } url = { version = "2.1.1", features = ["serde"] } diff --git a/src/lib.rs b/src/lib.rs index 7c2ed9c0..375c159b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,4 @@ pub mod error; pub mod r0; pub mod unversioned; -mod serde; - pub use error::Error; diff --git a/src/r0/account/register.rs b/src/r0/account/register.rs index 9b11340d..f517f4ca 100644 --- a/src/r0/account/register.rs +++ b/src/r0/account/register.rs @@ -55,7 +55,7 @@ ruma_api! { pub kind: Option, /// If `true`, an `access_token` and `device_id` should not be returned /// from this call, therefore preventing an automatic login. - #[serde(default, skip_serializing_if = "crate::serde::is_default")] + #[serde(default, skip_serializing_if = "ruma_serde::is_default")] pub inhibit_login: bool, } diff --git a/src/r0/account/request_openid_token.rs b/src/r0/account/request_openid_token.rs index 637524a5..ee5166d5 100644 --- a/src/r0/account/request_openid_token.rs +++ b/src/r0/account/request_openid_token.rs @@ -30,7 +30,7 @@ ruma_api! { /// Homeserver domain for verification of user's identity. pub matrix_server_name: String, /// Seconds until token expiration. - #[serde(with = "crate::serde::duration::secs")] + #[serde(with = "ruma_serde::duration::secs")] pub expires_in: Duration, } diff --git a/src/r0/contact/get_contacts.rs b/src/r0/contact/get_contacts.rs index 63b31303..06834c64 100644 --- a/src/r0/contact/get_contacts.rs +++ b/src/r0/contact/get_contacts.rs @@ -38,10 +38,10 @@ pub struct ThirdPartyIdentifier { /// The medium of third party identifier. pub medium: Medium, /// The time when the identifier was validated by the identity server. - #[serde(with = "crate::serde::time::ms_since_unix_epoch")] + #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] pub validated_at: SystemTime, /// The time when the homeserver associated the third party identifier with the user. - #[serde(with = "crate::serde::time::ms_since_unix_epoch")] + #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] pub added_at: SystemTime, } diff --git a/src/r0/device.rs b/src/r0/device.rs index 39523f2e..6e0a8620 100644 --- a/src/r0/device.rs +++ b/src/r0/device.rs @@ -22,7 +22,7 @@ pub struct Device { pub ip: Option, /// Unix timestamp that the session was last active. #[serde( - with = "crate::serde::time::opt_ms_since_unix_epoch", + with = "ruma_serde::time::opt_ms_since_unix_epoch", default, skip_serializing_if = "Option::is_none" )] diff --git a/src/r0/directory/get_public_rooms_filtered.rs b/src/r0/directory/get_public_rooms_filtered.rs index b3302f58..3deb6565 100644 --- a/src/r0/directory/get_public_rooms_filtered.rs +++ b/src/r0/directory/get_public_rooms_filtered.rs @@ -40,7 +40,7 @@ ruma_api! { #[serde(skip_serializing_if = "Option::is_none")] pub filter: Option, /// Network to fetch the public room lists from. - #[serde(flatten, skip_serializing_if = "crate::serde::is_default")] + #[serde(flatten, skip_serializing_if = "ruma_serde::is_default")] pub room_network: RoomNetwork, } diff --git a/src/r0/keys/claim_keys.rs b/src/r0/keys/claim_keys.rs index 3b4dd450..70b5a7ec 100644 --- a/src/r0/keys/claim_keys.rs +++ b/src/r0/keys/claim_keys.rs @@ -24,7 +24,7 @@ ruma_api! { /// The time (in milliseconds) to wait when downloading keys from remote servers. /// 10 seconds is the recommended default. #[serde( - with = "crate::serde::duration::opt_ms", + with = "ruma_serde::duration::opt_ms", default, skip_serializing_if = "Option::is_none", )] diff --git a/src/r0/keys/get_keys.rs b/src/r0/keys/get_keys.rs index 98628261..b9e3ecb4 100644 --- a/src/r0/keys/get_keys.rs +++ b/src/r0/keys/get_keys.rs @@ -22,7 +22,7 @@ ruma_api! { /// The time (in milliseconds) to wait when downloading keys from remote servers. /// 10 seconds is the recommended default. #[serde( - with = "crate::serde::duration::opt_ms", + with = "ruma_serde::duration::opt_ms", default, skip_serializing_if = "Option::is_none", )] diff --git a/src/r0/media/get_media_preview.rs b/src/r0/media/get_media_preview.rs index 118c09b6..b517d21d 100644 --- a/src/r0/media/get_media_preview.rs +++ b/src/r0/media/get_media_preview.rs @@ -21,7 +21,7 @@ ruma_api! { pub url: String, /// Preferred point in time (in milliseconds) to return a preview for. #[ruma_api(query)] - #[serde(with = "crate::serde::time::ms_since_unix_epoch")] + #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] pub ts: SystemTime, } diff --git a/src/r0/message/get_message_events.rs b/src/r0/message/get_message_events.rs index 3d7923ff..e5220d2a 100644 --- a/src/r0/message/get_message_events.rs +++ b/src/r0/message/get_message_events.rs @@ -49,7 +49,7 @@ ruma_api! { /// A RoomEventFilter to filter returned events with. #[ruma_api(query)] #[serde( - with = "crate::serde::json_string", + with = "ruma_serde::json_string", default, skip_serializing_if = "Option::is_none" )] diff --git a/src/r0/presence/get_presence.rs b/src/r0/presence/get_presence.rs index 6424435b..b6e02d6e 100644 --- a/src/r0/presence/get_presence.rs +++ b/src/r0/presence/get_presence.rs @@ -31,7 +31,7 @@ ruma_api! { pub currently_active: Option, /// The length of time in milliseconds since an action was performed by the user. #[serde( - with = "crate::serde::duration::opt_ms", + with = "ruma_serde::duration::opt_ms", default, skip_serializing_if = "Option::is_none", )] diff --git a/src/r0/push/get_notifications.rs b/src/r0/push/get_notifications.rs index f26a60fd..de263b96 100644 --- a/src/r0/push/get_notifications.rs +++ b/src/r0/push/get_notifications.rs @@ -74,6 +74,6 @@ pub struct Notification { pub room_id: RoomId, /// The time at which the event notification was sent, in milliseconds. - #[serde(with = "crate::serde::time::ms_since_unix_epoch")] + #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] pub ts: SystemTime, } diff --git a/src/r0/server/get_user_info.rs b/src/r0/server/get_user_info.rs index c07d1985..5c3a5dd9 100644 --- a/src/r0/server/get_user_info.rs +++ b/src/r0/server/get_user_info.rs @@ -38,7 +38,7 @@ pub struct ConnectionInfo { /// Most recently seen IP address of the session. pub ip: String, /// Time when that the session was last active. - #[serde(with = "crate::serde::time::ms_since_unix_epoch")] + #[serde(with = "ruma_serde::time::ms_since_unix_epoch")] pub last_seen: SystemTime, /// User agent string last seen in the session. pub user_agent: String, diff --git a/src/r0/sync/sync_events.rs b/src/r0/sync/sync_events.rs index c95e934b..cb6200e2 100644 --- a/src/r0/sync/sync_events.rs +++ b/src/r0/sync/sync_events.rs @@ -17,10 +17,7 @@ use ruma_events::{ use ruma_identifiers::RoomId; use serde::{Deserialize, Serialize}; -use crate::{ - r0::{filter::FilterDefinition, keys::KeyAlgorithm}, - serde::is_default, -}; +use crate::r0::{filter::FilterDefinition, keys::KeyAlgorithm}; ruma_api! { metadata { @@ -45,16 +42,16 @@ ruma_api! { #[ruma_api(query)] pub since: Option, /// Controls whether to include the full state for all rooms the user is a member of. - #[serde(default, skip_serializing_if = "is_default")] + #[serde(default, skip_serializing_if = "ruma_serde::is_default")] #[ruma_api(query)] pub full_state: bool, /// Controls whether the client is automatically marked as online by polling this API. - #[serde(default, skip_serializing_if = "is_default")] + #[serde(default, skip_serializing_if = "ruma_serde::is_default")] #[ruma_api(query)] pub set_presence: SetPresence, /// The maximum time to poll in milliseconds before returning this request. #[serde( - with = "crate::serde::duration::opt_ms", + with = "ruma_serde::duration::opt_ms", default, skip_serializing_if = "Option::is_none", )] @@ -122,7 +119,7 @@ pub enum Filter { // FilterDefinition is the first variant, JSON decoding is attempted first which is almost // functionally equivalent to looking at whether the first symbol is a '{' as the spec says. // (there are probably some corner cases like leading whitespace) - #[serde(with = "crate::serde::json_string")] + #[serde(with = "ruma_serde::json_string")] /// A complete filter definition serialized to JSON. FilterDefinition(FilterDefinition), /// The ID of a filter saved on the server. diff --git a/src/r0/typing/create_typing_event.rs b/src/r0/typing/create_typing_event.rs index 3731ad02..6d1a4d84 100644 --- a/src/r0/typing/create_typing_event.rs +++ b/src/r0/typing/create_typing_event.rs @@ -21,7 +21,7 @@ ruma_api! { pub room_id: RoomId, /// The length of time in milliseconds to mark this user as typing. #[serde( - with = "crate::serde::duration::opt_ms", + with = "ruma_serde::duration::opt_ms", default, skip_serializing_if = "Option::is_none", )] diff --git a/src/r0/voip/get_turn_server_info.rs b/src/r0/voip/get_turn_server_info.rs index 5e83b58f..420a3382 100644 --- a/src/r0/voip/get_turn_server_info.rs +++ b/src/r0/voip/get_turn_server_info.rs @@ -20,7 +20,7 @@ ruma_api! { /// The password to use. pub password: String, /// The time-to-live in seconds. - #[serde(with = "crate::serde::duration::secs")] + #[serde(with = "ruma_serde::duration::secs")] pub ttl: Duration, /// A list of TURN URIs. pub uris: Vec, diff --git a/src/serde.rs b/src/serde.rs deleted file mode 100644 index 79c08e92..00000000 --- a/src/serde.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Modules to hold functions for de-/serializing remote types - -pub mod duration; -pub mod json_string; -pub mod time; - -pub fn is_default(val: &T) -> bool { - val == &T::default() -} diff --git a/src/serde/duration.rs b/src/serde/duration.rs deleted file mode 100644 index d8c895fa..00000000 --- a/src/serde/duration.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! De-/serialization functions for `std::time::Duration` objects - -pub mod opt_ms; -pub mod secs; diff --git a/src/serde/duration/opt_ms.rs b/src/serde/duration/opt_ms.rs deleted file mode 100644 index 1e8d6462..00000000 --- a/src/serde/duration/opt_ms.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! De-/serialization functions for `Option` objects represented as milliseconds. -//! Delegates to `js_int::UInt` to ensure integer size is within bounds. - -use std::{convert::TryFrom, time::Duration}; - -use js_int::UInt; -use serde::{ - de::{Deserialize, Deserializer}, - ser::{Error, Serialize, Serializer}, -}; - -/// Serialize an Option. -/// -/// Will fail if integer is greater than the maximum integer that can be -/// unambiguously represented by an f64. -pub fn serialize(opt_duration: &Option, serializer: S) -> Result -where - S: Serializer, -{ - match opt_duration { - Some(duration) => match UInt::try_from(duration.as_millis()) { - Ok(uint) => uint.serialize(serializer), - Err(err) => Err(S::Error::custom(err)), - }, - None => serializer.serialize_none(), - } -} - -/// Deserializes an Option. -/// -/// Will fail if integer is greater than the maximum integer that can be -/// unambiguously represented by an f64. -pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - Ok(Option::::deserialize(deserializer)? - .map(|millis| Duration::from_millis(millis.into()))) -} - -#[cfg(test)] -mod tests { - use std::time::Duration; - - use serde::{Deserialize, Serialize}; - use serde_json::json; - - #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] - struct DurationTest { - #[serde(with = "super", default, skip_serializing_if = "Option::is_none")] - timeout: Option, - } - - #[test] - fn test_deserialize_some() { - let json = json!({ "timeout": 3000 }); - - assert_eq!( - serde_json::from_value::(json).unwrap(), - DurationTest { - timeout: Some(Duration::from_millis(3000)) - }, - ); - } - - #[test] - fn test_deserialize_none_by_absence() { - let json = json!({}); - - assert_eq!( - serde_json::from_value::(json).unwrap(), - DurationTest { timeout: None }, - ); - } - - #[test] - fn test_deserialize_none_by_null() { - let json = json!({ "timeout": null }); - - assert_eq!( - serde_json::from_value::(json).unwrap(), - DurationTest { timeout: None }, - ); - } - - #[test] - fn test_serialize_some() { - let request = DurationTest { - timeout: Some(Duration::new(2, 0)), - }; - assert_eq!( - serde_json::to_value(&request).unwrap(), - json!({ "timeout": 2000 }) - ); - } - - #[test] - fn test_serialize_none() { - let request = DurationTest { timeout: None }; - assert_eq!(serde_json::to_value(&request).unwrap(), json!({})); - } -} diff --git a/src/serde/duration/secs.rs b/src/serde/duration/secs.rs deleted file mode 100644 index 830eb4d5..00000000 --- a/src/serde/duration/secs.rs +++ /dev/null @@ -1,69 +0,0 @@ -//! De-/serialization functions for `Option` objects represented as milliseconds. -//! Delegates to `js_int::UInt` to ensure integer size is within bounds. - -use std::{convert::TryFrom, time::Duration}; - -use js_int::UInt; -use serde::{ - de::{Deserialize, Deserializer}, - ser::{Error, Serialize, Serializer}, -}; - -/// Serializes a Duration to an integer representing seconds. -/// -/// Will fail if integer is greater than the maximum integer that can be -/// unambiguously represented by an f64. -pub fn serialize(duration: &Duration, serializer: S) -> Result -where - S: Serializer, -{ - match UInt::try_from(duration.as_secs()) { - Ok(uint) => uint.serialize(serializer), - Err(err) => Err(S::Error::custom(err)), - } -} - -/// Deserializes an integer representing seconds into a Duration. -/// -/// Will fail if integer is greater than the maximum integer that can be -/// unambiguously represented by an f64. -pub fn deserialize<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - UInt::deserialize(deserializer).map(|secs| Duration::from_secs(secs.into())) -} - -#[cfg(test)] -mod tests { - use std::time::Duration; - - use serde::{Deserialize, Serialize}; - use serde_json::json; - - #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] - struct DurationTest { - #[serde(with = "super")] - timeout: Duration, - } - - #[test] - fn test_deserialize() { - let json = json!({ "timeout": 3 }); - - assert_eq!( - serde_json::from_value::(json).unwrap(), - DurationTest { - timeout: Duration::from_secs(3) - }, - ); - } - - #[test] - fn test_serialize() { - let test = DurationTest { - timeout: Duration::from_millis(7000), - }; - assert_eq!(serde_json::to_value(test).unwrap(), json!({ "timeout": 7 }),); - } -} diff --git a/src/serde/json_string.rs b/src/serde/json_string.rs deleted file mode 100644 index e5fabe70..00000000 --- a/src/serde/json_string.rs +++ /dev/null @@ -1,24 +0,0 @@ -//! De-/serialization functions to and from json strings, allows the type to be used as a query string. - -use serde::{ - de::{Deserialize, DeserializeOwned, Deserializer, Error as _}, - ser::{Error as _, Serialize, Serializer}, -}; - -pub fn serialize(filter: T, serializer: S) -> Result -where - T: Serialize, - S: Serializer, -{ - let json = serde_json::to_string(&filter).map_err(S::Error::custom)?; - serializer.serialize_str(&json) -} - -pub fn deserialize<'de, T, D>(deserializer: D) -> Result -where - T: DeserializeOwned, - D: Deserializer<'de>, -{ - let s = String::deserialize(deserializer)?; - serde_json::from_str(&s).map_err(D::Error::custom) -} diff --git a/src/serde/time.rs b/src/serde/time.rs deleted file mode 100644 index e60bb839..00000000 --- a/src/serde/time.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! De-/serialization functions for `std::time::SystemTime` objects - -pub mod ms_since_unix_epoch; -pub mod opt_ms_since_unix_epoch; diff --git a/src/serde/time/ms_since_unix_epoch.rs b/src/serde/time/ms_since_unix_epoch.rs deleted file mode 100644 index ea1b79cc..00000000 --- a/src/serde/time/ms_since_unix_epoch.rs +++ /dev/null @@ -1,78 +0,0 @@ -//! De-/serialization functions for `std::time::SystemTime` objects represented as milliseconds -//! since the UNIX epoch. Delegates to `js_int::UInt` to ensure integer size is within bounds. - -use std::{ - convert::TryFrom, - time::{Duration, SystemTime, UNIX_EPOCH}, -}; - -use js_int::UInt; -use serde::{ - de::{Deserialize, Deserializer}, - ser::{Error, Serialize, Serializer}, -}; - -/// Serialize a SystemTime. -/// -/// Will fail if integer is greater than the maximum integer that can be unambiguously represented -/// by an f64. -pub fn serialize(time: &SystemTime, serializer: S) -> Result -where - S: Serializer, -{ - // If this unwrap fails, the system this is executed is completely broken. - let time_since_epoch = time.duration_since(UNIX_EPOCH).unwrap(); - match UInt::try_from(time_since_epoch.as_millis()) { - Ok(uint) => uint.serialize(serializer), - Err(err) => Err(S::Error::custom(err)), - } -} - -/// Deserializes a SystemTime. -/// -/// Will fail if integer is greater than the maximum integer that can be unambiguously represented -/// by an f64. -pub fn deserialize<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let millis = UInt::deserialize(deserializer)?; - Ok(UNIX_EPOCH + Duration::from_millis(millis.into())) -} - -#[cfg(test)] -mod tests { - use std::time::{Duration, SystemTime, UNIX_EPOCH}; - - use serde::{Deserialize, Serialize}; - use serde_json::json; - - #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] - struct SystemTimeTest { - #[serde(with = "super")] - timestamp: SystemTime, - } - - #[test] - fn test_deserialize() { - let json = json!({ "timestamp": 3000 }); - - assert_eq!( - serde_json::from_value::(json).unwrap(), - SystemTimeTest { - timestamp: UNIX_EPOCH + Duration::from_millis(3000), - }, - ); - } - - #[test] - fn test_serialize() { - let request = SystemTimeTest { - timestamp: UNIX_EPOCH + Duration::new(2, 0), - }; - assert_eq!( - serde_json::to_value(&request).unwrap(), - json!({ "timestamp": 2000 }) - ); - } -} diff --git a/src/serde/time/opt_ms_since_unix_epoch.rs b/src/serde/time/opt_ms_since_unix_epoch.rs deleted file mode 100644 index 787455ac..00000000 --- a/src/serde/time/opt_ms_since_unix_epoch.rs +++ /dev/null @@ -1,100 +0,0 @@ -//! De-/serialization functions for `Option` objects represented as -//! milliseconds since the UNIX epoch. Delegates to `js_int::UInt` to ensure integer size is within -//! bounds. - -use std::time::{Duration, SystemTime, UNIX_EPOCH}; - -use js_int::UInt; -use serde::{ - de::{Deserialize, Deserializer}, - ser::{Serialize, Serializer}, -}; - -/// Serialize an `Option`. -/// -/// Will fail if integer is greater than the maximum integer that can be unambiguously represented -/// by an f64. -pub fn serialize(opt_time: &Option, serializer: S) -> Result -where - S: Serializer, -{ - match opt_time { - Some(time) => super::ms_since_unix_epoch::serialize(time, serializer), - None => Option::::serialize(&None, serializer), - } -} - -/// Deserializes an `Option`. -/// -/// Will fail if integer is greater than the maximum integer that can be unambiguously represented -/// by an f64. -pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - Ok(Option::::deserialize(deserializer)? - .map(|millis| UNIX_EPOCH + Duration::from_millis(millis.into()))) -} - -#[cfg(test)] -mod tests { - use std::time::{Duration, SystemTime, UNIX_EPOCH}; - - use serde::{Deserialize, Serialize}; - use serde_json::json; - - #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] - struct SystemTimeTest { - #[serde(with = "super", default, skip_serializing_if = "Option::is_none")] - timestamp: Option, - } - - #[test] - fn test_deserialize_some() { - let json = json!({ "timestamp": 3000 }); - - assert_eq!( - serde_json::from_value::(json).unwrap(), - SystemTimeTest { - timestamp: Some(UNIX_EPOCH + Duration::from_millis(3000)) - }, - ); - } - - #[test] - fn test_deserialize_none_by_absence() { - let json = json!({}); - - assert_eq!( - serde_json::from_value::(json).unwrap(), - SystemTimeTest { timestamp: None }, - ); - } - - #[test] - fn test_deserialize_none_by_null() { - let json = json!({ "timestamp": null }); - - assert_eq!( - serde_json::from_value::(json).unwrap(), - SystemTimeTest { timestamp: None }, - ); - } - - #[test] - fn test_serialize_some() { - let request = SystemTimeTest { - timestamp: Some(UNIX_EPOCH + Duration::new(2, 0)), - }; - assert_eq!( - serde_json::to_value(&request).unwrap(), - json!({ "timestamp": 2000 }) - ); - } - - #[test] - fn test_serialize_none() { - let request = SystemTimeTest { timestamp: None }; - assert_eq!(serde_json::to_value(&request).unwrap(), json!({})); - } -}