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