sync_events/get_message_events: ser/de filters to string
This commit is contained in:
parent
d94279efaf
commit
9b5b906868
@ -47,8 +47,12 @@ ruma_api! {
|
||||
#[ruma_api(query)]
|
||||
pub limit: Option<UInt>,
|
||||
/// A RoomEventFilter to filter returned events with.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[ruma_api(query)]
|
||||
#[serde(
|
||||
with = "crate::serde::json_string",
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none"
|
||||
)]
|
||||
pub filter: Option<RoomEventFilter>,
|
||||
}
|
||||
|
||||
@ -75,3 +79,80 @@ pub enum Direction {
|
||||
#[serde(rename = "f")]
|
||||
Forward,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Direction, Request};
|
||||
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
|
||||
use ruma_identifiers::RoomId;
|
||||
|
||||
use crate::r0::filter::{LazyLoadOptions, RoomEventFilter};
|
||||
|
||||
#[test]
|
||||
fn test_serialize_some_room_event_filter() {
|
||||
let room_id = RoomId::try_from("!roomid:example.org").unwrap();
|
||||
let filter = RoomEventFilter {
|
||||
lazy_load_options: LazyLoadOptions::Enabled {
|
||||
include_redundant_members: true,
|
||||
},
|
||||
rooms: Some(vec![room_id.clone()]),
|
||||
not_rooms: vec!["room".into(), "room2".into(), "room3".into()],
|
||||
not_types: vec!["type".into()],
|
||||
..Default::default()
|
||||
};
|
||||
let req = Request {
|
||||
room_id,
|
||||
from: "token".into(),
|
||||
to: Some("token2".into()),
|
||||
dir: Direction::Backward,
|
||||
limit: Some(js_int::UInt::min_value()),
|
||||
filter: Some(filter),
|
||||
};
|
||||
|
||||
let request: http::Request<Vec<u8>> = req.try_into().unwrap();
|
||||
assert_eq!(
|
||||
"from=token&to=token2&dir=b&limit=0&filter=%7B%22not_types%22%3A%5B%22type%22%5D%2C%22not_rooms%22%3A%5B%22room%22%2C%22room2%22%2C%22room3%22%5D%2C%22rooms%22%3A%5B%22%21roomid%3Aexample.org%22%5D%2C%22lazy_load_members%22%3Atrue%2C%22include_redundant_members%22%3Atrue%7D",
|
||||
request.uri().query().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_none_room_event_filter() {
|
||||
let room_id = RoomId::try_from("!roomid:example.org").unwrap();
|
||||
let req = Request {
|
||||
room_id,
|
||||
from: "token".into(),
|
||||
to: Some("token2".into()),
|
||||
dir: Direction::Backward,
|
||||
limit: Some(js_int::UInt::min_value()),
|
||||
filter: None,
|
||||
};
|
||||
|
||||
let request: http::Request<Vec<u8>> = req.try_into().unwrap();
|
||||
assert_eq!(
|
||||
"from=token&to=token2&dir=b&limit=0",
|
||||
request.uri().query().unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_default_room_event_filter() {
|
||||
let room_id = RoomId::try_from("!roomid:example.org").unwrap();
|
||||
let req = Request {
|
||||
room_id,
|
||||
from: "token".into(),
|
||||
to: Some("token2".into()),
|
||||
dir: Direction::Backward,
|
||||
limit: Some(js_int::UInt::min_value()),
|
||||
filter: Some(RoomEventFilter::default()),
|
||||
};
|
||||
|
||||
let request: http::Request<Vec<u8>> = req.try_into().unwrap();
|
||||
assert_eq!(
|
||||
"from=token&to=token2&dir=b&limit=0&filter=%7B%7D",
|
||||
request.uri().query().unwrap(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -122,39 +122,13 @@ pub enum Filter {
|
||||
// FilterDefinition is the first variant, JSON decoding is attempted first which is almost
|
||||
// functionally equivalent to looking at whether the first symbol is a '{' as the spec says.
|
||||
// (there are probably some corner cases like leading whitespace)
|
||||
#[serde(with = "filter_def_serde")]
|
||||
#[serde(with = "crate::serde::json_string")]
|
||||
/// A complete filter definition serialized to JSON.
|
||||
FilterDefinition(FilterDefinition),
|
||||
/// The ID of a filter saved on the server.
|
||||
FilterId(String),
|
||||
}
|
||||
|
||||
/// Serialization and deserialization logic for filter definitions.
|
||||
mod filter_def_serde {
|
||||
use serde::{de::Error as _, ser::Error as _, Deserialize, Deserializer, Serializer};
|
||||
|
||||
use crate::r0::filter::FilterDefinition;
|
||||
|
||||
/// Serialization logic for filter definitions.
|
||||
pub fn serialize<S>(filter_def: &FilterDefinition, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let string = serde_json::to_string(filter_def).map_err(S::Error::custom)?;
|
||||
serializer.serialize_str(&string)
|
||||
}
|
||||
|
||||
/// Deserialization logic for filter definitions.
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<FilterDefinition, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let filter_str = <&str>::deserialize(deserializer)?;
|
||||
|
||||
serde_json::from_str(filter_str).map_err(D::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
/// Updates to rooms.
|
||||
#[derive(Clone, Debug, Serialize, Outgoing)]
|
||||
pub struct Rooms {
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! Modules to hold functions for de-/serializing remote types
|
||||
|
||||
pub mod duration;
|
||||
pub mod json_string;
|
||||
|
||||
pub fn is_default<T: Default + PartialEq>(val: &T) -> bool {
|
||||
val == &T::default()
|
||||
|
24
src/serde/json_string.rs
Normal file
24
src/serde/json_string.rs
Normal file
@ -0,0 +1,24 @@
|
||||
//! De-/serialization functions to and from json strings, allows the type to be used as a query string.
|
||||
|
||||
use serde::{
|
||||
de::{Deserialize, DeserializeOwned, Deserializer, Error as _},
|
||||
ser::{Error as _, Serialize, Serializer},
|
||||
};
|
||||
|
||||
pub fn serialize<T, S>(filter: T, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
T: Serialize,
|
||||
S: Serializer,
|
||||
{
|
||||
let json = serde_json::to_string(&filter).map_err(S::Error::custom)?;
|
||||
serializer.serialize_str(&json)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
serde_json::from_str(&s).map_err(D::Error::custom)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user