diff --git a/src/collections/raw/all.rs b/src/collections/raw/all.rs index abab4a1b..c4e740f7 100644 --- a/src/collections/raw/all.rs +++ b/src/collections/raw/all.rs @@ -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), diff --git a/src/collections/raw/only.rs b/src/collections/raw/only.rs index 7fe339b6..92395e2c 100644 --- a/src/collections/raw/only.rs +++ b/src/collections/raw/only.rs @@ -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), diff --git a/src/stripped.rs b/src/stripped.rs index 2541e348..5f4f71ce 100644 --- a/src/stripped.rs +++ b/src/stripped.rs @@ -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")?, }) } } diff --git a/src/util.rs b/src/util.rs index 69a6fb91..953ee7ca 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,4 +1,6 @@ -use crate::{EventType, TryFromRaw}; +use serde::de::DeserializeOwned; + +use crate::TryFromRaw; pub fn try_convert_variant( raw_variant: fn(Content::Raw) -> Enum::Raw, @@ -14,12 +16,15 @@ pub fn serde_json_error_to_generic_de_error(error: serde_js E::custom(error.to_string()) } -pub fn get_type_field(value: &serde_json::Value) -> Result { +pub fn get_field( + value: &serde_json::Value, + field: &'static str, +) -> Result { 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) }