diff --git a/crates/ruma-common/src/directory.rs b/crates/ruma-common/src/directory.rs index b31ba7a2..d6d34fda 100644 --- a/crates/ruma-common/src/directory.rs +++ b/crates/ruma-common/src/directory.rs @@ -109,7 +109,7 @@ impl From for PublicRoomsChunk { } } -/// A filter for public rooms lists +/// A filter for public rooms lists. #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] pub struct Filter { @@ -121,6 +121,7 @@ pub struct Filter { /// /// Includes all room types if it is empty. #[serde(default, skip_serializing_if = "Vec::is_empty")] + #[cfg_attr(feature = "compat", serde(deserialize_with = "crate::serde::none_as_default"))] pub room_types: Vec, } diff --git a/crates/ruma-common/src/serde.rs b/crates/ruma-common/src/serde.rs index 28e4b81d..06475ede 100644 --- a/crates/ruma-common/src/serde.rs +++ b/crates/ruma-common/src/serde.rs @@ -5,7 +5,7 @@ //! //! [serde_urlencoded]: https://github.com/nox/serde_urlencoded -use serde::{de, Deserialize}; +use serde::{de, Deserialize, Deserializer}; use serde_json::{value::RawValue as RawJsonValue, Value as JsonValue}; pub mod base64; @@ -40,6 +40,15 @@ pub fn is_default(val: &T) -> bool { *val == T::default() } +/// Deserialize a `T` via `Option`, falling back to `T::default()`. +pub fn none_as_default<'de, D, T>(deserializer: D) -> Result +where + D: Deserializer<'de>, + T: Default + Deserialize<'de>, +{ + Ok(Option::deserialize(deserializer)?.unwrap_or_default()) +} + /// Simply returns `true`. /// /// Useful for `#[serde(default = ...)]`.