From 0f557294783499658c425f85bb81ae2a24df87b2 Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Mon, 8 Jul 2019 03:41:28 -0700 Subject: [PATCH] Handle both deserialization and validation errors in FromStr impls. --- src/room/canonical_alias.rs | 18 ++++++++++++++++-- src/room/encrypted.rs | 32 +++++++++++++++++++++++++++++--- src/room/message.rs | 32 +++++++++++++++++++++++++++++--- src/room/name.rs | 18 ++++++++++++++++-- src/room/power_levels.rs | 19 +++++++++++++++++-- src/room/server_acl.rs | 19 +++++++++++++++++-- 6 files changed, 124 insertions(+), 14 deletions(-) diff --git a/src/room/canonical_alias.rs b/src/room/canonical_alias.rs index 67baecda..7280650b 100644 --- a/src/room/canonical_alias.rs +++ b/src/room/canonical_alias.rs @@ -8,7 +8,8 @@ use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde_json::Value; use crate::{ - empty_string_as_none, Event, EventType, InvalidEvent, InvalidInput, RoomEvent, StateEvent, + empty_string_as_none, Event, EventType, InnerInvalidEvent, InvalidEvent, InvalidInput, + RoomEvent, StateEvent, }; /// Informs the room as to which alias is the canonical one. @@ -54,7 +55,20 @@ impl FromStr for CanonicalAliasEvent { /// Attempt to create `Self` from parsing a string of JSON data. fn from_str(json: &str) -> Result { - let raw = serde_json::from_str::(json)?; + let raw = match serde_json::from_str::(json) { + Ok(raw) => raw, + Err(error) => match serde_json::from_str::(json) { + Ok(value) => { + return Err(InvalidEvent(InnerInvalidEvent::Validation { + json: value, + message: error.to_string(), + })); + } + Err(error) => { + return Err(InvalidEvent(InnerInvalidEvent::Deserialization { error })); + } + }, + }; Ok(Self { content: CanonicalAliasEventContent { diff --git a/src/room/encrypted.rs b/src/room/encrypted.rs index f65720eb..8ca4609d 100644 --- a/src/room/encrypted.rs +++ b/src/room/encrypted.rs @@ -7,7 +7,7 @@ use ruma_identifiers::{DeviceId, EventId, RoomId, UserId}; use serde::{de::Error, ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer}; use serde_json::{from_value, Value}; -use crate::{Algorithm, Event, EventType, InvalidEvent, RoomEvent, StateEvent}; +use crate::{Algorithm, Event, EventType, InnerInvalidEvent, InvalidEvent, RoomEvent, StateEvent}; /// This event type is used when sending encrypted events. /// @@ -55,7 +55,20 @@ impl FromStr for EncryptedEvent { /// Attempt to create `Self` from parsing a string of JSON data. fn from_str(json: &str) -> Result { - let raw = serde_json::from_str::(json)?; + let raw = match serde_json::from_str::(json) { + Ok(raw) => raw, + Err(error) => match serde_json::from_str::(json) { + Ok(value) => { + return Err(InvalidEvent(InnerInvalidEvent::Validation { + json: value, + message: error.to_string(), + })); + } + Err(error) => { + return Err(InvalidEvent(InnerInvalidEvent::Deserialization { error })); + } + }, + }; let content = match raw.content { raw::EncryptedEventContent::OlmV1Curve25519AesSha2(content) => { @@ -136,7 +149,20 @@ impl FromStr for EncryptedEventContent { /// Attempt to create `Self` from parsing a string of JSON data. fn from_str(json: &str) -> Result { - let raw = serde_json::from_str::(json)?; + let raw = match serde_json::from_str::(json) { + Ok(raw) => raw, + Err(error) => match serde_json::from_str::(json) { + Ok(value) => { + return Err(InvalidEvent(InnerInvalidEvent::Validation { + json: value, + message: error.to_string(), + })); + } + Err(error) => { + return Err(InvalidEvent(InnerInvalidEvent::Deserialization { error })); + } + }, + }; match raw { raw::EncryptedEventContent::OlmV1Curve25519AesSha2(content) => { diff --git a/src/room/message.rs b/src/room/message.rs index 4e94cbe0..19096e61 100644 --- a/src/room/message.rs +++ b/src/room/message.rs @@ -12,7 +12,7 @@ use serde::{ use serde_json::{from_value, Value}; use super::{EncryptedFile, ImageInfo, ThumbnailInfo}; -use crate::{Event, EventType, InvalidEvent, InvalidInput, RoomEvent}; +use crate::{Event, EventType, InnerInvalidEvent, InvalidEvent, InvalidInput, RoomEvent}; pub mod feedback; @@ -81,7 +81,20 @@ impl FromStr for MessageEvent { /// Attempt to create `Self` from parsing a string of JSON data. fn from_str(json: &str) -> Result { - let raw = serde_json::from_str::(json)?; + let raw = match serde_json::from_str::(json) { + Ok(raw) => raw, + Err(error) => match serde_json::from_str::(json) { + Ok(value) => { + return Err(InvalidEvent(InnerInvalidEvent::Validation { + json: value, + message: error.to_string(), + })); + } + Err(error) => { + return Err(InvalidEvent(InnerInvalidEvent::Deserialization { error })); + } + }, + }; Ok(Self { content: match raw.content { @@ -185,7 +198,20 @@ impl FromStr for MessageEventContent { /// Attempt to create `Self` from parsing a string of JSON data. fn from_str(json: &str) -> Result { - let raw = serde_json::from_str::(json)?; + let raw = match serde_json::from_str::(json) { + Ok(raw) => raw, + Err(error) => match serde_json::from_str::(json) { + Ok(value) => { + return Err(InvalidEvent(InnerInvalidEvent::Validation { + json: value, + message: error.to_string(), + })); + } + Err(error) => { + return Err(InvalidEvent(InnerInvalidEvent::Deserialization { error })); + } + }, + }; match raw { raw::MessageEventContent::Audio(content) => Ok(MessageEventContent::Audio(content)), diff --git a/src/room/name.rs b/src/room/name.rs index 153c9fa1..e8181364 100644 --- a/src/room/name.rs +++ b/src/room/name.rs @@ -8,7 +8,8 @@ use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde_json::Value; use crate::{ - empty_string_as_none, Event, EventType, InvalidEvent, InvalidInput, RoomEvent, StateEvent, + empty_string_as_none, Event, EventType, InnerInvalidEvent, InvalidEvent, InvalidInput, + RoomEvent, StateEvent, }; /// A human-friendly room name designed to be displayed to the end-user. @@ -52,7 +53,20 @@ impl FromStr for NameEvent { /// Attempt to create `Self` from parsing a string of JSON data. fn from_str(json: &str) -> Result { - let raw = serde_json::from_str::(json)?; + let raw = match serde_json::from_str::(json) { + Ok(raw) => raw, + Err(error) => match serde_json::from_str::(json) { + Ok(value) => { + return Err(InvalidEvent(InnerInvalidEvent::Validation { + json: value, + message: error.to_string(), + })); + } + Err(error) => { + return Err(InvalidEvent(InnerInvalidEvent::Deserialization { error })); + } + }, + }; Ok(Self { content: NameEventContent { diff --git a/src/room/power_levels.rs b/src/room/power_levels.rs index 0e7d984f..19c66716 100644 --- a/src/room/power_levels.rs +++ b/src/room/power_levels.rs @@ -7,7 +7,9 @@ use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde_json::Value; -use crate::{Event, EventType, InvalidEvent, InvalidInput, RoomEvent, StateEvent}; +use crate::{ + Event, EventType, InnerInvalidEvent, InvalidEvent, InvalidInput, RoomEvent, StateEvent, +}; /// Defines the power levels (privileges) of users in the room. #[derive(Clone, Debug, PartialEq)] @@ -90,7 +92,20 @@ impl FromStr for PowerLevelsEvent { /// Attempt to create `Self` from parsing a string of JSON data. fn from_str(json: &str) -> Result { - let raw = serde_json::from_str::(json)?; + let raw = match serde_json::from_str::(json) { + Ok(raw) => raw, + Err(error) => match serde_json::from_str::(json) { + Ok(value) => { + return Err(InvalidEvent(InnerInvalidEvent::Validation { + json: value, + message: error.to_string(), + })); + } + Err(error) => { + return Err(InvalidEvent(InnerInvalidEvent::Deserialization { error })); + } + }, + }; Ok(Self { content: PowerLevelsEventContent { diff --git a/src/room/server_acl.rs b/src/room/server_acl.rs index 076dfa77..e5e09a77 100644 --- a/src/room/server_acl.rs +++ b/src/room/server_acl.rs @@ -7,7 +7,9 @@ use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; use serde_json::Value; -use crate::{default_true, Event, EventType, InvalidEvent, RoomEvent, StateEvent}; +use crate::{ + default_true, Event, EventType, InnerInvalidEvent, InvalidEvent, RoomEvent, StateEvent, +}; /// An event to indicate which servers are permitted to participate in the room. #[derive(Clone, Debug, PartialEq)] @@ -72,7 +74,20 @@ impl FromStr for ServerAclEvent { /// Attempt to create `Self` from parsing a string of JSON data. fn from_str(json: &str) -> Result { - let raw = serde_json::from_str::(json)?; + let raw = match serde_json::from_str::(json) { + Ok(raw) => raw, + Err(error) => match serde_json::from_str::(json) { + Ok(value) => { + return Err(InvalidEvent(InnerInvalidEvent::Validation { + json: value, + message: error.to_string(), + })); + } + Err(error) => { + return Err(InvalidEvent(InnerInvalidEvent::Deserialization { error })); + } + }, + }; Ok(Self { content: ServerAclEventContent {