Refactor collection deserialization

This commit is contained in:
Jonas Platte 2019-10-23 02:24:07 +02:00
parent 1689b09a05
commit 09378eb410
4 changed files with 160 additions and 326 deletions

View File

@ -2,7 +2,7 @@
//! the trait of the same name. //! the trait of the same name.
use serde::{de::Error as _, Deserialize, Deserializer}; use serde::{de::Error as _, Deserialize, Deserializer};
use serde_json::{from_value, Value}; use serde_json::Value;
use crate::{ use crate::{
call::{ call::{
@ -47,7 +47,7 @@ use crate::{
sticker::raw::StickerEvent, sticker::raw::StickerEvent,
tag::raw::TagEvent, tag::raw::TagEvent,
typing::raw::TypingEvent, typing::raw::TypingEvent,
util::{get_field, serde_json_error_to_generic_de_error as conv_err}, util::get_field,
CustomEvent, CustomRoomEvent, CustomStateEvent, EventType, CustomEvent, CustomRoomEvent, CustomStateEvent, EventType,
}; };
@ -341,101 +341,56 @@ impl<'de> Deserialize<'de> for Event {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
use crate::util::try_variant_from_value as from_value;
use EventType::*; use EventType::*;
let value = Value::deserialize(deserializer)?; let value = Value::deserialize(deserializer)?;
let event_type = get_field(&value, "type")?; let event_type = get_field(&value, "type")?;
match event_type { match event_type {
CallAnswer => from_value(value).map(Event::CallAnswer).map_err(conv_err), CallAnswer => from_value(value, Event::CallAnswer),
CallCandidates => from_value(value) CallCandidates => from_value(value, Event::CallCandidates),
.map(Event::CallCandidates) CallHangup => from_value(value, Event::CallHangup),
.map_err(conv_err), CallInvite => from_value(value, Event::CallInvite),
CallHangup => from_value(value).map(Event::CallHangup).map_err(conv_err), Direct => from_value(value, Event::Direct),
CallInvite => from_value(value).map(Event::CallInvite).map_err(conv_err), Dummy => from_value(value, Event::Dummy),
Direct => from_value(value).map(Event::Direct).map_err(conv_err), ForwardedRoomKey => from_value(value, Event::ForwardedRoomKey),
Dummy => from_value(value).map(Event::Dummy).map_err(conv_err), FullyRead => from_value(value, Event::FullyRead),
ForwardedRoomKey => from_value(value) IgnoredUserList => from_value(value, Event::IgnoredUserList),
.map(Event::ForwardedRoomKey) KeyVerificationAccept => from_value(value, Event::KeyVerificationAccept),
.map_err(conv_err), KeyVerificationCancel => from_value(value, Event::KeyVerificationCancel),
FullyRead => from_value(value).map(Event::FullyRead).map_err(conv_err), KeyVerificationKey => from_value(value, Event::KeyVerificationKey),
IgnoredUserList => from_value(value) KeyVerificationMac => from_value(value, Event::KeyVerificationMac),
.map(Event::IgnoredUserList) KeyVerificationRequest => from_value(value, Event::KeyVerificationRequest),
.map_err(conv_err), KeyVerificationStart => from_value(value, Event::KeyVerificationStart),
KeyVerificationAccept => from_value(value) Presence => from_value(value, Event::Presence),
.map(Event::KeyVerificationAccept) PushRules => from_value(value, Event::PushRules),
.map_err(conv_err), Receipt => from_value(value, Event::Receipt),
KeyVerificationCancel => from_value(value) RoomAliases => from_value(value, Event::RoomAliases),
.map(Event::KeyVerificationCancel) RoomAvatar => from_value(value, Event::RoomAvatar),
.map_err(conv_err), RoomCanonicalAlias => from_value(value, Event::RoomCanonicalAlias),
KeyVerificationKey => from_value(value) RoomCreate => from_value(value, Event::RoomCreate),
.map(Event::KeyVerificationKey) RoomEncrypted => from_value(value, Event::RoomEncrypted),
.map_err(conv_err), RoomEncryption => from_value(value, Event::RoomEncryption),
KeyVerificationMac => from_value(value) RoomGuestAccess => from_value(value, Event::RoomGuestAccess),
.map(Event::KeyVerificationMac) RoomHistoryVisibility => from_value(value, Event::RoomHistoryVisibility),
.map_err(conv_err), RoomJoinRules => from_value(value, Event::RoomJoinRules),
KeyVerificationRequest => from_value(value) RoomMember => from_value(value, Event::RoomMember),
.map(Event::KeyVerificationRequest) RoomMessage => from_value(value, Event::RoomMessage),
.map_err(conv_err), RoomMessageFeedback => from_value(value, Event::RoomMessageFeedback),
KeyVerificationStart => from_value(value) RoomName => from_value(value, Event::RoomName),
.map(Event::KeyVerificationStart) RoomPinnedEvents => from_value(value, Event::RoomPinnedEvents),
.map_err(conv_err), RoomPowerLevels => from_value(value, Event::RoomPowerLevels),
Presence => from_value(value).map(Event::Presence).map_err(conv_err), RoomRedaction => from_value(value, Event::RoomRedaction),
PushRules => from_value(value).map(Event::PushRules).map_err(conv_err), RoomServerAcl => from_value(value, Event::RoomServerAcl),
Receipt => from_value(value).map(Event::Receipt).map_err(conv_err), RoomThirdPartyInvite => from_value(value, Event::RoomThirdPartyInvite),
RoomAliases => from_value(value).map(Event::RoomAliases).map_err(conv_err), RoomTombstone => from_value(value, Event::RoomTombstone),
RoomAvatar => from_value(value).map(Event::RoomAvatar).map_err(conv_err), RoomTopic => from_value(value, Event::RoomTopic),
RoomCanonicalAlias => from_value(value) RoomKey => from_value(value, Event::RoomKey),
.map(Event::RoomCanonicalAlias) RoomKeyRequest => from_value(value, Event::RoomKeyRequest),
.map_err(conv_err), Sticker => from_value(value, Event::Sticker),
RoomCreate => from_value(value).map(Event::RoomCreate).map_err(conv_err), Tag => from_value(value, Event::Tag),
RoomEncrypted => from_value(value) Typing => from_value(value, Event::Typing),
.map(Event::RoomEncrypted)
.map_err(conv_err),
RoomEncryption => from_value(value)
.map(Event::RoomEncryption)
.map_err(conv_err),
RoomGuestAccess => from_value(value)
.map(Event::RoomGuestAccess)
.map_err(conv_err),
RoomHistoryVisibility => from_value(value)
.map(Event::RoomHistoryVisibility)
.map_err(conv_err),
RoomJoinRules => from_value(value)
.map(Event::RoomJoinRules)
.map_err(conv_err),
RoomMember => from_value(value).map(Event::RoomMember).map_err(conv_err),
RoomMessage => from_value(value).map(Event::RoomMessage).map_err(conv_err),
RoomMessageFeedback => from_value(value)
.map(Event::RoomMessageFeedback)
.map_err(conv_err),
RoomName => from_value(value).map(Event::RoomName).map_err(conv_err),
RoomPinnedEvents => from_value(value)
.map(Event::RoomPinnedEvents)
.map_err(conv_err),
RoomPowerLevels => from_value(value)
.map(Event::RoomPowerLevels)
.map_err(conv_err),
RoomRedaction => from_value(value)
.map(Event::RoomRedaction)
.map_err(conv_err),
RoomServerAcl => from_value(value)
.map(Event::RoomServerAcl)
.map_err(conv_err),
RoomThirdPartyInvite => from_value(value)
.map(Event::RoomThirdPartyInvite)
.map_err(conv_err),
RoomTombstone => from_value(value)
.map(Event::RoomTombstone)
.map_err(conv_err),
RoomTopic => from_value(value).map(Event::RoomTopic).map_err(conv_err),
RoomKey => from_value(value).map(Event::RoomKey).map_err(conv_err),
RoomKeyRequest => from_value(value)
.map(Event::RoomKeyRequest)
.map_err(conv_err),
Sticker => from_value(value).map(Event::Sticker).map_err(conv_err),
Tag => from_value(value).map(Event::Tag).map_err(conv_err),
Typing => from_value(value).map(Event::Typing).map_err(conv_err),
// TODO // TODO
Custom(_event_type_name) => Err(D::Error::custom("invalid event type")), Custom(_event_type_name) => Err(D::Error::custom("invalid event type")),
__Nonexhaustive => { __Nonexhaustive => {
@ -450,83 +405,38 @@ impl<'de> Deserialize<'de> for RoomEvent {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
use crate::util::try_variant_from_value as from_value;
use EventType::*; use EventType::*;
let value = Value::deserialize(deserializer)?; let value = Value::deserialize(deserializer)?;
let event_type = get_field(&value, "type")?; let event_type = get_field(&value, "type")?;
match event_type { match event_type {
CallAnswer => from_value(value) CallAnswer => from_value(value, RoomEvent::CallAnswer),
.map(RoomEvent::CallAnswer) CallCandidates => from_value(value, RoomEvent::CallCandidates),
.map_err(conv_err), CallHangup => from_value(value, RoomEvent::CallHangup),
CallCandidates => from_value(value) CallInvite => from_value(value, RoomEvent::CallInvite),
.map(RoomEvent::CallCandidates) RoomAliases => from_value(value, RoomEvent::RoomAliases),
.map_err(conv_err), RoomAvatar => from_value(value, RoomEvent::RoomAvatar),
CallHangup => from_value(value) RoomCanonicalAlias => from_value(value, RoomEvent::RoomCanonicalAlias),
.map(RoomEvent::CallHangup) RoomCreate => from_value(value, RoomEvent::RoomCreate),
.map_err(conv_err), RoomEncrypted => from_value(value, RoomEvent::RoomEncrypted),
CallInvite => from_value(value) RoomEncryption => from_value(value, RoomEvent::RoomEncryption),
.map(RoomEvent::CallInvite) RoomGuestAccess => from_value(value, RoomEvent::RoomGuestAccess),
.map_err(conv_err), RoomHistoryVisibility => from_value(value, RoomEvent::RoomHistoryVisibility),
RoomAliases => from_value(value) RoomJoinRules => from_value(value, RoomEvent::RoomJoinRules),
.map(RoomEvent::RoomAliases) RoomMember => from_value(value, RoomEvent::RoomMember),
.map_err(conv_err), RoomMessage => from_value(value, RoomEvent::RoomMessage),
RoomAvatar => from_value(value) RoomMessageFeedback => from_value(value, RoomEvent::RoomMessageFeedback),
.map(RoomEvent::RoomAvatar) RoomName => from_value(value, RoomEvent::RoomName),
.map_err(conv_err), RoomPinnedEvents => from_value(value, RoomEvent::RoomPinnedEvents),
RoomCanonicalAlias => from_value(value) RoomPowerLevels => from_value(value, RoomEvent::RoomPowerLevels),
.map(RoomEvent::RoomCanonicalAlias) RoomRedaction => from_value(value, RoomEvent::RoomRedaction),
.map_err(conv_err), RoomServerAcl => from_value(value, RoomEvent::RoomServerAcl),
RoomCreate => from_value(value) RoomThirdPartyInvite => from_value(value, RoomEvent::RoomThirdPartyInvite),
.map(RoomEvent::RoomCreate) RoomTombstone => from_value(value, RoomEvent::RoomTombstone),
.map_err(conv_err), RoomTopic => from_value(value, RoomEvent::RoomTopic),
RoomEncrypted => from_value(value) Sticker => from_value(value, RoomEvent::Sticker),
.map(RoomEvent::RoomEncrypted)
.map_err(conv_err),
RoomEncryption => from_value(value)
.map(RoomEvent::RoomEncryption)
.map_err(conv_err),
RoomGuestAccess => from_value(value)
.map(RoomEvent::RoomGuestAccess)
.map_err(conv_err),
RoomHistoryVisibility => from_value(value)
.map(RoomEvent::RoomHistoryVisibility)
.map_err(conv_err),
RoomJoinRules => from_value(value)
.map(RoomEvent::RoomJoinRules)
.map_err(conv_err),
RoomMember => from_value(value)
.map(RoomEvent::RoomMember)
.map_err(conv_err),
RoomMessage => from_value(value)
.map(RoomEvent::RoomMessage)
.map_err(conv_err),
RoomMessageFeedback => from_value(value)
.map(RoomEvent::RoomMessageFeedback)
.map_err(conv_err),
RoomName => from_value(value).map(RoomEvent::RoomName).map_err(conv_err),
RoomPinnedEvents => from_value(value)
.map(RoomEvent::RoomPinnedEvents)
.map_err(conv_err),
RoomPowerLevels => from_value(value)
.map(RoomEvent::RoomPowerLevels)
.map_err(conv_err),
RoomRedaction => from_value(value)
.map(RoomEvent::RoomRedaction)
.map_err(conv_err),
RoomServerAcl => from_value(value)
.map(RoomEvent::RoomServerAcl)
.map_err(conv_err),
RoomThirdPartyInvite => from_value(value)
.map(RoomEvent::RoomThirdPartyInvite)
.map_err(conv_err),
RoomTombstone => from_value(value)
.map(RoomEvent::RoomTombstone)
.map_err(conv_err),
RoomTopic => from_value(value)
.map(RoomEvent::RoomTopic)
.map_err(conv_err),
Sticker => from_value(value).map(RoomEvent::Sticker).map_err(conv_err),
//Custom(_event_type_name) => unimplemented!("todo"), //Custom(_event_type_name) => unimplemented!("todo"),
_ => Err(D::Error::custom("invalid event type")), _ => Err(D::Error::custom("invalid event type")),
} }
@ -538,60 +448,29 @@ impl<'de> Deserialize<'de> for StateEvent {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
use crate::util::try_variant_from_value as from_value;
use EventType::*; use EventType::*;
let value = Value::deserialize(deserializer)?; let value = Value::deserialize(deserializer)?;
let event_type = get_field(&value, "type")?; let event_type = get_field(&value, "type")?;
match event_type { match event_type {
RoomAliases => from_value(value) RoomAliases => from_value(value, StateEvent::RoomAliases),
.map(StateEvent::RoomAliases) RoomAvatar => from_value(value, StateEvent::RoomAvatar),
.map_err(conv_err), RoomCanonicalAlias => from_value(value, StateEvent::RoomCanonicalAlias),
RoomAvatar => from_value(value) RoomCreate => from_value(value, StateEvent::RoomCreate),
.map(StateEvent::RoomAvatar) RoomEncryption => from_value(value, StateEvent::RoomEncryption),
.map_err(conv_err), RoomGuestAccess => from_value(value, StateEvent::RoomGuestAccess),
RoomCanonicalAlias => from_value(value) RoomHistoryVisibility => from_value(value, StateEvent::RoomHistoryVisibility),
.map(StateEvent::RoomCanonicalAlias) RoomJoinRules => from_value(value, StateEvent::RoomJoinRules),
.map_err(conv_err), RoomMember => from_value(value, StateEvent::RoomMember),
RoomCreate => from_value(value) RoomName => from_value(value, StateEvent::RoomName),
.map(StateEvent::RoomCreate) RoomPinnedEvents => from_value(value, StateEvent::RoomPinnedEvents),
.map_err(conv_err), RoomPowerLevels => from_value(value, StateEvent::RoomPowerLevels),
RoomEncryption => from_value(value) RoomServerAcl => from_value(value, StateEvent::RoomServerAcl),
.map(StateEvent::RoomEncryption) RoomThirdPartyInvite => from_value(value, StateEvent::RoomThirdPartyInvite),
.map_err(conv_err), RoomTombstone => from_value(value, StateEvent::RoomTombstone),
RoomGuestAccess => from_value(value) RoomTopic => from_value(value, StateEvent::RoomTopic),
.map(StateEvent::RoomGuestAccess)
.map_err(conv_err),
RoomHistoryVisibility => from_value(value)
.map(StateEvent::RoomHistoryVisibility)
.map_err(conv_err),
RoomJoinRules => from_value(value)
.map(StateEvent::RoomJoinRules)
.map_err(conv_err),
RoomMember => from_value(value)
.map(StateEvent::RoomMember)
.map_err(conv_err),
RoomName => from_value(value)
.map(StateEvent::RoomName)
.map_err(conv_err),
RoomPinnedEvents => from_value(value)
.map(StateEvent::RoomPinnedEvents)
.map_err(conv_err),
RoomPowerLevels => from_value(value)
.map(StateEvent::RoomPowerLevels)
.map_err(conv_err),
RoomServerAcl => from_value(value)
.map(StateEvent::RoomServerAcl)
.map_err(conv_err),
RoomThirdPartyInvite => from_value(value)
.map(StateEvent::RoomThirdPartyInvite)
.map_err(conv_err),
RoomTombstone => from_value(value)
.map(StateEvent::RoomTombstone)
.map_err(conv_err),
RoomTopic => from_value(value)
.map(StateEvent::RoomTopic)
.map_err(conv_err),
//Custom(_event_type_name) => unimplemented!("todo"), //Custom(_event_type_name) => unimplemented!("todo"),
_ => Err(D::Error::custom("invalid event type")), _ => Err(D::Error::custom("invalid event type")),
} }

View File

@ -2,7 +2,7 @@
//! most" the trait of the same name. //! most" the trait of the same name.
use serde::{de::Error as _, Deserialize, Deserializer}; use serde::{de::Error as _, Deserialize, Deserializer};
use serde_json::{from_value, Value}; use serde_json::Value;
pub use super::all::StateEvent; pub use super::all::StateEvent;
use crate::{ use crate::{
@ -32,7 +32,7 @@ use crate::{
sticker::raw::StickerEvent, sticker::raw::StickerEvent,
tag::raw::TagEvent, tag::raw::TagEvent,
typing::raw::TypingEvent, typing::raw::TypingEvent,
util::{get_field, serde_json_error_to_generic_de_error as conv_err}, util::get_field,
CustomEvent, CustomRoomEvent, EventType, CustomEvent, CustomRoomEvent, EventType,
}; };
@ -148,48 +148,31 @@ impl<'de> Deserialize<'de> for Event {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
use crate::util::try_variant_from_value as from_value;
use EventType::*; use EventType::*;
let value = Value::deserialize(deserializer)?; let value = Value::deserialize(deserializer)?;
let event_type = get_field(&value, "type")?; let event_type = get_field(&value, "type")?;
match event_type { match event_type {
Direct => from_value(value).map(Event::Direct).map_err(conv_err), Direct => from_value(value, Event::Direct),
Dummy => from_value(value).map(Event::Dummy).map_err(conv_err), Dummy => from_value(value, Event::Dummy),
ForwardedRoomKey => from_value(value) ForwardedRoomKey => from_value(value, Event::ForwardedRoomKey),
.map(Event::ForwardedRoomKey) FullyRead => from_value(value, Event::FullyRead),
.map_err(conv_err), KeyVerificationAccept => from_value(value, Event::KeyVerificationAccept),
FullyRead => from_value(value).map(Event::FullyRead).map_err(conv_err), KeyVerificationCancel => from_value(value, Event::KeyVerificationCancel),
KeyVerificationAccept => from_value(value) KeyVerificationKey => from_value(value, Event::KeyVerificationKey),
.map(Event::KeyVerificationAccept) KeyVerificationMac => from_value(value, Event::KeyVerificationMac),
.map_err(conv_err), KeyVerificationRequest => from_value(value, Event::KeyVerificationRequest),
KeyVerificationCancel => from_value(value) KeyVerificationStart => from_value(value, Event::KeyVerificationStart),
.map(Event::KeyVerificationCancel) IgnoredUserList => from_value(value, Event::IgnoredUserList),
.map_err(conv_err), Presence => from_value(value, Event::Presence),
KeyVerificationKey => from_value(value) PushRules => from_value(value, Event::PushRules),
.map(Event::KeyVerificationKey) RoomKey => from_value(value, Event::RoomKey),
.map_err(conv_err), RoomKeyRequest => from_value(value, Event::RoomKeyRequest),
KeyVerificationMac => from_value(value) Receipt => from_value(value, Event::Receipt),
.map(Event::KeyVerificationMac) Tag => from_value(value, Event::Tag),
.map_err(conv_err), Typing => from_value(value, Event::Typing),
KeyVerificationRequest => from_value(value)
.map(Event::KeyVerificationRequest)
.map_err(conv_err),
KeyVerificationStart => from_value(value)
.map(Event::KeyVerificationStart)
.map_err(conv_err),
IgnoredUserList => from_value(value)
.map(Event::IgnoredUserList)
.map_err(conv_err),
Presence => from_value(value).map(Event::Presence).map_err(conv_err),
PushRules => from_value(value).map(Event::PushRules).map_err(conv_err),
RoomKey => from_value(value).map(Event::RoomKey).map_err(conv_err),
RoomKeyRequest => from_value(value)
.map(Event::RoomKeyRequest)
.map_err(conv_err),
Receipt => from_value(value).map(Event::Receipt).map_err(conv_err),
Tag => from_value(value).map(Event::Tag).map_err(conv_err),
Typing => from_value(value).map(Event::Typing).map_err(conv_err),
//Custom(_event_type_name) => unimplemented!("todo"), //Custom(_event_type_name) => unimplemented!("todo"),
_ => Err(D::Error::custom("invalid event type")), _ => Err(D::Error::custom("invalid event type")),
} }
@ -201,37 +184,22 @@ impl<'de> Deserialize<'de> for RoomEvent {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
use crate::util::try_variant_from_value as from_value;
use EventType::*; use EventType::*;
let value = Value::deserialize(deserializer)?; let value = Value::deserialize(deserializer)?;
let event_type = get_field(&value, "type")?; let event_type = get_field(&value, "type")?;
match event_type { match event_type {
CallAnswer => from_value(value) CallAnswer => from_value(value, RoomEvent::CallAnswer),
.map(RoomEvent::CallAnswer) CallCandidates => from_value(value, RoomEvent::CallCandidates),
.map_err(conv_err), CallHangup => from_value(value, RoomEvent::CallHangup),
CallCandidates => from_value(value) CallInvite => from_value(value, RoomEvent::CallInvite),
.map(RoomEvent::CallCandidates) RoomEncrypted => from_value(value, RoomEvent::RoomEncrypted),
.map_err(conv_err), RoomMessage => from_value(value, RoomEvent::RoomMessage),
CallHangup => from_value(value) RoomMessageFeedback => from_value(value, RoomEvent::RoomMessageFeedback),
.map(RoomEvent::CallHangup) RoomRedaction => from_value(value, RoomEvent::RoomRedaction),
.map_err(conv_err), Sticker => from_value(value, RoomEvent::Sticker),
CallInvite => from_value(value)
.map(RoomEvent::CallInvite)
.map_err(conv_err),
RoomEncrypted => from_value(value)
.map(RoomEvent::RoomEncrypted)
.map_err(conv_err),
RoomMessage => from_value(value)
.map(RoomEvent::RoomMessage)
.map_err(conv_err),
RoomMessageFeedback => from_value(value)
.map(RoomEvent::RoomMessageFeedback)
.map_err(conv_err),
RoomRedaction => from_value(value)
.map(RoomEvent::RoomRedaction)
.map_err(conv_err),
Sticker => from_value(value).map(RoomEvent::Sticker).map_err(conv_err),
//Custom(_event_type_name) => unimplemented!("todo"), //Custom(_event_type_name) => unimplemented!("todo"),
_ => Err(D::Error::custom("invalid event type")), _ => Err(D::Error::custom("invalid event type")),
} }

View File

@ -219,14 +219,17 @@ mod raw {
use serde_json::Value; use serde_json::Value;
use super::StrippedStateContent; use super::StrippedStateContent;
use crate::room::{ use crate::{
aliases::raw::AliasesEventContent, avatar::raw::AvatarEventContent, room::{
canonical_alias::raw::CanonicalAliasEventContent, create::raw::CreateEventContent, aliases::raw::AliasesEventContent, avatar::raw::AvatarEventContent,
guest_access::raw::GuestAccessEventContent, canonical_alias::raw::CanonicalAliasEventContent, create::raw::CreateEventContent,
history_visibility::raw::HistoryVisibilityEventContent, guest_access::raw::GuestAccessEventContent,
join_rules::raw::JoinRulesEventContent, member::raw::MemberEventContent, history_visibility::raw::HistoryVisibilityEventContent,
name::raw::NameEventContent, power_levels::raw::PowerLevelsEventContent, join_rules::raw::JoinRulesEventContent, member::raw::MemberEventContent,
third_party_invite::raw::ThirdPartyInviteEventContent, topic::raw::TopicEventContent, name::raw::NameEventContent, power_levels::raw::PowerLevelsEventContent,
third_party_invite::raw::ThirdPartyInviteEventContent, topic::raw::TopicEventContent,
},
util::get_field,
}; };
/// A stripped-down version of the *m.room.aliases* event. /// A stripped-down version of the *m.room.aliases* event.
@ -311,54 +314,26 @@ mod raw {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
use crate::{ use crate::{util::try_variant_from_value as from_value, EventType::*};
util::{get_field, serde_json_error_to_generic_de_error as conv_err},
EventType::*,
};
use serde::de::Error as _; use serde::de::Error as _;
use serde_json::from_value;
// TODO: Optimize // TODO: Optimize
let value = Value::deserialize(deserializer)?; let value = Value::deserialize(deserializer)?;
let event_type = get_field(&value, "type")?; let event_type = get_field(&value, "type")?;
match event_type { match event_type {
RoomAliases => from_value(value) RoomAliases => from_value(value, StrippedState::RoomAliases),
.map(StrippedState::RoomAliases) RoomAvatar => from_value(value, StrippedState::RoomAvatar),
.map_err(conv_err), RoomCanonicalAlias => from_value(value, StrippedState::RoomCanonicalAlias),
RoomAvatar => from_value(value) RoomCreate => from_value(value, StrippedState::RoomCreate),
.map(StrippedState::RoomAvatar) RoomGuestAccess => from_value(value, StrippedState::RoomGuestAccess),
.map_err(conv_err), RoomHistoryVisibility => from_value(value, StrippedState::RoomHistoryVisibility),
RoomCanonicalAlias => from_value(value) RoomJoinRules => from_value(value, StrippedState::RoomJoinRules),
.map(StrippedState::RoomCanonicalAlias) RoomMember => from_value(value, StrippedState::RoomMember),
.map_err(conv_err), RoomName => from_value(value, StrippedState::RoomName),
RoomCreate => from_value(value) RoomPowerLevels => from_value(value, StrippedState::RoomPowerLevels),
.map(StrippedState::RoomCreate) RoomThirdPartyInvite => from_value(value, StrippedState::RoomThirdPartyInvite),
.map_err(conv_err), RoomTopic => from_value(value, StrippedState::RoomTopic),
RoomGuestAccess => from_value(value)
.map(StrippedState::RoomGuestAccess)
.map_err(conv_err),
RoomHistoryVisibility => from_value(value)
.map(StrippedState::RoomHistoryVisibility)
.map_err(conv_err),
RoomJoinRules => from_value(value)
.map(StrippedState::RoomJoinRules)
.map_err(conv_err),
RoomMember => from_value(value)
.map(StrippedState::RoomMember)
.map_err(conv_err),
RoomName => from_value(value)
.map(StrippedState::RoomName)
.map_err(conv_err),
RoomPowerLevels => from_value(value)
.map(StrippedState::RoomPowerLevels)
.map_err(conv_err),
RoomThirdPartyInvite => from_value(value)
.map(StrippedState::RoomThirdPartyInvite)
.map_err(conv_err),
RoomTopic => from_value(value)
.map(StrippedState::RoomTopic)
.map_err(conv_err),
_ => Err(D::Error::custom("not a state event")), _ => Err(D::Error::custom("not a state event")),
} }
} }

View File

@ -1,4 +1,5 @@
use serde::de::{Deserialize, DeserializeOwned, IntoDeserializer}; use serde::de::{Deserialize, DeserializeOwned, IntoDeserializer};
use serde_json::Value;
use crate::TryFromRaw; use crate::TryFromRaw;
@ -12,14 +13,25 @@ pub fn try_convert_variant<Enum: TryFromRaw, Content: TryFromRaw>(
.map_err(|(err, raw)| (err.to_string(), raw_variant(raw))) .map_err(|(err, raw)| (err.to_string(), raw_variant(raw)))
} }
pub fn try_variant_from_value<T, U, E>(value: Value, variant: fn(T) -> U) -> Result<U, E>
where
T: DeserializeOwned,
E: serde::de::Error,
{
serde_json::from_value(value)
.map(variant)
.map_err(serde_json_error_to_generic_de_error)
}
pub fn serde_json_error_to_generic_de_error<E: serde::de::Error>(error: serde_json::Error) -> E { pub fn serde_json_error_to_generic_de_error<E: serde::de::Error>(error: serde_json::Error) -> E {
E::custom(error.to_string()) E::custom(error.to_string())
} }
pub fn get_field<T: DeserializeOwned, E: serde::de::Error>( pub fn get_field<T, E>(value: &Value, field: &'static str) -> Result<T, E>
value: &serde_json::Value, where
field: &'static str, T: DeserializeOwned,
) -> Result<T, E> { E: serde::de::Error,
{
serde_json::from_value( serde_json::from_value(
value value
.get(field) .get(field)