Simplify StrippedStateContent deserialization

This commit is contained in:
Jonas Platte 2019-10-21 14:20:53 +02:00
parent 7e210476fa
commit 7e5ca6e7af
4 changed files with 21 additions and 52 deletions

View File

@ -47,7 +47,7 @@ use crate::{
sticker::raw::StickerEvent,
tag::raw::TagEvent,
typing::raw::TypingEvent,
util::{get_type_field, serde_json_error_to_generic_de_error as conv_err},
util::{get_field, serde_json_error_to_generic_de_error as conv_err},
CustomEvent, CustomRoomEvent, CustomStateEvent, EventType,
};
@ -344,7 +344,7 @@ impl<'de> Deserialize<'de> for Event {
use EventType::*;
let value = Value::deserialize(deserializer)?;
let event_type = get_type_field(&value)?;
let event_type = get_field(&value, "type")?;
match event_type {
CallAnswer => from_value(value).map(Self::CallAnswer).map_err(conv_err),
@ -443,7 +443,7 @@ impl<'de> Deserialize<'de> for RoomEvent {
use EventType::*;
let value = Value::deserialize(deserializer)?;
let event_type = get_type_field(&value)?;
let event_type = get_field(&value, "type")?;
match event_type {
CallAnswer => from_value(value).map(Self::CallAnswer).map_err(conv_err),
@ -503,7 +503,7 @@ impl<'de> Deserialize<'de> for StateEvent {
use EventType::*;
let value = Value::deserialize(deserializer)?;
let event_type = get_type_field(&value)?;
let event_type = get_field(&value, "type")?;
match event_type {
RoomAliases => from_value(value).map(Self::RoomAliases).map_err(conv_err),

View File

@ -32,7 +32,7 @@ use crate::{
sticker::raw::StickerEvent,
tag::raw::TagEvent,
typing::raw::TypingEvent,
util::{get_type_field, serde_json_error_to_generic_de_error as conv_err},
util::{get_field, serde_json_error_to_generic_de_error as conv_err},
CustomEvent, CustomRoomEvent, EventType,
};
@ -151,7 +151,7 @@ impl<'de> Deserialize<'de> for Event {
use EventType::*;
let value = Value::deserialize(deserializer)?;
let event_type = get_type_field(&value)?;
let event_type = get_field(&value, "type")?;
match event_type {
Direct => from_value(value).map(Self::Direct).map_err(conv_err),
@ -204,7 +204,7 @@ impl<'de> Deserialize<'de> for RoomEvent {
use EventType::*;
let value = Value::deserialize(deserializer)?;
let event_type = get_type_field(&value)?;
let event_type = get_field(&value, "type")?;
match event_type {
CallAnswer => from_value(value).map(Self::CallAnswer).map_err(conv_err),

View File

@ -18,6 +18,7 @@ use crate::{
power_levels::PowerLevelsEventContent, third_party_invite::ThirdPartyInviteEventContent,
topic::TopicEventContent,
},
util::get_field,
EventType, TryFromRaw,
};
@ -195,51 +196,14 @@ where
where
D: Deserializer<'de>,
{
use serde::de::Error as _;
use serde_json::from_value;
let conv_err = |error: serde_json::Error| D::Error::custom(error.to_string());
// TODO: Optimize
let value = Value::deserialize(deserializer)?;
let event_type = from_value(
value
.get("type")
.cloned()
.ok_or_else(|| D::Error::missing_field("type"))?,
)
.map_err(conv_err)?;
let content = from_value(
value
.get("content")
.cloned()
.ok_or_else(|| D::Error::missing_field("content"))?,
)
.map_err(conv_err)?;
let sender = from_value(
value
.get("sender")
.cloned()
.ok_or_else(|| D::Error::missing_field("sender"))?,
)
.map_err(conv_err)?;
let state_key = from_value(
value
.get("state_key")
.cloned()
.ok_or_else(|| D::Error::missing_field("state_key"))?,
)
.map_err(conv_err)?;
Ok(Self {
content,
event_type,
state_key,
sender,
content: get_field(&value, "content")?,
event_type: get_field(&value, "type")?,
state_key: get_field(&value, "state_key")?,
sender: get_field(&value, "sender")?,
})
}
}

View File

@ -1,4 +1,6 @@
use crate::{EventType, TryFromRaw};
use serde::de::DeserializeOwned;
use crate::TryFromRaw;
pub fn try_convert_variant<Enum: TryFromRaw, Content: TryFromRaw>(
raw_variant: fn(Content::Raw) -> Enum::Raw,
@ -14,12 +16,15 @@ pub fn serde_json_error_to_generic_de_error<E: serde::de::Error>(error: serde_js
E::custom(error.to_string())
}
pub fn get_type_field<E: serde::de::Error>(value: &serde_json::Value) -> Result<EventType, E> {
pub fn get_field<T: DeserializeOwned, E: serde::de::Error>(
value: &serde_json::Value,
field: &'static str,
) -> Result<T, E> {
serde_json::from_value(
value
.get("type")
.get(field)
.cloned()
.ok_or_else(|| E::missing_field("type"))?,
.ok_or_else(|| E::missing_field(field))?,
)
.map_err(serde_json_error_to_generic_de_error)
}