diff --git a/ruma-client-api/src/r0/filter.rs b/ruma-client-api/src/r0/filter.rs index 3355553f..274fd6ca 100644 --- a/ruma-client-api/src/r0/filter.rs +++ b/ruma-client-api/src/r0/filter.rs @@ -3,16 +3,16 @@ pub mod create_filter; pub mod get_filter; -use std::fmt; +mod lazy_load; +mod url; + +pub use lazy_load::LazyLoadOptions; +pub use url::UrlFilter; use js_int::UInt; use ruma_common::Outgoing; use ruma_identifiers::{RoomId, UserId}; -use serde::{ - de::{MapAccess, Visitor}, - ser::SerializeStruct, - Deserialize, Deserializer, Serialize, Serializer, -}; +use serde::{Deserialize, Serialize}; /// Format to use for returned events #[derive(Copy, Clone, Debug, Deserialize, Serialize)] @@ -25,40 +25,6 @@ pub enum EventFormat { Federation, } -/// Options for filtering based on the presence of a URL. -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum UrlFilter { - /// Includes only events with a url key in their content. - EventsWithUrl, - - /// Excludes events with a url key in their content. - EventsWithoutUrl, -} - -impl Serialize for UrlFilter { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - match *self { - Self::EventsWithUrl => serializer.serialize_bool(true), - Self::EventsWithoutUrl => serializer.serialize_bool(false), - } - } -} - -impl<'de> Deserialize<'de> for UrlFilter { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Ok(match bool::deserialize(deserializer)? { - true => Self::EventsWithUrl, - false => Self::EventsWithoutUrl, - }) - } -} - /// Filters to be applied to room events #[derive(Clone, Copy, Debug, Default, Outgoing, Serialize)] #[incoming_derive(Clone, Serialize)] @@ -266,154 +232,3 @@ impl<'a> FilterDefinition<'a> { } } } - -/// 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)] -pub enum LazyLoadOptions { - /// Disables lazy-loading of membership events. - Disabled, - - /// Enables lazy-loading of events. - Enabled { - /// If `true`, sends all membership events for all events, even if they have - /// already been sent to the client. Defaults to `false`. - include_redundant_members: bool, - }, -} - -impl Serialize for LazyLoadOptions { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut state; - match *self { - Self::Enabled { include_redundant_members: true } => { - state = serializer.serialize_struct("LazyLoad", 2)?; - state.serialize_field("lazy_load_members", &true)?; - state.serialize_field("include_redundant_members", &true)?; - } - Self::Enabled { .. } => { - state = serializer.serialize_struct("LazyLoad", 1)?; - state.serialize_field("lazy_load_members", &true)?; - } - _ => { - state = serializer.serialize_struct("LazyLoad", 0)?; - } - } - state.end() - } -} - -impl Default for LazyLoadOptions { - fn default() -> Self { - Self::Disabled - } -} - -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 - }) - } -} - -impl<'de> Deserialize<'de> for LazyLoadOptions { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_map(LazyLoadOptionsVisitor) - } -} - -#[cfg(test)] -mod tests { - use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; - - use super::{LazyLoadOptions, UrlFilter}; - - #[test] - fn serialize_contains_url_filter_events_with_url() { - let events_with_url = UrlFilter::EventsWithUrl; - assert_eq!(to_json_value(events_with_url).unwrap(), json!(true)) - } - - #[test] - fn serialize_contains_url_filter_events_without_url() { - let events_without_url = UrlFilter::EventsWithoutUrl; - assert_eq!(to_json_value(events_without_url).unwrap(), json!(false)) - } - - #[test] - fn deserialize_contains_url_true() { - let json = json!(true); - assert_eq!(from_json_value::(json).unwrap(), UrlFilter::EventsWithUrl); - } - - #[test] - fn deserialize_contains_url_false() { - let json = json!(false); - assert_eq!(from_json_value::(json).unwrap(), UrlFilter::EventsWithoutUrl); - } - - #[test] - fn serialize_disabled_lazy_load() { - let lazy_load_options = LazyLoadOptions::Disabled; - assert_eq!(to_json_value(lazy_load_options).unwrap(), json!({})); - } - - #[test] - fn serialize_lazy_load_no_redundant() { - let lazy_load_options = LazyLoadOptions::Enabled { include_redundant_members: false }; - assert_eq!(to_json_value(lazy_load_options).unwrap(), json!({ "lazy_load_members": true })); - } - - #[test] - fn serialize_lazy_load_with_redundant() { - let lazy_load_options = LazyLoadOptions::Enabled { include_redundant_members: true }; - assert_eq!( - to_json_value(lazy_load_options).unwrap(), - json!({ "lazy_load_members": true, "include_redundant_members": true }) - ); - } - - #[test] - fn deserialize_no_lazy_load() { - let json = json!({}); - assert_eq!(from_json_value::(json).unwrap(), LazyLoadOptions::Disabled,); - } - - #[test] - fn deserialize_ignore_redundant_members_when_no_lazy_load() { - let json = json!({ "include_redundant_members": true }); - assert_eq!(from_json_value::(json).unwrap(), LazyLoadOptions::Disabled,); - } -} diff --git a/ruma-client-api/src/r0/filter/lazy_load.rs b/ruma-client-api/src/r0/filter/lazy_load.rs new file mode 100644 index 00000000..a8077981 --- /dev/null +++ b/ruma-client-api/src/r0/filter/lazy_load.rs @@ -0,0 +1,130 @@ +use std::fmt; + +use serde::{ + de::{Deserialize, Deserializer, MapAccess, Visitor}, + ser::{Serialize, SerializeStruct as _, 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)] +pub enum LazyLoadOptions { + /// Disables lazy-loading of membership events. + Disabled, + + /// Enables lazy-loading of events. + Enabled { + /// If `true`, sends all membership events for all events, even if they have + /// already been sent to the client. Defaults to `false`. + include_redundant_members: bool, + }, +} + +impl Serialize for LazyLoadOptions { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state; + match *self { + Self::Enabled { include_redundant_members: true } => { + state = serializer.serialize_struct("LazyLoad", 2)?; + state.serialize_field("lazy_load_members", &true)?; + state.serialize_field("include_redundant_members", &true)?; + } + Self::Enabled { .. } => { + state = serializer.serialize_struct("LazyLoad", 1)?; + state.serialize_field("lazy_load_members", &true)?; + } + _ => { + state = serializer.serialize_struct("LazyLoad", 0)?; + } + } + state.end() + } +} + +impl Default for LazyLoadOptions { + fn default() -> Self { + Self::Disabled + } +} + +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 + }) + } +} + +impl<'de> Deserialize<'de> for LazyLoadOptions { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_map(LazyLoadOptionsVisitor) + } +} + +#[cfg(test)] +mod tests { + use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; + + use super::LazyLoadOptions; + + #[test] + fn serialize_disabled() { + let lazy_load_options = LazyLoadOptions::Disabled; + assert_eq!(to_json_value(lazy_load_options).unwrap(), json!({})); + } + + #[test] + fn serialize_no_redundant() { + let lazy_load_options = LazyLoadOptions::Enabled { include_redundant_members: false }; + assert_eq!(to_json_value(lazy_load_options).unwrap(), json!({ "lazy_load_members": true })); + } + + #[test] + fn serialize_with_redundant() { + let lazy_load_options = LazyLoadOptions::Enabled { include_redundant_members: true }; + assert_eq!( + to_json_value(lazy_load_options).unwrap(), + json!({ "lazy_load_members": true, "include_redundant_members": true }) + ); + } + + #[test] + fn deserialize_no_lazy_load() { + let json = json!({}); + assert_eq!(from_json_value::(json).unwrap(), LazyLoadOptions::Disabled); + + let json = json!({ "include_redundant_members": true }); + assert_eq!(from_json_value::(json).unwrap(), LazyLoadOptions::Disabled); + } +} diff --git a/ruma-client-api/src/r0/filter/url.rs b/ruma-client-api/src/r0/filter/url.rs new file mode 100644 index 00000000..3def41cf --- /dev/null +++ b/ruma-client-api/src/r0/filter/url.rs @@ -0,0 +1,69 @@ +use serde::{ + de::{Deserialize, Deserializer}, + ser::{Serialize, Serializer}, +}; + +/// Options for filtering based on the presence of a URL. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum UrlFilter { + /// Includes only events with a url key in their content. + EventsWithUrl, + + /// Excludes events with a url key in their content. + EventsWithoutUrl, +} + +impl Serialize for UrlFilter { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match *self { + Self::EventsWithUrl => serializer.serialize_bool(true), + Self::EventsWithoutUrl => serializer.serialize_bool(false), + } + } +} + +impl<'de> Deserialize<'de> for UrlFilter { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Ok(match bool::deserialize(deserializer)? { + true => Self::EventsWithUrl, + false => Self::EventsWithoutUrl, + }) + } +} + +#[cfg(test)] +mod tests { + use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; + + use super::UrlFilter; + + #[test] + fn serialize_filter_events_with_url() { + let events_with_url = UrlFilter::EventsWithUrl; + assert_eq!(to_json_value(events_with_url).unwrap(), json!(true)) + } + + #[test] + fn serialize_filter_events_without_url() { + let events_without_url = UrlFilter::EventsWithoutUrl; + assert_eq!(to_json_value(events_without_url).unwrap(), json!(false)) + } + + #[test] + fn deserialize_filter_events_with_url() { + let json = json!(true); + assert_eq!(from_json_value::(json).unwrap(), UrlFilter::EventsWithUrl); + } + + #[test] + fn deserialize_filter_events_without_url() { + let json = json!(false); + assert_eq!(from_json_value::(json).unwrap(), UrlFilter::EventsWithoutUrl); + } +}