events: Use an enum for a media's source
Have stricter media types that accept either an encrypted or plain file. Co-authored-by: Jonas Platte <jplatte@element.io>
This commit is contained in:
parent
9da6bd4861
commit
12ee658e96
@ -1,5 +1,10 @@
|
|||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
Breaking changes:
|
||||||
|
|
||||||
|
* Change `events::room` media types to accept either a plain file or an
|
||||||
|
encrypted file, not both simultaneously
|
||||||
|
|
||||||
# 0.8.0
|
# 0.8.0
|
||||||
|
|
||||||
Breaking changes:
|
Breaking changes:
|
||||||
|
@ -29,9 +29,23 @@ pub mod power_levels;
|
|||||||
pub mod redaction;
|
pub mod redaction;
|
||||||
pub mod server_acl;
|
pub mod server_acl;
|
||||||
pub mod third_party_invite;
|
pub mod third_party_invite;
|
||||||
|
mod thumbnail_src_serde;
|
||||||
pub mod tombstone;
|
pub mod tombstone;
|
||||||
pub mod topic;
|
pub mod topic;
|
||||||
|
|
||||||
|
/// The source of a media file.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
|
pub enum MediaSource {
|
||||||
|
/// The MXC URI to the unencrypted media file.
|
||||||
|
#[serde(rename = "url")]
|
||||||
|
Plain(Box<MxcUri>),
|
||||||
|
|
||||||
|
/// The encryption info of the encrypted media file.
|
||||||
|
#[serde(rename = "file")]
|
||||||
|
Encrypted(Box<EncryptedFile>),
|
||||||
|
}
|
||||||
|
|
||||||
/// Metadata about an image.
|
/// Metadata about an image.
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
@ -52,21 +66,13 @@ pub struct ImageInfo {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub size: Option<UInt>,
|
pub size: Option<UInt>,
|
||||||
|
|
||||||
/// Metadata about the image referred to in `thumbnail_url`.
|
/// Metadata about the image referred to in `thumbnail_src`.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
||||||
|
|
||||||
/// The URL to the thumbnail of the image.
|
/// The source of the thumbnail of the image.
|
||||||
///
|
#[serde(flatten, with = "thumbnail_src_serde", skip_serializing_if = "Option::is_none")]
|
||||||
/// Only present if the thumbnail is unencrypted.
|
pub thumbnail_src: Option<MediaSource>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub thumbnail_url: Option<Box<MxcUri>>,
|
|
||||||
|
|
||||||
/// Information on the encrypted thumbnail image.
|
|
||||||
///
|
|
||||||
/// Only present if the thumbnail is encrypted.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub thumbnail_file: Option<Box<EncryptedFile>>,
|
|
||||||
|
|
||||||
/// The [BlurHash](https://blurha.sh) for this image.
|
/// The [BlurHash](https://blurha.sh) for this image.
|
||||||
///
|
///
|
||||||
|
@ -9,7 +9,7 @@ use ruma_macros::EventContent;
|
|||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::Value as JsonValue;
|
||||||
|
|
||||||
use super::{EncryptedFile, ImageInfo, ThumbnailInfo};
|
use super::{EncryptedFile, ImageInfo, MediaSource, ThumbnailInfo};
|
||||||
#[cfg(feature = "unstable-msc1767")]
|
#[cfg(feature = "unstable-msc1767")]
|
||||||
use crate::events::{
|
use crate::events::{
|
||||||
emote::EmoteEventContent,
|
emote::EmoteEventContent,
|
||||||
@ -474,17 +474,9 @@ pub struct AudioMessageEventContent {
|
|||||||
/// The textual representation of this message.
|
/// The textual representation of this message.
|
||||||
pub body: String,
|
pub body: String,
|
||||||
|
|
||||||
/// The URL to the audio clip.
|
/// The source of the audio clip.
|
||||||
///
|
#[serde(flatten)]
|
||||||
/// Required if the file is unencrypted.
|
pub src: MediaSource,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub url: Option<Box<MxcUri>>,
|
|
||||||
|
|
||||||
/// Information on the encrypted audio clip.
|
|
||||||
///
|
|
||||||
/// Required if the audio clip is encrypted.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub file: Option<Box<EncryptedFile>>,
|
|
||||||
|
|
||||||
/// Metadata for the audio clip referred to in `url`.
|
/// Metadata for the audio clip referred to in `url`.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@ -495,13 +487,13 @@ impl AudioMessageEventContent {
|
|||||||
/// Creates a new non-encrypted `RoomAudioMessageEventContent` with the given body, url and
|
/// Creates a new non-encrypted `RoomAudioMessageEventContent` with the given body, url and
|
||||||
/// optional extra info.
|
/// optional extra info.
|
||||||
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<AudioInfo>>) -> Self {
|
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<AudioInfo>>) -> Self {
|
||||||
Self { body, url: Some(url), info, file: None }
|
Self { body, src: MediaSource::Plain(url), info }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new encrypted `RoomAudioMessageEventContent` with the given body and encrypted
|
/// Creates a new encrypted `RoomAudioMessageEventContent` with the given body and encrypted
|
||||||
/// file.
|
/// file.
|
||||||
pub fn encrypted(body: String, file: EncryptedFile) -> Self {
|
pub fn encrypted(body: String, file: EncryptedFile) -> Self {
|
||||||
Self { body, url: None, info: None, file: Some(Box::new(file)) }
|
Self { body, src: MediaSource::Encrypted(Box::new(file)), info: None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,15 +608,9 @@ pub struct FileMessageEventContent {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub filename: Option<String>,
|
pub filename: Option<String>,
|
||||||
|
|
||||||
/// The URL to the file.
|
/// The source of the file.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(flatten)]
|
||||||
pub url: Option<Box<MxcUri>>,
|
pub src: MediaSource,
|
||||||
|
|
||||||
/// Information on the encrypted file.
|
|
||||||
///
|
|
||||||
/// Required if file is encrypted.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub file: Option<Box<EncryptedFile>>,
|
|
||||||
|
|
||||||
/// Metadata about the file referred to in `url`.
|
/// Metadata about the file referred to in `url`.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@ -635,13 +621,13 @@ impl FileMessageEventContent {
|
|||||||
/// Creates a new non-encrypted `RoomFileMessageEventContent` with the given body, url and
|
/// Creates a new non-encrypted `RoomFileMessageEventContent` with the given body, url and
|
||||||
/// optional extra info.
|
/// optional extra info.
|
||||||
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<FileInfo>>) -> Self {
|
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<FileInfo>>) -> Self {
|
||||||
Self { body, filename: None, url: Some(url), info, file: None }
|
Self { body, filename: None, src: MediaSource::Plain(url), info }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new encrypted `RoomFileMessageEventContent` with the given body and encrypted
|
/// Creates a new encrypted `RoomFileMessageEventContent` with the given body and encrypted
|
||||||
/// file.
|
/// file.
|
||||||
pub fn encrypted(body: String, file: EncryptedFile) -> Self {
|
pub fn encrypted(body: String, file: EncryptedFile) -> Self {
|
||||||
Self { body, filename: None, url: None, info: None, file: Some(Box::new(file)) }
|
Self { body, filename: None, src: MediaSource::Encrypted(Box::new(file)), info: None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,21 +643,13 @@ pub struct FileInfo {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub size: Option<UInt>,
|
pub size: Option<UInt>,
|
||||||
|
|
||||||
/// Metadata about the image referred to in `thumbnail_url`.
|
/// Metadata about the image referred to in `thumbnail_src`.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
||||||
|
|
||||||
/// The URL to the thumbnail of the file.
|
/// The source of the thumbnail of the file.
|
||||||
///
|
#[serde(flatten, with = "super::thumbnail_src_serde", skip_serializing_if = "Option::is_none")]
|
||||||
/// Only present if the thumbnail is unencrypted.
|
pub thumbnail_src: Option<MediaSource>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub thumbnail_url: Option<Box<MxcUri>>,
|
|
||||||
|
|
||||||
/// Information on the encrypted thumbnail file.
|
|
||||||
///
|
|
||||||
/// Only present if the thumbnail is encrypted.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub thumbnail_file: Option<Box<EncryptedFile>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileInfo {
|
impl FileInfo {
|
||||||
@ -692,15 +670,9 @@ pub struct ImageMessageEventContent {
|
|||||||
/// description for accessibility e.g. "image attachment".
|
/// description for accessibility e.g. "image attachment".
|
||||||
pub body: String,
|
pub body: String,
|
||||||
|
|
||||||
/// The URL to the image.
|
/// The source of the image.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(flatten)]
|
||||||
pub url: Option<Box<MxcUri>>,
|
pub src: MediaSource,
|
||||||
|
|
||||||
/// Information on the encrypted image.
|
|
||||||
///
|
|
||||||
/// Required if image is encrypted.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub file: Option<Box<EncryptedFile>>,
|
|
||||||
|
|
||||||
/// Metadata about the image referred to in `url`.
|
/// Metadata about the image referred to in `url`.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@ -711,13 +683,13 @@ impl ImageMessageEventContent {
|
|||||||
/// Creates a new non-encrypted `RoomImageMessageEventContent` with the given body, url and
|
/// Creates a new non-encrypted `RoomImageMessageEventContent` with the given body, url and
|
||||||
/// optional extra info.
|
/// optional extra info.
|
||||||
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<ImageInfo>>) -> Self {
|
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<ImageInfo>>) -> Self {
|
||||||
Self { body, url: Some(url), info, file: None }
|
Self { body, src: MediaSource::Plain(url), info }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new encrypted `RoomImageMessageEventContent` with the given body and encrypted
|
/// Creates a new encrypted `RoomImageMessageEventContent` with the given body and encrypted
|
||||||
/// file.
|
/// file.
|
||||||
pub fn encrypted(body: String, file: EncryptedFile) -> Self {
|
pub fn encrypted(body: String, file: EncryptedFile) -> Self {
|
||||||
Self { body, url: None, info: None, file: Some(Box::new(file)) }
|
Self { body, src: MediaSource::Encrypted(Box::new(file)), info: None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,19 +721,11 @@ impl LocationMessageEventContent {
|
|||||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||||
pub struct LocationInfo {
|
pub struct LocationInfo {
|
||||||
/// The URL to a thumbnail of the location being represented.
|
/// The URL to a thumbnail of the location.
|
||||||
///
|
#[serde(flatten, with = "super::thumbnail_src_serde", skip_serializing_if = "Option::is_none")]
|
||||||
/// Only present if the thumbnail is unencrypted.
|
pub thumbnail_src: Option<MediaSource>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub thumbnail_url: Option<Box<MxcUri>>,
|
|
||||||
|
|
||||||
/// Information on an encrypted thumbnail of the location being represented.
|
/// Metadata about the image referred to in `thumbnail_src.
|
||||||
///
|
|
||||||
/// Only present if the thumbnail is encrypted.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub thumbnail_file: Option<Box<EncryptedFile>>,
|
|
||||||
|
|
||||||
/// Metadata about the image referred to in `thumbnail_url` or `thumbnail_file`.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
||||||
}
|
}
|
||||||
@ -1053,15 +1017,9 @@ pub struct VideoMessageEventContent {
|
|||||||
/// accessibility, e.g. "video attachment".
|
/// accessibility, e.g. "video attachment".
|
||||||
pub body: String,
|
pub body: String,
|
||||||
|
|
||||||
/// The URL to the video clip.
|
/// The source of the video clip.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(flatten)]
|
||||||
pub url: Option<Box<MxcUri>>,
|
pub src: MediaSource,
|
||||||
|
|
||||||
/// Information on the encrypted video clip.
|
|
||||||
///
|
|
||||||
/// Required if video clip is encrypted.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub file: Option<Box<EncryptedFile>>,
|
|
||||||
|
|
||||||
/// Metadata about the video clip referred to in `url`.
|
/// Metadata about the video clip referred to in `url`.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
@ -1072,13 +1030,13 @@ impl VideoMessageEventContent {
|
|||||||
/// Creates a new non-encrypted `RoomVideoMessageEventContent` with the given body, url and
|
/// Creates a new non-encrypted `RoomVideoMessageEventContent` with the given body, url and
|
||||||
/// optional extra info.
|
/// optional extra info.
|
||||||
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<VideoInfo>>) -> Self {
|
pub fn plain(body: String, url: Box<MxcUri>, info: Option<Box<VideoInfo>>) -> Self {
|
||||||
Self { body, url: Some(url), info, file: None }
|
Self { body, src: MediaSource::Plain(url), info }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new encrypted `RoomVideoMessageEventContent` with the given body and encrypted
|
/// Creates a new encrypted `RoomVideoMessageEventContent` with the given body and encrypted
|
||||||
/// file.
|
/// file.
|
||||||
pub fn encrypted(body: String, file: EncryptedFile) -> Self {
|
pub fn encrypted(body: String, file: EncryptedFile) -> Self {
|
||||||
Self { body, url: None, info: None, file: Some(Box::new(file)) }
|
Self { body, src: MediaSource::Encrypted(Box::new(file)), info: None }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1110,21 +1068,13 @@ pub struct VideoInfo {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub size: Option<UInt>,
|
pub size: Option<UInt>,
|
||||||
|
|
||||||
/// Metadata about an image.
|
/// Metadata about the image referred to in `thumbnail_src`.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
||||||
|
|
||||||
/// The URL to an image thumbnail of the video clip.
|
/// The source of the thumbnail of the video clip.
|
||||||
///
|
#[serde(flatten, with = "super::thumbnail_src_serde", skip_serializing_if = "Option::is_none")]
|
||||||
/// Only present if the thumbnail is unencrypted.
|
pub thumbnail_src: Option<MediaSource>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub thumbnail_url: Option<Box<MxcUri>>,
|
|
||||||
|
|
||||||
/// Information on the encrypted thumbnail file.
|
|
||||||
///
|
|
||||||
/// Only present if the thumbnail is encrypted.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub thumbnail_file: Option<Box<EncryptedFile>>,
|
|
||||||
|
|
||||||
/// The [BlurHash](https://blurha.sh) for this video.
|
/// The [BlurHash](https://blurha.sh) for this video.
|
||||||
///
|
///
|
||||||
|
207
crates/ruma-common/src/events/room/thumbnail_src_serde.rs
Normal file
207
crates/ruma-common/src/events/room/thumbnail_src_serde.rs
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
//! De-/serialization functions for `Option<MediaSource>` objects representing a thumbnail source.
|
||||||
|
|
||||||
|
use serde::{
|
||||||
|
de::Deserializer,
|
||||||
|
ser::{SerializeStruct, Serializer},
|
||||||
|
Deserialize,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::MxcUri;
|
||||||
|
|
||||||
|
use super::{EncryptedFile, MediaSource};
|
||||||
|
|
||||||
|
/// Serializes a MediaSource to a thumbnail source.
|
||||||
|
pub fn serialize<S>(src: &Option<MediaSource>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
if let Some(src) = src {
|
||||||
|
let mut st = serializer.serialize_struct("ThumbnailSource", 1)?;
|
||||||
|
match src {
|
||||||
|
MediaSource::Plain(url) => st.serialize_field("thumbnail_url", url)?,
|
||||||
|
MediaSource::Encrypted(file) => st.serialize_field("thumbnail_file", file)?,
|
||||||
|
}
|
||||||
|
st.end()
|
||||||
|
} else {
|
||||||
|
serializer.serialize_none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserializes a thumbnail source to a MediaSource.
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<MediaSource>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Option::<ThumbnailSource>::deserialize(deserializer).map(|src| src.map(Into::into))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
enum ThumbnailSource {
|
||||||
|
/// The MXC URI to the unencrypted media file.
|
||||||
|
#[serde(rename = "thumbnail_url")]
|
||||||
|
Plain(Box<MxcUri>),
|
||||||
|
|
||||||
|
/// The encryption info of the encrypted media file.
|
||||||
|
#[serde(rename = "thumbnail_file")]
|
||||||
|
Encrypted(Box<EncryptedFile>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ThumbnailSource> for MediaSource {
|
||||||
|
fn from(src: ThumbnailSource) -> Self {
|
||||||
|
match src {
|
||||||
|
ThumbnailSource::Plain(url) => Self::Plain(url),
|
||||||
|
ThumbnailSource::Encrypted(file) => Self::Encrypted(file),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use matches::assert_matches;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
events::room::{EncryptedFileInit, JsonWebKeyInit, MediaSource},
|
||||||
|
mxc_uri,
|
||||||
|
serde::Base64,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
struct ThumbnailSourceTest {
|
||||||
|
#[serde(flatten, with = "super", skip_serializing_if = "Option::is_none")]
|
||||||
|
src: Option<MediaSource>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_plain() {
|
||||||
|
let json = json!({ "thumbnail_url": "mxc://notareal.hs/abcdef" });
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
serde_json::from_value::<ThumbnailSourceTest>(json).unwrap(),
|
||||||
|
ThumbnailSourceTest { src: Some(MediaSource::Plain(url)) }
|
||||||
|
if url == "mxc://notareal.hs/abcdef"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_encrypted() {
|
||||||
|
let json = json!({
|
||||||
|
"thumbnail_file": {
|
||||||
|
"url": "mxc://notareal.hs/abcdef",
|
||||||
|
"key": {
|
||||||
|
"kty": "oct",
|
||||||
|
"key_ops": ["encrypt", "decrypt"],
|
||||||
|
"alg": "A256CTR",
|
||||||
|
"k": "TLlG_OpX807zzQuuwv4QZGJ21_u7weemFGYJFszMn9A",
|
||||||
|
"ext": true
|
||||||
|
},
|
||||||
|
"iv": "S22dq3NAX8wAAAAAAAAAAA",
|
||||||
|
"hashes": {
|
||||||
|
"sha256": "aWOHudBnDkJ9IwaR1Nd8XKoI7DOrqDTwt6xDPfVGN6Q"
|
||||||
|
},
|
||||||
|
"v": "v2",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
serde_json::from_value::<ThumbnailSourceTest>(json).unwrap(),
|
||||||
|
ThumbnailSourceTest { src: Some(MediaSource::Encrypted(file)) }
|
||||||
|
if file.url == "mxc://notareal.hs/abcdef"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_none_by_absence() {
|
||||||
|
let json = json!({});
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
serde_json::from_value::<ThumbnailSourceTest>(json).unwrap(),
|
||||||
|
ThumbnailSourceTest { src: None }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_none_by_null_plain() {
|
||||||
|
let json = json!({ "thumbnail_url": null });
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
serde_json::from_value::<ThumbnailSourceTest>(json).unwrap(),
|
||||||
|
ThumbnailSourceTest { src: None }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn deserialize_none_by_null_encrypted() {
|
||||||
|
let json = json!({ "thumbnail_file": null });
|
||||||
|
|
||||||
|
assert_matches!(
|
||||||
|
serde_json::from_value::<ThumbnailSourceTest>(json).unwrap(),
|
||||||
|
ThumbnailSourceTest { src: None }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serialize_plain() {
|
||||||
|
let request = ThumbnailSourceTest {
|
||||||
|
src: Some(MediaSource::Plain(mxc_uri!("mxc://notareal.hs/abcdef").into())),
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::to_value(&request).unwrap(),
|
||||||
|
json!({ "thumbnail_url": "mxc://notareal.hs/abcdef" })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serialize_encrypted() {
|
||||||
|
let request = ThumbnailSourceTest {
|
||||||
|
src: Some(MediaSource::Encrypted(Box::new(
|
||||||
|
EncryptedFileInit {
|
||||||
|
url: mxc_uri!("mxc://notareal.hs/abcdef").to_owned(),
|
||||||
|
key: JsonWebKeyInit {
|
||||||
|
kty: "oct".to_owned(),
|
||||||
|
key_ops: vec!["encrypt".to_owned(), "decrypt".to_owned()],
|
||||||
|
alg: "A256CTR".to_owned(),
|
||||||
|
k: Base64::parse("TLlG_OpX807zzQuuwv4QZGJ21_u7weemFGYJFszMn9A").unwrap(),
|
||||||
|
ext: true,
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
iv: Base64::parse("S22dq3NAX8wAAAAAAAAAAA").unwrap(),
|
||||||
|
hashes: [(
|
||||||
|
"sha256".to_owned(),
|
||||||
|
Base64::parse("aWOHudBnDkJ9IwaR1Nd8XKoI7DOrqDTwt6xDPfVGN6Q").unwrap(),
|
||||||
|
)]
|
||||||
|
.into(),
|
||||||
|
v: "v2".to_owned(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
))),
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::to_value(&request).unwrap(),
|
||||||
|
json!({
|
||||||
|
"thumbnail_file": {
|
||||||
|
"url": "mxc://notareal.hs/abcdef",
|
||||||
|
"key": {
|
||||||
|
"kty": "oct",
|
||||||
|
"key_ops": ["encrypt", "decrypt"],
|
||||||
|
"alg": "A256CTR",
|
||||||
|
"k": "TLlG_OpX807zzQuuwv4QZGJ21_u7weemFGYJFszMn9A",
|
||||||
|
"ext": true
|
||||||
|
},
|
||||||
|
"iv": "S22dq3NAX8wAAAAAAAAAAA",
|
||||||
|
"hashes": {
|
||||||
|
"sha256": "aWOHudBnDkJ9IwaR1Nd8XKoI7DOrqDTwt6xDPfVGN6Q"
|
||||||
|
},
|
||||||
|
"v": "v2",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serialize_none() {
|
||||||
|
let request = ThumbnailSourceTest { src: None };
|
||||||
|
assert_eq!(serde_json::to_value(&request).unwrap(), json!({}));
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ use ruma_common::{
|
|||||||
event_id,
|
event_id,
|
||||||
events::{
|
events::{
|
||||||
call::{answer::CallAnswerEventContent, SessionDescription, SessionDescriptionType},
|
call::{answer::CallAnswerEventContent, SessionDescription, SessionDescriptionType},
|
||||||
room::{ImageInfo, ThumbnailInfo},
|
room::{ImageInfo, MediaSource, ThumbnailInfo},
|
||||||
sticker::StickerEventContent,
|
sticker::StickerEventContent,
|
||||||
AnyMessageLikeEvent, AnyMessageLikeEventContent, AnySyncMessageLikeEvent, MessageLikeEvent,
|
AnyMessageLikeEvent, AnyMessageLikeEventContent, AnySyncMessageLikeEvent, MessageLikeEvent,
|
||||||
MessageLikeEventType, MessageLikeUnsigned,
|
MessageLikeEventType, MessageLikeUnsigned,
|
||||||
@ -32,7 +32,7 @@ fn message_serialize_sticker() {
|
|||||||
mimetype: Some("image/png".into()),
|
mimetype: Some("image/png".into()),
|
||||||
size: UInt::new(82595),
|
size: UInt::new(82595),
|
||||||
}))),
|
}))),
|
||||||
thumbnail_url: Some(mxc_uri!("mxc://matrix.org/irsns989Rrsn").to_owned()),
|
thumbnail_src: Some(MediaSource::Plain(mxc_uri!("mxc://matrix.org/irsns989Rrsn").to_owned())),
|
||||||
}),
|
}),
|
||||||
mxc_uri!("mxc://matrix.org/rnsldl8srs98IRrs").to_owned(),
|
mxc_uri!("mxc://matrix.org/rnsldl8srs98IRrs").to_owned(),
|
||||||
),
|
),
|
||||||
@ -184,8 +184,7 @@ fn deserialize_message_sticker() {
|
|||||||
mimetype: Some(mimetype),
|
mimetype: Some(mimetype),
|
||||||
size,
|
size,
|
||||||
thumbnail_info: Some(thumbnail_info),
|
thumbnail_info: Some(thumbnail_info),
|
||||||
thumbnail_url: Some(thumbnail_url),
|
thumbnail_src: Some(MediaSource::Plain(thumbnail_url)),
|
||||||
thumbnail_file: None,
|
|
||||||
#[cfg(feature = "unstable-msc2448")]
|
#[cfg(feature = "unstable-msc2448")]
|
||||||
blurhash: None,
|
blurhash: None,
|
||||||
..
|
..
|
||||||
|
@ -12,9 +12,12 @@ use ruma_common::{
|
|||||||
event_id,
|
event_id,
|
||||||
events::{
|
events::{
|
||||||
key::verification::VerificationMethod,
|
key::verification::VerificationMethod,
|
||||||
room::message::{
|
room::{
|
||||||
AudioMessageEventContent, KeyVerificationRequestEventContent, MessageType,
|
message::{
|
||||||
RoomMessageEvent, RoomMessageEventContent, TextMessageEventContent,
|
AudioMessageEventContent, KeyVerificationRequestEventContent, MessageType,
|
||||||
|
RoomMessageEvent, RoomMessageEventContent, TextMessageEventContent,
|
||||||
|
},
|
||||||
|
MediaSource,
|
||||||
},
|
},
|
||||||
MessageLikeUnsigned,
|
MessageLikeUnsigned,
|
||||||
},
|
},
|
||||||
@ -443,8 +446,7 @@ fn content_deserialization() {
|
|||||||
msgtype: MessageType::Audio(AudioMessageEventContent {
|
msgtype: MessageType::Audio(AudioMessageEventContent {
|
||||||
body,
|
body,
|
||||||
info: None,
|
info: None,
|
||||||
url: Some(url),
|
src: MediaSource::Plain(url),
|
||||||
file: None,
|
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
..
|
..
|
||||||
|
Loading…
x
Reference in New Issue
Block a user