impl Deserialize for m.room.message
This commit is contained in:
parent
2acca3e3ef
commit
bd64b7f4be
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user