Update ruma_serde to 0.1.2

This commit is contained in:
Jonas Platte 2020-04-30 18:07:20 +02:00
parent fd5527da78
commit 0d305d8f24
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
14 changed files with 30 additions and 170 deletions

View File

@ -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"] }

View File

@ -64,10 +64,10 @@ impl From<Algorithm> 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() {

View File

@ -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.

View File

@ -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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_map(Some(0))?.end()
}
}
impl<'de> Deserialize<'de> for Empty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
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<A>(self, _map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
Ok(Empty)
}
}
deserializer.deserialize_map(EmptyMapVisitor)
}
}
impl FromRaw for Empty {
type Raw = Self;
fn from_raw(raw: Self) -> Self {
raw
}
}

View File

@ -269,10 +269,10 @@ impl From<EventType> 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]

View File

@ -27,6 +27,14 @@ pub trait TryFromRaw: Sized {
fn try_from_raw(_: Self::Raw) -> Result<Self, Self::Err>;
}
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;

View File

@ -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<UserId>,
}
@ -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<UserId>,
}
}

View File

@ -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;

View File

@ -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,
},
}

View File

@ -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<RoomAliasId>,

View File

@ -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.

View File

@ -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<String>,
}
}

View File

@ -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

View File

@ -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<Option<T>, D::Error>
where
D: serde::Deserializer<'de>,
T: serde::Deserialize<'de>,
{
let opt = Option::<String>::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<T>` to a `BTreeMap<T, Empty>`.
///
/// 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<S, T>(vec: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: Serialize + Eq + Ord,
{
vec.iter()
.map(|v| (v, Empty))
.collect::<BTreeMap<_, _>>()
.serialize(serializer)
}
pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
where
D: Deserializer<'de>,
T: Deserialize<'de> + Eq + Ord,
{
BTreeMap::<T, Empty>::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<T>(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<T>(de: T, se: serde_json::Value)
where