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)]
|
#[ruma_api(query)]
|
||||||
pub limit: Option<UInt>,
|
pub limit: Option<UInt>,
|
||||||
/// A RoomEventFilter to filter returned events with.
|
/// A RoomEventFilter to filter returned events with.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
#[ruma_api(query)]
|
#[ruma_api(query)]
|
||||||
|
#[serde(
|
||||||
|
with = "crate::serde::json_string",
|
||||||
|
default,
|
||||||
|
skip_serializing_if = "Option::is_none"
|
||||||
|
)]
|
||||||
pub filter: Option<RoomEventFilter>,
|
pub filter: Option<RoomEventFilter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,3 +79,80 @@ pub enum Direction {
|
|||||||
#[serde(rename = "f")]
|
#[serde(rename = "f")]
|
||||||
Forward,
|
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
|
// 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.
|
// functionally equivalent to looking at whether the first symbol is a '{' as the spec says.
|
||||||
// (there are probably some corner cases like leading whitespace)
|
// (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.
|
/// A complete filter definition serialized to JSON.
|
||||||
FilterDefinition(FilterDefinition),
|
FilterDefinition(FilterDefinition),
|
||||||
/// The ID of a filter saved on the server.
|
/// The ID of a filter saved on the server.
|
||||||
FilterId(String),
|
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.
|
/// Updates to rooms.
|
||||||
#[derive(Clone, Debug, Serialize, Outgoing)]
|
#[derive(Clone, Debug, Serialize, Outgoing)]
|
||||||
pub struct Rooms {
|
pub struct Rooms {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Modules to hold functions for de-/serializing remote types
|
//! Modules to hold functions for de-/serializing remote types
|
||||||
|
|
||||||
pub mod duration;
|
pub mod duration;
|
||||||
|
pub mod json_string;
|
||||||
|
|
||||||
pub fn is_default<T: Default + PartialEq>(val: &T) -> bool {
|
pub fn is_default<T: Default + PartialEq>(val: &T) -> bool {
|
||||||
val == &T::default()
|
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