From 0d305d8f243f7146beef9e4b66339c9117ffbf4c Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 30 Apr 2020 18:07:20 +0200 Subject: [PATCH] Update ruma_serde to 0.1.2 --- Cargo.toml | 2 +- src/algorithm.rs | 2 +- src/dummy.rs | 3 +- src/empty.rs | 58 -------------------------- src/event_type.rs | 2 +- src/from_raw.rs | 8 ++++ src/ignored_user_list.rs | 6 +-- src/lib.rs | 9 ++-- src/push_rules.rs | 8 ++-- src/room/canonical_alias.rs | 4 +- src/room/create.rs | 5 +-- src/room/name.rs | 5 +-- src/room/server_acl.rs | 6 +-- src/util.rs | 82 +------------------------------------ 14 files changed, 30 insertions(+), 170 deletions(-) delete mode 100644 src/empty.rs diff --git a/Cargo.toml b/Cargo.toml index f3315bf3..80633b73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ edition = "2018" js_int = { version = "0.1.5", features = ["serde"] } ruma-events-macros = { path = "ruma-events-macros", version = "=0.21.0-beta.1" } ruma-identifiers = "0.16.0" -ruma-serde = "0.1.0" +ruma-serde = "0.1.2" serde = { version = "1.0.106", features = ["derive"] } serde_json = { version = "1.0.52", features = ["raw_value"] } diff --git a/src/algorithm.rs b/src/algorithm.rs index 3d67f3c8..ba3a5284 100644 --- a/src/algorithm.rs +++ b/src/algorithm.rs @@ -64,10 +64,10 @@ impl From for String { #[cfg(test)] mod tests { + use ruma_serde::test::serde_json_eq; use serde_json::json; use super::*; - use crate::util::serde_json_eq; #[test] fn serialize_and_deserialize_from_display_form() { diff --git a/src/dummy.rs b/src/dummy.rs index f192d2db..8c7f514b 100644 --- a/src/dummy.rs +++ b/src/dummy.rs @@ -1,8 +1,7 @@ //! Types for the *m.dummy* event. use ruma_events_macros::ruma_event; - -use crate::Empty; +use ruma_serde::empty::Empty; ruma_event! { /// This event type is used to indicate new Olm sessions for end-to-end encryption. diff --git a/src/empty.rs b/src/empty.rs deleted file mode 100644 index a288af01..00000000 --- a/src/empty.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::fmt::{self, Formatter}; - -use serde::{ - de::{Deserialize, Deserializer, MapAccess, Visitor}, - ser::{Serialize, SerializeMap, Serializer}, -}; - -use crate::FromRaw; - -/// A meaningless value that serializes to an empty JSON object. -/// -/// This type is used in a few places where the Matrix specification requires an empty JSON object, -/// but it's wasteful to represent it as a `BTreeMap` in Rust code. -#[derive(Clone, Debug, PartialEq)] -pub struct Empty; - -impl Serialize for Empty { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_map(Some(0))?.end() - } -} - -impl<'de> Deserialize<'de> for Empty { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct EmptyMapVisitor; - - impl<'de> Visitor<'de> for EmptyMapVisitor { - type Value = Empty; - - fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "an object/map") - } - - fn visit_map(self, _map: A) -> Result - where - A: MapAccess<'de>, - { - Ok(Empty) - } - } - - deserializer.deserialize_map(EmptyMapVisitor) - } -} - -impl FromRaw for Empty { - type Raw = Self; - - fn from_raw(raw: Self) -> Self { - raw - } -} diff --git a/src/event_type.rs b/src/event_type.rs index f0d30a8b..445c0973 100644 --- a/src/event_type.rs +++ b/src/event_type.rs @@ -269,10 +269,10 @@ impl From for String { #[cfg(test)] mod tests { + use ruma_serde::test::serde_json_eq; use serde_json::json; use super::*; - use crate::util::serde_json_eq; #[allow(clippy::cognitive_complexity)] #[test] diff --git a/src/from_raw.rs b/src/from_raw.rs index 07d27b88..631ab934 100644 --- a/src/from_raw.rs +++ b/src/from_raw.rs @@ -27,6 +27,14 @@ pub trait TryFromRaw: Sized { fn try_from_raw(_: Self::Raw) -> Result; } +impl FromRaw for ruma_serde::empty::Empty { + type Raw = Self; + + fn from_raw(raw: Self) -> Self { + raw + } +} + impl FromRaw for serde_json::Value { type Raw = Self; diff --git a/src/ignored_user_list.rs b/src/ignored_user_list.rs index aa8438d6..f44c7e07 100644 --- a/src/ignored_user_list.rs +++ b/src/ignored_user_list.rs @@ -3,7 +3,7 @@ use ruma_identifiers::UserId; use serde::{Deserialize, Serialize}; -use crate::{util::vec_as_map_of_empty, EventType, FromRaw}; +use crate::{EventType, FromRaw}; /// A list of users to ignore. #[derive(Clone, Debug, PartialEq, Serialize)] @@ -27,7 +27,7 @@ impl FromRaw for IgnoredUserListEvent { #[derive(Clone, Debug, PartialEq, Serialize)] pub struct IgnoredUserListEventContent { /// A list of users to ignore. - #[serde(with = "vec_as_map_of_empty")] + #[serde(with = "ruma_serde::vec_as_map_of_empty")] pub ignored_users: Vec, } @@ -61,7 +61,7 @@ pub(crate) mod raw { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct IgnoredUserListEventContent { /// A list of users to ignore. - #[serde(with = "vec_as_map_of_empty")] + #[serde(with = "ruma_serde::vec_as_map_of_empty")] pub ignored_users: Vec, } } diff --git a/src/lib.rs b/src/lib.rs index b5b5cc41..a630194d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -122,16 +122,15 @@ use serde::{Deserialize, Serialize}; use self::room::redaction::RedactionEvent; -pub use self::{ - custom::{CustomEvent, CustomRoomEvent, CustomStateEvent}, - empty::Empty, -}; +pub use self::custom::{CustomEvent, CustomRoomEvent, CustomStateEvent}; + +#[deprecated = "Use ruma_serde::empty::Empty directly instead."] +pub use ruma_serde::empty::Empty; #[macro_use] mod macros; mod algorithm; -mod empty; mod error; mod event_type; mod from_raw; diff --git a/src/push_rules.rs b/src/push_rules.rs index 152337cf..c2b70828 100644 --- a/src/push_rules.rs +++ b/src/push_rules.rs @@ -13,7 +13,7 @@ use serde::{ }; use serde_json::{from_value, Value}; -use crate::{util::default_true, FromStrError}; +use crate::FromStrError; ruma_event! { /// Describes all push rules for a user. @@ -230,13 +230,12 @@ impl<'de> Deserialize<'de> for Action { /// Values for the `set_tweak` action. #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -#[serde(tag = "set_tweak")] +#[serde(tag = "set_tweak", rename_all = "lowercase")] pub enum Tweak { /// A string representing the sound to be played when this notification arrives. /// /// A value of "default" means to play a default sound. A device may choose to alert the user by /// some other means if appropriate, eg. vibration. - #[serde(rename = "sound")] Sound { /// The sound to be played. value: String, @@ -249,10 +248,9 @@ pub enum Tweak { /// event occurred. If a `highlight` tweak is given with no value, its value is defined to be /// `true`. If no highlight tweak is given at all then the value of `highlight` is defined to be /// `false`. - #[serde(rename = "highlight")] Highlight { /// Whether or not the message should be highlighted. - #[serde(default = "default_true")] + #[serde(default = "ruma_serde::default_true")] value: bool, }, } diff --git a/src/room/canonical_alias.rs b/src/room/canonical_alias.rs index 6f35e296..a6513cd9 100644 --- a/src/room/canonical_alias.rs +++ b/src/room/canonical_alias.rs @@ -3,8 +3,6 @@ use ruma_events_macros::ruma_event; use ruma_identifiers::RoomAliasId; -use crate::util::empty_string_as_none; - ruma_event! { /// Informs the room as to which alias is the canonical one. CanonicalAliasEvent { @@ -16,7 +14,7 @@ ruma_event! { /// Rooms with `alias: None` should be treated the same as a room /// with no canonical alias. #[serde( - default, deserialize_with = "empty_string_as_none", + default, deserialize_with = "ruma_serde::empty_string_as_none", skip_serializing_if = "Option::is_none" )] pub alias: Option, diff --git a/src/room/create.rs b/src/room/create.rs index d7f93e5d..87734ce9 100644 --- a/src/room/create.rs +++ b/src/room/create.rs @@ -6,8 +6,6 @@ use ruma_events_macros::ruma_event; use ruma_identifiers::{EventId, RoomId, RoomVersionId, UserId}; use serde::{Deserialize, Serialize}; -use crate::util::default_true; - ruma_event! { /// This is the first event in a room and cannot be changed. It acts as the root of all other /// events. @@ -19,8 +17,7 @@ ruma_event! { pub creator: UserId, /// Whether or not this room's data should be transferred to other homeservers. - #[serde(rename = "m.federate")] - #[serde(default = "default_true")] + #[serde(rename = "m.federate", default = "ruma_serde::default_true")] pub federate: bool, /// The version of the room. Defaults to "1" if the key does not exist. diff --git a/src/room/name.rs b/src/room/name.rs index 41f531a1..4676f6db 100644 --- a/src/room/name.rs +++ b/src/room/name.rs @@ -5,7 +5,7 @@ use std::time::SystemTime; use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{Deserialize, Serialize}; -use crate::{util::empty_string_as_none, EventType, InvalidInput, TryFromRaw, UnsignedData}; +use crate::{EventType, InvalidInput, TryFromRaw, UnsignedData}; /// A human-friendly room name designed to be displayed to the end-user. #[derive(Clone, Debug, PartialEq, Serialize)] @@ -144,8 +144,7 @@ pub(crate) mod raw { /// The name of the room. This MUST NOT exceed 255 bytes. // The spec says "A room with an m.room.name event with an absent, null, or empty name field // should be treated the same as a room with no m.room.name event." - #[serde(default)] - #[serde(deserialize_with = "empty_string_as_none")] + #[serde(default, deserialize_with = "ruma_serde::empty_string_as_none")] pub(crate) name: Option, } } diff --git a/src/room/server_acl.rs b/src/room/server_acl.rs index 56da5f78..cdd3836b 100644 --- a/src/room/server_acl.rs +++ b/src/room/server_acl.rs @@ -5,7 +5,7 @@ use std::time::SystemTime; use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{Deserialize, Serialize}; -use crate::{util::default_true, EventType, FromRaw, UnsignedData}; +use crate::{EventType, FromRaw, UnsignedData}; /// An event to indicate which servers are permitted to participate in the room. #[derive(Clone, Debug, PartialEq, Serialize)] @@ -49,7 +49,7 @@ pub struct ServerAclEventContent { /// This is strongly recommended to be set to false as servers running with IP literal names are /// strongly discouraged in order to require legitimate homeservers to be backed by a valid /// registered domain name. - #[serde(default = "default_true")] + #[serde(default = "ruma_serde::default_true")] pub allow_ip_literals: bool, /// The server names to allow in the room, excluding any port information. Wildcards may be used @@ -146,7 +146,7 @@ pub(crate) mod raw { /// This is strongly recommended to be set to false as servers running with IP literal names /// are strongly discouraged in order to require legitimate homeservers to be backed by a /// valid registered domain name. - #[serde(default = "default_true")] + #[serde(default = "ruma_serde::default_true")] pub allow_ip_literals: bool, /// The server names to allow in the room, excluding any port information. Wildcards may be diff --git a/src/util.rs b/src/util.rs index bf96c909..0ec2b187 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,9 +1,6 @@ use std::fmt::Debug; -use serde::{ - de::{Deserialize, DeserializeOwned, IntoDeserializer}, - Serialize, -}; +use serde::{de::DeserializeOwned, Serialize}; use serde_json::Value; use crate::{EventJson, TryFromRaw}; @@ -45,83 +42,6 @@ where .map_err(serde_json_error_to_generic_de_error) } -/// Serde deserialization decorator to map empty Strings to None, -/// and forward non-empty Strings to the Deserialize implementation for T. -/// Useful for the typical -/// "A room with an X event with an absent, null, or empty Y field -/// should be treated the same as a room with no such event." -/// formulation in the spec. -/// -/// To be used like this: -/// `#[serde(deserialize_with = "empty_string_as_none"]` -/// Relevant serde issue: https://github.com/serde-rs/serde/issues/1425 -pub fn empty_string_as_none<'de, D, T>(de: D) -> Result, D::Error> -where - D: serde::Deserializer<'de>, - T: serde::Deserialize<'de>, -{ - let opt = Option::::deserialize(de)?; - // TODO: Switch to and remove this attribute `opt.as_deref()` once MSRV is >= 1.40 - #[allow(clippy::option_as_ref_deref, clippy::unknown_clippy_lints)] - let opt = opt.as_ref().map(String::as_str); - match opt { - None | Some("") => Ok(None), - // If T = String, like in m.room.name, the second deserialize is actually superfluous. - // TODO: optimize that somehow? - Some(s) => T::deserialize(s.into_deserializer()).map(Some), - } -} - -/// Serde serialization and deserialization functions that map a `Vec` to a `BTreeMap`. -/// -/// The Matrix spec sometimes specifies lists as hash maps so the list entries can be expanded with -/// attributes without breaking compatibility. As that would be a breaking change for ruma's event -/// types anyway, we convert them to `Vec`s for simplicity, using this module. -/// -/// To be used as `#[serde(with = "vec_as_map_of_empty")]`. -pub mod vec_as_map_of_empty { - use std::collections::BTreeMap; - - use serde::{Deserialize, Deserializer, Serialize, Serializer}; - - use crate::Empty; - - #[allow(clippy::ptr_arg)] - pub fn serialize(vec: &Vec, serializer: S) -> Result - where - S: Serializer, - T: Serialize + Eq + Ord, - { - vec.iter() - .map(|v| (v, Empty)) - .collect::>() - .serialize(serializer) - } - - pub fn deserialize<'de, D, T>(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - T: Deserialize<'de> + Eq + Ord, - { - BTreeMap::::deserialize(deserializer) - .map(|hashmap| hashmap.into_iter().map(|(k, _)| k).collect()) - } -} - -/// Used to default the `bool` fields to `true` during deserialization. -pub fn default_true() -> bool { - true -} - -#[cfg(test)] -pub fn serde_json_eq(de: T, se: serde_json::Value) -where - T: Clone + Debug + PartialEq + Serialize + DeserializeOwned, -{ - assert_eq!(se, serde_json::to_value(de.clone()).unwrap()); - assert_eq!(de, serde_json::from_value(se).unwrap()); -} - // This would be #[cfg(test)] if it wasn't used from external tests pub fn serde_json_eq_try_from_raw(de: T, se: serde_json::Value) where