361 lines
12 KiB
Rust
361 lines
12 KiB
Rust
//! `Deserialize` implementation for RoomMessageEventContent and MessageType.
|
|
|
|
use serde::{de, Deserialize};
|
|
use serde_json::value::RawValue as RawJsonValue;
|
|
|
|
#[cfg(feature = "unstable-msc3245")]
|
|
use super::VoiceContent;
|
|
#[cfg(feature = "unstable-msc3246")]
|
|
use super::{AudioContent, AudioInfo, AudioMessageEventContent};
|
|
#[cfg(feature = "unstable-msc3551")]
|
|
use super::{FileContent, FileInfo, FileMessageEventContent, MediaSource, MessageContent};
|
|
#[cfg(feature = "unstable-msc3552")]
|
|
use super::{ImageContent, ImageInfo, ImageMessageEventContent, ThumbnailContent};
|
|
use super::{MessageType, Relation, RoomMessageEventContent};
|
|
#[cfg(feature = "unstable-msc3553")]
|
|
use super::{VideoContent, VideoInfo, VideoMessageEventContent};
|
|
use crate::serde::from_raw_json_value;
|
|
|
|
impl<'de> Deserialize<'de> for RoomMessageEventContent {
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
where
|
|
D: de::Deserializer<'de>,
|
|
{
|
|
let json = Box::<RawJsonValue>::deserialize(deserializer)?;
|
|
let mut deserializer = serde_json::Deserializer::from_str(json.get());
|
|
let relates_to =
|
|
Option::<Relation>::deserialize(&mut deserializer).map_err(de::Error::custom)?;
|
|
|
|
Ok(Self { msgtype: from_raw_json_value(&json)?, relates_to })
|
|
}
|
|
}
|
|
|
|
/// Helper struct to determine the msgtype from a `serde_json::value::RawValue`
|
|
#[derive(Debug, Deserialize)]
|
|
struct MessageTypeDeHelper {
|
|
/// The message type field
|
|
msgtype: String,
|
|
}
|
|
|
|
impl<'de> Deserialize<'de> for MessageType {
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
where
|
|
D: de::Deserializer<'de>,
|
|
{
|
|
let json = Box::<RawJsonValue>::deserialize(deserializer)?;
|
|
let MessageTypeDeHelper { msgtype } = from_raw_json_value(&json)?;
|
|
|
|
Ok(match msgtype.as_ref() {
|
|
"m.audio" => Self::Audio(from_raw_json_value(&json)?),
|
|
"m.emote" => Self::Emote(from_raw_json_value(&json)?),
|
|
"m.file" => Self::File(from_raw_json_value(&json)?),
|
|
"m.image" => Self::Image(from_raw_json_value(&json)?),
|
|
"m.location" => Self::Location(from_raw_json_value(&json)?),
|
|
"m.notice" => Self::Notice(from_raw_json_value(&json)?),
|
|
"m.server_notice" => Self::ServerNotice(from_raw_json_value(&json)?),
|
|
"m.text" => Self::Text(from_raw_json_value(&json)?),
|
|
"m.video" => Self::Video(from_raw_json_value(&json)?),
|
|
"m.key.verification.request" => Self::VerificationRequest(from_raw_json_value(&json)?),
|
|
_ => Self::_Custom(from_raw_json_value(&json)?),
|
|
})
|
|
}
|
|
}
|
|
|
|
/// Helper struct for deserializing `AudioMessageEventContent` with stable and unstable field names.
|
|
///
|
|
/// It's not possible to use the `alias` attribute of serde because of
|
|
/// https://github.com/serde-rs/serde/issues/1504.
|
|
#[derive(Clone, Debug, Deserialize)]
|
|
#[cfg(feature = "unstable-msc3246")]
|
|
pub struct AudioMessageEventContentDeHelper {
|
|
/// The textual representation of this message.
|
|
pub body: String,
|
|
|
|
/// The source of the audio clip.
|
|
#[serde(flatten)]
|
|
pub source: MediaSource,
|
|
|
|
/// Metadata for the audio clip referred to in `source`.
|
|
pub info: Option<Box<AudioInfo>>,
|
|
|
|
/// Extensible-event text representation of the message.
|
|
#[serde(flatten)]
|
|
pub message: Option<MessageContent>,
|
|
|
|
/// Extensible-event file content of the message, with stable name.
|
|
#[serde(rename = "m.file")]
|
|
pub file_stable: Option<FileContent>,
|
|
|
|
/// Extensible-event file content of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.file")]
|
|
pub file_unstable: Option<FileContent>,
|
|
|
|
/// Extensible-event audio info of the message, with stable name.
|
|
#[serde(rename = "m.audio")]
|
|
pub audio_stable: Option<AudioContent>,
|
|
|
|
/// Extensible-event audio info of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.audio")]
|
|
pub audio_unstable: Option<AudioContent>,
|
|
|
|
/// Extensible-event voice flag of the message, with stable name.
|
|
#[cfg(feature = "unstable-msc3245")]
|
|
#[serde(rename = "m.voice")]
|
|
pub voice_stable: Option<VoiceContent>,
|
|
|
|
/// Extensible-event voice flag of the message, with unstable name.
|
|
#[cfg(feature = "unstable-msc3245")]
|
|
#[serde(rename = "org.matrix.msc3245.voice")]
|
|
pub voice_unstable: Option<VoiceContent>,
|
|
}
|
|
|
|
#[cfg(feature = "unstable-msc3246")]
|
|
impl From<AudioMessageEventContentDeHelper> for AudioMessageEventContent {
|
|
fn from(helper: AudioMessageEventContentDeHelper) -> Self {
|
|
let AudioMessageEventContentDeHelper {
|
|
body,
|
|
source,
|
|
info,
|
|
message,
|
|
file_stable,
|
|
file_unstable,
|
|
audio_stable,
|
|
audio_unstable,
|
|
#[cfg(feature = "unstable-msc3245")]
|
|
voice_stable,
|
|
#[cfg(feature = "unstable-msc3245")]
|
|
voice_unstable,
|
|
} = helper;
|
|
|
|
let file = file_stable.or(file_unstable);
|
|
let audio = audio_stable.or(audio_unstable);
|
|
#[cfg(feature = "unstable-msc3245")]
|
|
let voice = voice_stable.or(voice_unstable);
|
|
|
|
Self {
|
|
body,
|
|
source,
|
|
info,
|
|
message,
|
|
file,
|
|
audio,
|
|
#[cfg(feature = "unstable-msc3245")]
|
|
voice,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Helper struct for deserializing `FileMessageEventContent` with stable and unstable field names.
|
|
///
|
|
/// It's not possible to use the `alias` attribute of serde because of
|
|
/// https://github.com/serde-rs/serde/issues/1504.
|
|
#[derive(Clone, Debug, Deserialize)]
|
|
#[cfg(feature = "unstable-msc3551")]
|
|
pub struct FileMessageEventContentDeHelper {
|
|
/// A human-readable description of the file.
|
|
pub body: String,
|
|
|
|
/// The original filename of the uploaded file.
|
|
pub filename: Option<String>,
|
|
|
|
/// The source of the file.
|
|
#[serde(flatten)]
|
|
pub source: MediaSource,
|
|
|
|
/// Metadata about the file referred to in `url`.
|
|
pub info: Option<Box<FileInfo>>,
|
|
|
|
/// Extensible-event text representation of the message.
|
|
#[serde(flatten)]
|
|
pub message: Option<MessageContent>,
|
|
|
|
/// Extensible-event file content of the message, with stable name.
|
|
#[serde(rename = "m.file")]
|
|
pub file_stable: Option<FileContent>,
|
|
|
|
/// Extensible-event file content of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.file")]
|
|
pub file_unstable: Option<FileContent>,
|
|
}
|
|
|
|
#[cfg(feature = "unstable-msc3551")]
|
|
impl From<FileMessageEventContentDeHelper> for FileMessageEventContent {
|
|
fn from(helper: FileMessageEventContentDeHelper) -> Self {
|
|
let FileMessageEventContentDeHelper {
|
|
body,
|
|
filename,
|
|
source,
|
|
info,
|
|
message,
|
|
file_stable,
|
|
file_unstable,
|
|
} = helper;
|
|
|
|
let file = file_stable.or(file_unstable);
|
|
|
|
Self { body, filename, source, info, message, file }
|
|
}
|
|
}
|
|
|
|
/// Helper struct for deserializing `ImageMessageEventContent` with stable and unstable field names.
|
|
///
|
|
/// It's not possible to use the `alias` attribute of serde because of
|
|
/// https://github.com/serde-rs/serde/issues/1504.
|
|
#[derive(Clone, Debug, Deserialize)]
|
|
#[cfg(feature = "unstable-msc3552")]
|
|
pub struct ImageMessageEventContentDeHelper {
|
|
/// A textual representation of the image.
|
|
pub body: String,
|
|
|
|
/// The source of the image.
|
|
#[serde(flatten)]
|
|
pub source: MediaSource,
|
|
|
|
/// Metadata about the image referred to in `source`.
|
|
pub info: Option<Box<ImageInfo>>,
|
|
|
|
/// Extensible-event text representation of the message.
|
|
#[serde(flatten)]
|
|
pub message: Option<MessageContent>,
|
|
|
|
/// Extensible-event file content of the message, with unstable name.
|
|
#[serde(rename = "m.file")]
|
|
pub file_stable: Option<FileContent>,
|
|
|
|
/// Extensible-event file content of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.file")]
|
|
pub file_unstable: Option<FileContent>,
|
|
|
|
/// Extensible-event image info of the message, with stable name.
|
|
#[serde(rename = "m.image")]
|
|
pub image_stable: Option<Box<ImageContent>>,
|
|
|
|
/// Extensible-event image info of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.image")]
|
|
pub image_unstable: Option<Box<ImageContent>>,
|
|
|
|
/// Extensible-event thumbnails of the message, with stable name.
|
|
#[serde(rename = "m.thumbnail")]
|
|
pub thumbnail_stable: Option<Vec<ThumbnailContent>>,
|
|
|
|
/// Extensible-event thumbnails of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.thumbnail")]
|
|
pub thumbnail_unstable: Option<Vec<ThumbnailContent>>,
|
|
|
|
/// Extensible-event captions of the message, with stable name.
|
|
#[serde(rename = "m.caption")]
|
|
pub caption_stable: Option<MessageContent>,
|
|
|
|
/// Extensible-event captions of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.caption")]
|
|
pub caption_unstable: Option<MessageContent>,
|
|
}
|
|
|
|
#[cfg(feature = "unstable-msc3552")]
|
|
impl From<ImageMessageEventContentDeHelper> for ImageMessageEventContent {
|
|
fn from(helper: ImageMessageEventContentDeHelper) -> Self {
|
|
let ImageMessageEventContentDeHelper {
|
|
body,
|
|
source,
|
|
info,
|
|
message,
|
|
file_stable,
|
|
file_unstable,
|
|
image_stable,
|
|
image_unstable,
|
|
thumbnail_stable,
|
|
thumbnail_unstable,
|
|
caption_stable,
|
|
caption_unstable,
|
|
} = helper;
|
|
|
|
let file = file_stable.or(file_unstable);
|
|
let image = image_stable.or(image_unstable);
|
|
let thumbnail = thumbnail_stable.or(thumbnail_unstable);
|
|
let caption = caption_stable.or(caption_unstable);
|
|
|
|
Self { body, source, info, message, file, image, thumbnail, caption }
|
|
}
|
|
}
|
|
|
|
/// Helper struct for deserializing `VideoMessageEventContent` with stable and unstable field names.
|
|
///
|
|
/// It's not possible to use the `alias` attribute of serde because of
|
|
/// https://github.com/serde-rs/serde/issues/1504.
|
|
#[derive(Clone, Debug, Deserialize)]
|
|
#[cfg(feature = "unstable-msc3553")]
|
|
pub struct VideoMessageEventContentDeHelper {
|
|
/// A description of the video.
|
|
pub body: String,
|
|
|
|
/// The source of the video clip.
|
|
#[serde(flatten)]
|
|
pub source: MediaSource,
|
|
|
|
/// Metadata about the video clip referred to in `source`.
|
|
pub info: Option<Box<VideoInfo>>,
|
|
|
|
/// Extensible-event text representation of the message.
|
|
#[serde(flatten)]
|
|
pub message: Option<MessageContent>,
|
|
|
|
/// Extensible-event file content of the message, with stable name.
|
|
#[serde(rename = "m.file")]
|
|
pub file_stable: Option<FileContent>,
|
|
|
|
/// Extensible-event file content of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.file")]
|
|
pub file_unstable: Option<FileContent>,
|
|
|
|
/// Extensible-event video info of the message, with stable name.
|
|
#[serde(rename = "m.video")]
|
|
pub video_stable: Option<Box<VideoContent>>,
|
|
|
|
/// Extensible-event video info of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.video")]
|
|
pub video_unstable: Option<Box<VideoContent>>,
|
|
|
|
/// Extensible-event thumbnails of the message, with stable name.
|
|
#[serde(rename = "m.thumbnail")]
|
|
pub thumbnail_stable: Option<Vec<ThumbnailContent>>,
|
|
|
|
/// Extensible-event thumbnails of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.thumbnail")]
|
|
pub thumbnail_unstable: Option<Vec<ThumbnailContent>>,
|
|
|
|
/// Extensible-event captions of the message, with stable name.
|
|
#[serde(rename = "m.caption")]
|
|
pub caption_stable: Option<MessageContent>,
|
|
|
|
/// Extensible-event captions of the message, with unstable name.
|
|
#[serde(rename = "org.matrix.msc1767.caption")]
|
|
pub caption_unstable: Option<MessageContent>,
|
|
}
|
|
|
|
#[cfg(feature = "unstable-msc3553")]
|
|
impl From<VideoMessageEventContentDeHelper> for VideoMessageEventContent {
|
|
fn from(helper: VideoMessageEventContentDeHelper) -> Self {
|
|
let VideoMessageEventContentDeHelper {
|
|
body,
|
|
source,
|
|
info,
|
|
message,
|
|
file_stable,
|
|
file_unstable,
|
|
video_stable,
|
|
video_unstable,
|
|
thumbnail_stable,
|
|
thumbnail_unstable,
|
|
caption_stable,
|
|
caption_unstable,
|
|
} = helper;
|
|
|
|
let file = file_stable.or(file_unstable);
|
|
let video = video_stable.or(video_unstable);
|
|
let thumbnail = thumbnail_stable.or(thumbnail_unstable);
|
|
let caption = caption_stable.or(caption_unstable);
|
|
|
|
Self { body, source, info, message, file, video, thumbnail, caption }
|
|
}
|
|
}
|