pub mod create_filter;
pub mod get_filter;
use std::fmt;
use js_int::UInt;
use ruma_identifiers::{RoomId, UserId};
use serde::{
de::{MapAccess, Visitor},
ser::SerializeStruct,
Deserialize, Deserializer, Serialize, Serializer,
};
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum EventFormat {
Client,
Federation,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct RoomEventFilter {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub not_types: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub not_rooms: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<UInt>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub rooms: Option<Vec<RoomId>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub not_senders: Vec<UserId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub senders: Option<Vec<UserId>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub types: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contains_url: Option<bool>,
#[serde(flatten)]
pub lazy_load_options: LazyLoadOptions,
}
impl RoomEventFilter {
pub fn ignore_all() -> Self {
Self {
types: Some(vec![]),
..Default::default()
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct RoomFilter {
#[serde(skip_serializing_if = "Option::is_none")]
pub include_leave: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub account_data: Option<RoomEventFilter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timeline: Option<RoomEventFilter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ephemeral: Option<RoomEventFilter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub state: Option<RoomEventFilter>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub not_rooms: Vec<RoomId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub rooms: Option<Vec<RoomId>>,
}
impl RoomFilter {
pub fn ignore_all() -> Self {
Self {
rooms: Some(vec![]),
..Default::default()
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Filter {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub not_types: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<UInt>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub senders: Option<Vec<UserId>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub types: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub not_senders: Vec<UserId>,
}
impl Filter {
pub fn ignore_all() -> Self {
Self {
types: Some(vec![]),
..Default::default()
}
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct FilterDefinition {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub event_fields: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub event_format: Option<EventFormat>,
#[serde(skip_serializing_if = "Option::is_none")]
pub account_data: Option<Filter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub room: Option<RoomFilter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub presence: Option<Filter>,
}
impl FilterDefinition {
pub fn ignore_all() -> Self {
Self {
account_data: Some(Filter::ignore_all()),
room: Some(RoomFilter::ignore_all()),
presence: Some(Filter::ignore_all()),
..Default::default()
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LazyLoadOptions {
Disabled,
Enabled {
include_redundant_members: bool,
},
}
impl Serialize for LazyLoadOptions {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
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<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut lazy_load_members = false;
let mut include_redundant_members = false;
while let Some((key, value)) = access.next_entry::<String, bool>()? {
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<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(LazyLoadOptionsVisitor)
}
}
#[cfg(test)]
mod tests {
use serde_json::json;
use super::LazyLoadOptions;
#[test]
fn test_serializing_disabled_lazy_load() {
let lazy_load_options = LazyLoadOptions::Disabled;
assert_eq!(serde_json::to_value(lazy_load_options).unwrap(), json!({}));
}
#[test]
fn test_serializing_lazy_load_no_redundant() {
let lazy_load_options = LazyLoadOptions::Enabled {
include_redundant_members: false,
};
assert_eq!(
serde_json::to_value(lazy_load_options).unwrap(),
json!({ "lazy_load_members": true })
);
}
#[test]
fn test_serializing_lazy_load_with_redundant() {
let lazy_load_options = LazyLoadOptions::Enabled {
include_redundant_members: true,
};
assert_eq!(
serde_json::to_value(lazy_load_options).unwrap(),
json!({ "lazy_load_members": true, "include_redundant_members": true })
);
}
#[test]
fn test_deserializing_no_lazy_load() {
let json = json!({});
assert_eq!(
serde_json::from_value::<LazyLoadOptions>(json).unwrap(),
LazyLoadOptions::Disabled,
);
}
#[test]
fn test_deserializing_ignore_redundant_members_when_no_lazy_load() {
let json = json!({ "include_redundant_members": true });
assert_eq!(
serde_json::from_value::<LazyLoadOptions>(json).unwrap(),
LazyLoadOptions::Disabled,
);
}
}