Handle both deserialization and validation errors in FromStr impls.

This commit is contained in:
Jimmy Cuadra 2019-07-08 03:41:28 -07:00
parent 4e363bc2c5
commit 0f55729478
6 changed files with 124 additions and 14 deletions

View File

@ -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<Self, Self::Err> {
let raw = serde_json::from_str::<raw::CanonicalAliasEvent>(json)?;
let raw = match serde_json::from_str::<raw::CanonicalAliasEvent>(json) {
Ok(raw) => raw,
Err(error) => match serde_json::from_str::<serde_json::Value>(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 {

View File

@ -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<Self, Self::Err> {
let raw = serde_json::from_str::<raw::EncryptedEvent>(json)?;
let raw = match serde_json::from_str::<raw::EncryptedEvent>(json) {
Ok(raw) => raw,
Err(error) => match serde_json::from_str::<serde_json::Value>(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<Self, Self::Err> {
let raw = serde_json::from_str::<raw::EncryptedEventContent>(json)?;
let raw = match serde_json::from_str::<raw::EncryptedEventContent>(json) {
Ok(raw) => raw,
Err(error) => match serde_json::from_str::<serde_json::Value>(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) => {

View File

@ -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<Self, Self::Err> {
let raw = serde_json::from_str::<raw::MessageEvent>(json)?;
let raw = match serde_json::from_str::<raw::MessageEvent>(json) {
Ok(raw) => raw,
Err(error) => match serde_json::from_str::<serde_json::Value>(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<Self, Self::Err> {
let raw = serde_json::from_str::<raw::MessageEventContent>(json)?;
let raw = match serde_json::from_str::<raw::MessageEventContent>(json) {
Ok(raw) => raw,
Err(error) => match serde_json::from_str::<serde_json::Value>(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)),

View File

@ -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<Self, Self::Err> {
let raw = serde_json::from_str::<raw::NameEvent>(json)?;
let raw = match serde_json::from_str::<raw::NameEvent>(json) {
Ok(raw) => raw,
Err(error) => match serde_json::from_str::<serde_json::Value>(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 {

View File

@ -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<Self, Self::Err> {
let raw = serde_json::from_str::<raw::PowerLevelsEvent>(json)?;
let raw = match serde_json::from_str::<raw::PowerLevelsEvent>(json) {
Ok(raw) => raw,
Err(error) => match serde_json::from_str::<serde_json::Value>(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 {

View File

@ -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<Self, Self::Err> {
let raw = serde_json::from_str::<raw::ServerAclEvent>(json)?;
let raw = match serde_json::from_str::<raw::ServerAclEvent>(json) {
Ok(raw) => raw,
Err(error) => match serde_json::from_str::<serde_json::Value>(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 {