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]
|
||||
|
||||
Breaking changes:
|
||||
|
||||
* Change `events::room` media types to accept either a plain file or an
|
||||
encrypted file, not both simultaneously
|
||||
|
||||
# 0.8.0
|
||||
|
||||
Breaking changes:
|
||||
|
@ -29,9 +29,23 @@ pub mod power_levels;
|
||||
pub mod redaction;
|
||||
pub mod server_acl;
|
||||
pub mod third_party_invite;
|
||||
mod thumbnail_src_serde;
|
||||
pub mod tombstone;
|
||||
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.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
@ -52,21 +66,13 @@ pub struct ImageInfo {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
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")]
|
||||
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
||||
|
||||
/// The URL to the thumbnail of the image.
|
||||
///
|
||||
/// Only present if the thumbnail is unencrypted.
|
||||
#[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 source of the thumbnail of the image.
|
||||
#[serde(flatten, with = "thumbnail_src_serde", skip_serializing_if = "Option::is_none")]
|
||||
pub thumbnail_src: Option<MediaSource>,
|
||||
|
||||
/// The [BlurHash](https://blurha.sh) for this image.
|
||||
///
|
||||
|
@ -9,7 +9,7 @@ use ruma_macros::EventContent;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use serde_json::Value as JsonValue;
|
||||
|
||||
use super::{EncryptedFile, ImageInfo, ThumbnailInfo};
|
||||
use super::{EncryptedFile, ImageInfo, MediaSource, ThumbnailInfo};
|
||||
#[cfg(feature = "unstable-msc1767")]
|
||||
use crate::events::{
|
||||
emote::EmoteEventContent,
|
||||
@ -474,17 +474,9 @@ pub struct AudioMessageEventContent {
|
||||
/// The textual representation of this message.
|
||||
pub body: String,
|
||||
|
||||
/// The URL to the audio clip.
|
||||
///
|
||||
/// Required if the file is unencrypted.
|
||||
#[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>>,
|
||||
/// The source of the audio clip.
|
||||
#[serde(flatten)]
|
||||
pub src: MediaSource,
|
||||
|
||||
/// Metadata for the audio clip referred to in `url`.
|
||||
#[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
|
||||
/// optional extra info.
|
||||
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
|
||||
/// file.
|
||||
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")]
|
||||
pub filename: Option<String>,
|
||||
|
||||
/// The URL to the file.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub url: Option<Box<MxcUri>>,
|
||||
|
||||
/// Information on the encrypted file.
|
||||
///
|
||||
/// Required if file is encrypted.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub file: Option<Box<EncryptedFile>>,
|
||||
/// The source of the file.
|
||||
#[serde(flatten)]
|
||||
pub src: MediaSource,
|
||||
|
||||
/// Metadata about the file referred to in `url`.
|
||||
#[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
|
||||
/// optional extra info.
|
||||
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
|
||||
/// file.
|
||||
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")]
|
||||
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")]
|
||||
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
||||
|
||||
/// The URL to the thumbnail of the file.
|
||||
///
|
||||
/// Only present if the thumbnail is unencrypted.
|
||||
#[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 source of the thumbnail of the file.
|
||||
#[serde(flatten, with = "super::thumbnail_src_serde", skip_serializing_if = "Option::is_none")]
|
||||
pub thumbnail_src: Option<MediaSource>,
|
||||
}
|
||||
|
||||
impl FileInfo {
|
||||
@ -692,15 +670,9 @@ pub struct ImageMessageEventContent {
|
||||
/// description for accessibility e.g. "image attachment".
|
||||
pub body: String,
|
||||
|
||||
/// The URL to the image.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub url: Option<Box<MxcUri>>,
|
||||
|
||||
/// Information on the encrypted image.
|
||||
///
|
||||
/// Required if image is encrypted.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub file: Option<Box<EncryptedFile>>,
|
||||
/// The source of the image.
|
||||
#[serde(flatten)]
|
||||
pub src: MediaSource,
|
||||
|
||||
/// Metadata about the image referred to in `url`.
|
||||
#[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
|
||||
/// optional extra info.
|
||||
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
|
||||
/// file.
|
||||
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)]
|
||||
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
|
||||
pub struct LocationInfo {
|
||||
/// The URL to a thumbnail of the location being represented.
|
||||
///
|
||||
/// Only present if the thumbnail is unencrypted.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub thumbnail_url: Option<Box<MxcUri>>,
|
||||
/// The URL to a thumbnail of the location.
|
||||
#[serde(flatten, with = "super::thumbnail_src_serde", skip_serializing_if = "Option::is_none")]
|
||||
pub thumbnail_src: Option<MediaSource>,
|
||||
|
||||
/// Information on an encrypted thumbnail of the location being represented.
|
||||
///
|
||||
/// 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`.
|
||||
/// Metadata about the image referred to in `thumbnail_src.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
||||
}
|
||||
@ -1053,15 +1017,9 @@ pub struct VideoMessageEventContent {
|
||||
/// accessibility, e.g. "video attachment".
|
||||
pub body: String,
|
||||
|
||||
/// The URL to the video clip.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub url: Option<Box<MxcUri>>,
|
||||
|
||||
/// Information on the encrypted video clip.
|
||||
///
|
||||
/// Required if video clip is encrypted.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub file: Option<Box<EncryptedFile>>,
|
||||
/// The source of the video clip.
|
||||
#[serde(flatten)]
|
||||
pub src: MediaSource,
|
||||
|
||||
/// Metadata about the video clip referred to in `url`.
|
||||
#[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
|
||||
/// optional extra info.
|
||||
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
|
||||
/// file.
|
||||
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")]
|
||||
pub size: Option<UInt>,
|
||||
|
||||
/// Metadata about an image.
|
||||
/// Metadata about the image referred to in `thumbnail_src`.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub thumbnail_info: Option<Box<ThumbnailInfo>>,
|
||||
|
||||
/// The URL to an image thumbnail of the video clip.
|
||||
///
|
||||
/// Only present if the thumbnail is unencrypted.
|
||||
#[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 source of the thumbnail of the video clip.
|
||||
#[serde(flatten, with = "super::thumbnail_src_serde", skip_serializing_if = "Option::is_none")]
|
||||
pub thumbnail_src: Option<MediaSource>,
|
||||
|
||||
/// 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,
|
||||
events::{
|
||||
call::{answer::CallAnswerEventContent, SessionDescription, SessionDescriptionType},
|
||||
room::{ImageInfo, ThumbnailInfo},
|
||||
room::{ImageInfo, MediaSource, ThumbnailInfo},
|
||||
sticker::StickerEventContent,
|
||||
AnyMessageLikeEvent, AnyMessageLikeEventContent, AnySyncMessageLikeEvent, MessageLikeEvent,
|
||||
MessageLikeEventType, MessageLikeUnsigned,
|
||||
@ -32,7 +32,7 @@ fn message_serialize_sticker() {
|
||||
mimetype: Some("image/png".into()),
|
||||
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(),
|
||||
),
|
||||
@ -184,8 +184,7 @@ fn deserialize_message_sticker() {
|
||||
mimetype: Some(mimetype),
|
||||
size,
|
||||
thumbnail_info: Some(thumbnail_info),
|
||||
thumbnail_url: Some(thumbnail_url),
|
||||
thumbnail_file: None,
|
||||
thumbnail_src: Some(MediaSource::Plain(thumbnail_url)),
|
||||
#[cfg(feature = "unstable-msc2448")]
|
||||
blurhash: None,
|
||||
..
|
||||
|
@ -12,9 +12,12 @@ use ruma_common::{
|
||||
event_id,
|
||||
events::{
|
||||
key::verification::VerificationMethod,
|
||||
room::message::{
|
||||
AudioMessageEventContent, KeyVerificationRequestEventContent, MessageType,
|
||||
RoomMessageEvent, RoomMessageEventContent, TextMessageEventContent,
|
||||
room::{
|
||||
message::{
|
||||
AudioMessageEventContent, KeyVerificationRequestEventContent, MessageType,
|
||||
RoomMessageEvent, RoomMessageEventContent, TextMessageEventContent,
|
||||
},
|
||||
MediaSource,
|
||||
},
|
||||
MessageLikeUnsigned,
|
||||
},
|
||||
@ -443,8 +446,7 @@ fn content_deserialization() {
|
||||
msgtype: MessageType::Audio(AudioMessageEventContent {
|
||||
body,
|
||||
info: None,
|
||||
url: Some(url),
|
||||
file: None,
|
||||
src: MediaSource::Plain(url),
|
||||
..
|
||||
}),
|
||||
..
|
||||
|
Loading…
x
Reference in New Issue
Block a user