events: Optimize deserialization helpers

This commit is contained in:
Jonas Platte 2021-08-12 20:46:15 +02:00
parent 4e72c374b9
commit 3b0afb520a
No known key found for this signature in database
GPG Key ID: CC154DE0E30B7C67
3 changed files with 36 additions and 38 deletions

View File

@ -161,10 +161,10 @@ fn expand_any_with_deser(
use #serde::de::Error as _; use #serde::de::Error as _;
let json = Box::<#serde_json::value::RawValue>::deserialize(deserializer)?; let json = Box::<#serde_json::value::RawValue>::deserialize(deserializer)?;
let #ruma_events::EventDeHelper { ev_type, .. } = let #ruma_events::EventTypeDeHelper { ev_type, .. } =
#ruma_events::from_raw_json_value(&json)?; #ruma_events::from_raw_json_value(&json)?;
match ev_type.as_str() { match &*ev_type {
#( #(
#variant_attrs #events => { #variant_attrs #events => {
let event = #serde_json::from_str::<#content>(json.get()) let event = #serde_json::from_str::<#content>(json.get())
@ -609,7 +609,7 @@ fn expand_redacted_enum(
D: #serde::de::Deserializer<'de>, D: #serde::de::Deserializer<'de>,
{ {
let json = Box::<#serde_json::value::RawValue>::deserialize(deserializer)?; let json = Box::<#serde_json::value::RawValue>::deserialize(deserializer)?;
let #ruma_events::EventDeHelper { unsigned, .. } = let #ruma_events::RedactionDeHelper { unsigned } =
#ruma_events::from_raw_json_value(&json)?; #ruma_events::from_raw_json_value(&json)?;
Ok(match unsigned { Ok(match unsigned {

View File

@ -1,10 +1,10 @@
use ruma_common::MilliSecondsSinceUnixEpoch; use ruma_common::MilliSecondsSinceUnixEpoch;
use ruma_events_macros::event_enum; use ruma_events_macros::event_enum;
use ruma_identifiers::{EventId, RoomId, RoomVersionId, UserId}; use ruma_identifiers::{EventId, RoomId, RoomVersionId, UserId};
use serde::{de, Serialize}; use serde::{de, Deserialize, Serialize};
use serde_json::value::RawValue as RawJsonValue; use serde_json::value::RawValue as RawJsonValue;
use crate::{from_raw_json_value, room::redaction::SyncRedactionEvent, EventDeHelper, Redact}; use crate::{from_raw_json_value, room::redaction::SyncRedactionEvent, Redact, UnsignedDeHelper};
event_enum! { event_enum! {
/// Any global account data event. /// Any global account data event.
@ -197,13 +197,20 @@ impl AnySyncRoomEvent {
} }
} }
impl<'de> de::Deserialize<'de> for AnyRoomEvent { #[derive(Deserialize)]
#[allow(clippy::exhaustive_structs)]
struct EventDeHelper {
pub state_key: Option<de::IgnoredAny>,
pub unsigned: Option<UnsignedDeHelper>,
}
impl<'de> Deserialize<'de> for AnyRoomEvent {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
D: de::Deserializer<'de>, D: de::Deserializer<'de>,
{ {
let json = Box::<RawJsonValue>::deserialize(deserializer)?; let json = Box::<RawJsonValue>::deserialize(deserializer)?;
let EventDeHelper { state_key, unsigned, .. } = from_raw_json_value(&json)?; let EventDeHelper { state_key, unsigned } = from_raw_json_value(&json)?;
if state_key.is_some() { if state_key.is_some() {
Ok(match unsigned { Ok(match unsigned {
@ -223,13 +230,13 @@ impl<'de> de::Deserialize<'de> for AnyRoomEvent {
} }
} }
impl<'de> de::Deserialize<'de> for AnySyncRoomEvent { impl<'de> Deserialize<'de> for AnySyncRoomEvent {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
D: de::Deserializer<'de>, D: de::Deserializer<'de>,
{ {
let json = Box::<RawJsonValue>::deserialize(deserializer)?; let json = Box::<RawJsonValue>::deserialize(deserializer)?;
let EventDeHelper { state_key, unsigned, .. } = from_raw_json_value(&json)?; let EventDeHelper { state_key, unsigned } = from_raw_json_value(&json)?;
if state_key.is_some() { if state_key.is_some() {
Ok(match unsigned { Ok(match unsigned {

View File

@ -430,45 +430,36 @@ pub enum HasDeserializeFields {
Optional, Optional,
} }
/// Helper struct to determine if the event has been redacted. /// Helper struct to determine the event kind from a `serde_json::value::RawValue`.
#[doc(hidden)] #[doc(hidden)]
#[derive(Debug, Deserialize)] #[derive(Deserialize)]
#[allow(clippy::exhaustive_structs)]
pub struct EventTypeDeHelper<'a> {
#[serde(borrow, rename = "type")]
pub ev_type: std::borrow::Cow<'a, str>,
}
/// Helper struct to determine if an event has been redacted.
#[doc(hidden)]
#[derive(Deserialize)]
pub struct RedactionDeHelper {
/// Used to check whether redacted_because exists.
pub unsigned: Option<UnsignedDeHelper>,
}
#[doc(hidden)]
#[derive(Deserialize)]
#[allow(clippy::exhaustive_structs)] #[allow(clippy::exhaustive_structs)]
pub struct UnsignedDeHelper { pub struct UnsignedDeHelper {
/// This is the field that signals an event has been redacted. /// This is the field that signals an event has been redacted.
pub redacted_because: Option<IgnoredAny>, pub redacted_because: Option<IgnoredAny>,
} }
/// Helper struct to determine the event kind from a `serde_json::value::RawValue`.
#[doc(hidden)]
#[derive(Debug, Deserialize)]
#[allow(clippy::exhaustive_structs)]
pub struct EventDeHelper {
/// the Matrix event type string "m.room.whatever".
#[serde(rename = "type")]
pub ev_type: String,
/// If `state_key` is present the event will be deserialized as a state event.
pub state_key: Option<IgnoredAny>,
/// If no `state_key` is found but an `event_id` is present the event
/// will be deserialized as a message event.
pub event_id: Option<IgnoredAny>,
/// If no `event_id` or `state_key` are found but a `room_id` is present
/// the event will be deserialized as an ephemeral event.
pub room_id: Option<IgnoredAny>,
/// If this `UnsignedData` contains a `redacted_because` key the event is
/// immediately deserialized as a redacted event.
pub unsigned: Option<UnsignedDeHelper>,
}
/// Helper function for `serde_json::value::RawValue` deserialization. /// Helper function for `serde_json::value::RawValue` deserialization.
#[doc(hidden)] #[doc(hidden)]
pub fn from_raw_json_value<T, E>(val: &RawJsonValue) -> Result<T, E> pub fn from_raw_json_value<'a, T, E>(val: &'a RawJsonValue) -> Result<T, E>
where where
T: de::DeserializeOwned, T: de::Deserialize<'a>,
E: de::Error, E: de::Error,
{ {
serde_json::from_str(val.get()).map_err(E::custom) serde_json::from_str(val.get()).map_err(E::custom)