diff --git a/ruma-client-api/src/r0/filter.rs b/ruma-client-api/src/r0/filter.rs index 62cfc8da..8ae4519b 100644 --- a/ruma-client-api/src/r0/filter.rs +++ b/ruma-client-api/src/r0/filter.rs @@ -390,11 +390,12 @@ can_be_empty!(IncomingRoomFilter); #[cfg(test)] mod tests { + use matches::assert_matches; use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; use super::{ - Filter, FilterDefinition, IncomingFilterDefinition, IncomingRoomFilter, RoomEventFilter, - RoomFilter, + Filter, FilterDefinition, IncomingFilterDefinition, IncomingRoomEventFilter, + IncomingRoomFilter, LazyLoadOptions, RoomEventFilter, RoomFilter, UrlFilter, }; #[test] @@ -428,4 +429,39 @@ mod tests { Ok(()) } + + #[test] + fn issue_218() -> Result<(), serde_json::Error> { + let obj = json!({ + "lazy_load_members": true, + "filter_json": { "contains_url": true, "types": ["m.room.message"] }, + "types": ["m.room.message"], + "not_types": [], + "rooms": null, + "not_rooms": [], + "senders": null, + "not_senders": [], + "contains_url": true, + }); + + assert_matches!( + from_json_value(obj)?, + IncomingRoomEventFilter { + types: Some(types), + not_types, + rooms: None, + not_rooms, + senders: None, + not_senders, + limit: None, + url_filter: Some(UrlFilter::EventsWithUrl), + lazy_load_options: LazyLoadOptions::Enabled { include_redundant_members: false }, + } if types == vec!["m.room.message".to_owned()] + && not_types.is_empty() + && not_rooms.is_empty() + && not_senders.is_empty() + ); + + Ok(()) + } } diff --git a/ruma-client-api/src/r0/filter/lazy_load.rs b/ruma-client-api/src/r0/filter/lazy_load.rs index e5286ae8..934e8182 100644 --- a/ruma-client-api/src/r0/filter/lazy_load.rs +++ b/ruma-client-api/src/r0/filter/lazy_load.rs @@ -1,15 +1,11 @@ -use std::fmt; - -use serde::{ - de::{Deserialize, Deserializer, MapAccess, Visitor}, - ser::{Serialize, SerializeStruct as _, Serializer}, -}; +use serde::{ser::SerializeStruct as _, Deserialize, Serialize, Serializer}; /// Specifies options for [lazy-loading membership events][lazy-loading] on /// supported endpoints /// /// [lazy-loading]: https://matrix.org/docs/spec/client_server/r0.6.0#lazy-loading-room-members -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize)] +#[serde(from = "LazyLoadJsonRepr")] pub enum LazyLoadOptions { /// Disables lazy-loading of membership events. Disabled, @@ -52,7 +48,7 @@ impl Serialize for LazyLoadOptions { state = serializer.serialize_struct("LazyLoad", 1)?; state.serialize_field("lazy_load_members", &true)?; } - _ => { + Self::Disabled => { state = serializer.serialize_struct("LazyLoad", 0)?; } } @@ -60,43 +56,21 @@ impl Serialize for LazyLoadOptions { } } -struct LazyLoadOptionsVisitor; - -impl<'de> Visitor<'de> for LazyLoadOptionsVisitor { - type Value = LazyLoadOptions; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("Lazy load options") - } - - fn visit_map(self, mut access: M) -> Result - where - M: MapAccess<'de>, - { - let mut lazy_load_members = false; - let mut include_redundant_members = false; - while let Some((key, value)) = access.next_entry::()? { - match &*key { - "lazy_load_members" => lazy_load_members = value, - "include_redundant_members" => include_redundant_members = value, - _ => {} - }; - } - - Ok(if lazy_load_members { - LazyLoadOptions::Enabled { include_redundant_members } - } else { - LazyLoadOptions::Disabled - }) - } +#[derive(Deserialize)] +struct LazyLoadJsonRepr { + lazy_load_members: Option, + include_redundant_members: Option, } -impl<'de> Deserialize<'de> for LazyLoadOptions { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_map(LazyLoadOptionsVisitor) +impl From for LazyLoadOptions { + fn from(opts: LazyLoadJsonRepr) -> Self { + if opts.lazy_load_members.unwrap_or(false) { + Self::Enabled { + include_redundant_members: opts.include_redundant_members.unwrap_or(false), + } + } else { + Self::Disabled + } } }