impl Deserialize for m.room.message

This commit is contained in:
Jimmy Cuadra 2019-08-06 15:02:05 -07:00
parent 2acca3e3ef
commit bd64b7f4be

View File

@ -12,7 +12,7 @@ use serde::{
use serde_json::{from_value, Value}; use serde_json::{from_value, Value};
use super::{EncryptedFile, ImageInfo, ThumbnailInfo}; use super::{EncryptedFile, ImageInfo, ThumbnailInfo};
use crate::{Event, EventType, InnerInvalidEvent, InvalidEvent, RoomEvent}; use crate::{Event, EventResult, EventType, InnerInvalidEvent, InvalidEvent, RoomEvent};
pub mod feedback; pub mod feedback;
@ -76,6 +76,53 @@ pub enum MessageEventContent {
__Nonexhaustive, __Nonexhaustive,
} }
impl<'de> Deserialize<'de> for EventResult<MessageEvent> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let json = serde_json::Value::deserialize(deserializer)?;
let raw: raw::MessageEvent = match serde_json::from_value(json.clone()) {
Ok(raw) => raw,
Err(error) => {
return Ok(EventResult::Err(InvalidEvent(
InnerInvalidEvent::Validation {
json,
message: error.to_string(),
},
)));
}
};
Ok(EventResult::Ok(MessageEvent {
content: match raw.content {
raw::MessageEventContent::Audio(content) => MessageEventContent::Audio(content),
raw::MessageEventContent::Emote(content) => MessageEventContent::Emote(content),
raw::MessageEventContent::File(content) => MessageEventContent::File(content),
raw::MessageEventContent::Image(content) => MessageEventContent::Image(content),
raw::MessageEventContent::Location(content) => {
MessageEventContent::Location(content)
}
raw::MessageEventContent::Notice(content) => MessageEventContent::Notice(content),
raw::MessageEventContent::ServerNotice(content) => {
MessageEventContent::ServerNotice(content)
}
raw::MessageEventContent::Text(content) => MessageEventContent::Text(content),
raw::MessageEventContent::Video(content) => MessageEventContent::Video(content),
raw::MessageEventContent::__Nonexhaustive => {
panic!("__Nonexhaustive enum variant is not intended for use.")
}
},
event_id: raw.event_id,
origin_server_ts: raw.origin_server_ts,
room_id: raw.room_id,
sender: raw.sender,
unsigned: raw.unsigned,
}))
}
}
impl FromStr for MessageEvent { impl FromStr for MessageEvent {
type Err = InvalidEvent; type Err = InvalidEvent;
@ -193,6 +240,46 @@ impl Serialize for MessageEventContent {
} }
} }
impl<'de> Deserialize<'de> for EventResult<MessageEventContent> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let json = serde_json::Value::deserialize(deserializer)?;
let raw: raw::MessageEventContent = match serde_json::from_value(json.clone()) {
Ok(raw) => raw,
Err(error) => {
return Ok(EventResult::Err(InvalidEvent(
InnerInvalidEvent::Validation {
json,
message: error.to_string(),
},
)));
}
};
let content = match raw {
raw::MessageEventContent::Audio(content) => MessageEventContent::Audio(content),
raw::MessageEventContent::Emote(content) => MessageEventContent::Emote(content),
raw::MessageEventContent::File(content) => MessageEventContent::File(content),
raw::MessageEventContent::Image(content) => MessageEventContent::Image(content),
raw::MessageEventContent::Location(content) => MessageEventContent::Location(content),
raw::MessageEventContent::Notice(content) => MessageEventContent::Notice(content),
raw::MessageEventContent::ServerNotice(content) => {
MessageEventContent::ServerNotice(content)
}
raw::MessageEventContent::Text(content) => MessageEventContent::Text(content),
raw::MessageEventContent::Video(content) => MessageEventContent::Video(content),
raw::MessageEventContent::__Nonexhaustive => {
panic!("__Nonexhaustive enum variant is not intended for use.")
}
};
Ok(EventResult::Ok(content))
}
}
impl FromStr for MessageEventContent { impl FromStr for MessageEventContent {
type Err = InvalidEvent; type Err = InvalidEvent;
@ -1107,7 +1194,7 @@ impl Serialize for VideoMessageEventContent {
mod tests { mod tests {
use serde_json::to_string; use serde_json::to_string;
use super::{AudioMessageEventContent, MessageEventContent}; use super::{AudioMessageEventContent, EventResult, MessageEventContent};
#[test] #[test]
fn serialization() { fn serialization() {
@ -1134,19 +1221,23 @@ mod tests {
}); });
assert_eq!( assert_eq!(
r#"{"body":"test","msgtype":"m.audio","url":"http://example.com/audio.mp3"}"# serde_json::from_str::<EventResult<MessageEventContent>>(
.parse::<MessageEventContent>() r#"{"body":"test","msgtype":"m.audio","url":"http://example.com/audio.mp3"}"#
.unwrap(), )
.unwrap()
.into_result()
.unwrap(),
message_event_content message_event_content
); );
} }
#[test] #[test]
fn deserialization_failure() { fn deserialization_failure() {
assert!( assert!(serde_json::from_str::<EventResult<MessageEventContent>>(
r#"{"body":"test","msgtype":"m.location","url":"http://example.com/audio.mp3"}"# r#"{"body":"test","msgtype":"m.location","url":"http://example.com/audio.mp3"}"#
.parse::<MessageEventContent>() )
.is_err() .unwrap()
); .into_result()
.is_err());
} }
} }