Simplify InvalidEvent, update its documentation

This commit is contained in:
Jonas Platte 2019-10-24 22:26:20 +02:00
parent 398e0a73d1
commit 1af436b775
2 changed files with 81 additions and 104 deletions

View File

@ -93,12 +93,12 @@ pub enum EventResult<T: TryFromRaw> {
/// `T` deserialized but was invalid. /// `T` deserialized but was invalid.
/// ///
/// `InvalidEvent` contains the original input. /// `InvalidEvent` contains the original input.
Err(InvalidEvent<T::Raw>), Err(InvalidEvent),
} }
impl<T: TryFromRaw> EventResult<T> { impl<T: TryFromRaw> EventResult<T> {
/// Convert `EventResult<T>` into the equivalent `std::result::Result<T, InvalidEvent<T::Raw>>`. /// Convert `EventResult<T>` into the equivalent `std::result::Result<T, InvalidEvent>`.
pub fn into_result(self) -> Result<T, InvalidEvent<T::Raw>> { pub fn into_result(self) -> Result<T, InvalidEvent> {
match self { match self {
EventResult::Ok(t) => Ok(t), EventResult::Ok(t) => Ok(t),
EventResult::Err(invalid_event) => Err(invalid_event), EventResult::Err(invalid_event) => Err(invalid_event),
@ -145,23 +145,21 @@ where
let raw_data: T::Raw = match serde_json::from_value(json.clone()) { let raw_data: T::Raw = match serde_json::from_value(json.clone()) {
Ok(raw) => raw, Ok(raw) => raw,
Err(error) => { Err(error) => {
return Ok(EventResult::Err(InvalidEvent( return Ok(EventResult::Err(InvalidEvent {
InnerInvalidEvent::Deserialization { json,
json, message: error.to_string(),
error: error.to_string(), kind: InvalidEventKind::Deserialization,
}, }));
)));
} }
}; };
match T::try_from_raw(raw_data) { match T::try_from_raw(raw_data) {
Ok(value) => Ok(EventResult::Ok(value)), Ok(value) => Ok(EventResult::Ok(value)),
Err((err, raw_data)) => Ok(EventResult::Err(InvalidEvent( Err((err, _)) => Ok(EventResult::Err(InvalidEvent {
InnerInvalidEvent::Validation { message: err.to_string(),
message: err.to_string(), json,
raw_data, kind: InvalidEventKind::Validation,
}, })),
))),
} }
} }
} }
@ -211,35 +209,50 @@ pub trait StateEvent: RoomEvent {
/// An event that is malformed or otherwise invalid. /// An event that is malformed or otherwise invalid.
/// ///
/// When attempting to create an event from a string of JSON data, an error in the input data may /// When attempting to deserialize an `EventResult`, an error in the input data may cause
/// cause deserialization to fail, or the JSON structure may not corresponded to ruma-events's /// deserialization to fail, or the JSON structure may be correct, but additional constraints
/// strict definition of the event's schema. If deserialization completely fails, this type will /// defined in the matrix specification are not upheld. This type provides an error message and a
/// provide a message with details about the deserialization error. If deserialization succeeds but /// `serde_json::Value` representation of the invalid event, as well as a flag for which type of
/// the event is otherwise invalid, a similar message will be provided, as well as a /// error was encountered.
/// `serde_json::Value` containing the raw JSON data as it was deserialized. #[derive(Clone, Debug)]
#[derive(Debug)] pub struct InvalidEvent {
pub struct InvalidEvent<T>(InnerInvalidEvent<T>); message: String,
json: Value,
kind: InvalidEventKind,
}
/// An event that is malformed or otherwise invalid. #[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Debug)] enum InvalidEventKind {
enum InnerInvalidEvent<T> { Deserialization,
/// An event that failed to deserialize from JSON. Validation,
Deserialization { }
/// The raw `serde_json::Value` representation of the invalid event.
json: Value,
/// The deserialization error returned by serde. impl InvalidEvent {
error: String, /// A message describing why the event is invalid.
}, pub fn message(&self) -> String {
self.message.clone()
}
/// An event that deserialized but failed validation. /// The `serde_json::Value` representation of the invalid event.
Validation { pub fn json(&self) -> &Value {
/// The event data that failed validation. &self.json
raw_data: T, }
/// A message describing why the event was invalid. /// Returns whether this is a deserialization error.
message: String, pub fn is_deserialization(&self) -> bool {
}, self.kind == InvalidEventKind::Deserialization
}
/// Returns whether this is a validation error.
pub fn is_validation(&self) -> bool {
self.kind == InvalidEventKind::Validation
}
}
impl Display for InvalidEvent {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "{}", self.message())
}
} }
// See note about wrapping macro expansion in a module from `src/lib.rs` // See note about wrapping macro expansion in a module from `src/lib.rs`

View File

@ -166,63 +166,43 @@ pub mod typing;
/// An event that is malformed or otherwise invalid. /// An event that is malformed or otherwise invalid.
/// ///
/// When attempting to create an event from a string of JSON data, an error in the input data may /// When attempting to deserialize an `EventResult`, an error in the input data may cause
/// cause deserialization to fail, or the JSON structure may not corresponded to ruma-events's /// deserialization to fail, or the JSON structure may be correct, but additional constraints
/// strict definition of the event's schema. If deserialization completely fails, this type will /// defined in the matrix specification are not upheld. This type provides an error message and a
/// provide a message with details about the deserialization error. If deserialization succeeds but /// `serde_json::Value` representation of the invalid event, as well as a flag for which type of
/// the event is otherwise invalid, a similar message will be provided, as well as a /// error was encountered.
/// `serde_json::Value` containing the raw JSON data as it was deserialized.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum InvalidEvent { pub struct InvalidEvent {
/// An error that occured during deserialization. message: String,
Deserialization(DeserializationError), json: Value,
kind: InvalidEventKind,
}
/// An error that occured during raw event validation. #[derive(Copy, Clone, Debug, PartialEq, Eq)]
Validation(ValidationError), enum InvalidEventKind {
Deserialization,
/// Additional variants may be added in the future and will not be considered breaking changes Validation,
/// to ruma-events.
#[doc(hidden)]
__Nonexhaustive,
} }
impl InvalidEvent { impl InvalidEvent {
/// A message describing why the event is invalid. /// A message describing why the event is invalid.
pub fn message(&self) -> String { pub fn message(&self) -> String {
match self { self.message.clone()
InvalidEvent::Deserialization(err) => err.message.clone(),
InvalidEvent::Validation(err) => err.message.clone(),
InvalidEvent::__Nonexhaustive => {
panic!("__Nonexhaustive enum variant is not intended for use.")
}
}
} }
/// The `serde_json::Value` representation of the invalid event. /// The `serde_json::Value` representation of the invalid event.
pub fn json(&self) -> &Value { pub fn json(&self) -> &Value {
match self { &self.json
InvalidEvent::Deserialization(err) => &err.json,
InvalidEvent::Validation(err) => &err.json,
InvalidEvent::__Nonexhaustive => {
panic!("__Nonexhaustive enum variant is not intended for use.")
}
}
} }
/// Returns whether this is a deserialization error. /// Returns whether this is a deserialization error.
pub fn is_deserialization(&self) -> bool { pub fn is_deserialization(&self) -> bool {
match self { self.kind == InvalidEventKind::Deserialization
InvalidEvent::Deserialization(_) => true,
_ => false,
}
} }
/// Returns whether this is a validation error. /// Returns whether this is a validation error.
pub fn is_validation(&self) -> bool { pub fn is_validation(&self) -> bool {
match self { self.kind == InvalidEventKind::Validation
InvalidEvent::Validation(_) => true,
_ => false,
}
} }
} }
@ -234,20 +214,6 @@ impl Display for InvalidEvent {
impl Error for InvalidEvent {} impl Error for InvalidEvent {}
/// An error that occured during deserialization.
#[derive(Clone, Debug)]
pub struct DeserializationError {
message: String,
json: Value,
}
/// An error that occured during raw event validation.
#[derive(Clone, Debug)]
pub struct ValidationError {
message: String,
json: Value,
}
/// An error returned when attempting to create an event with data that would make it invalid. /// An error returned when attempting to create an event with data that would make it invalid.
/// ///
/// This type is similar to `InvalidEvent`, but used during the construction of a new event, as /// This type is similar to `InvalidEvent`, but used during the construction of a new event, as
@ -336,23 +302,21 @@ where
let raw_data: T::Raw = match serde_json::from_value(json.clone()) { let raw_data: T::Raw = match serde_json::from_value(json.clone()) {
Ok(raw) => raw, Ok(raw) => raw,
Err(error) => { Err(error) => {
return Ok(EventResult::Err(InvalidEvent::Deserialization( return Ok(EventResult::Err(InvalidEvent {
DeserializationError { json,
json, message: error.to_string(),
message: error.to_string(), kind: InvalidEventKind::Deserialization,
}, }));
)));
} }
}; };
match T::try_from_raw(raw_data) { match T::try_from_raw(raw_data) {
Ok(value) => Ok(EventResult::Ok(value)), Ok(value) => Ok(EventResult::Ok(value)),
Err((err, _)) => Ok(EventResult::Err(InvalidEvent::Validation( Err((err, _)) => Ok(EventResult::Err(InvalidEvent {
ValidationError { message: err.to_string(),
message: err.to_string(), json,
json, kind: InvalidEventKind::Validation,
}, })),
))),
} }
} }
} }