events: Add support for transitional extensible sticker messages

According to MSC3552
This commit is contained in:
Kévin Commaille 2022-03-26 15:39:00 +01:00 committed by Kévin Commaille
parent e94a8db7f4
commit f2d35f217c
4 changed files with 202 additions and 1 deletions

View File

@ -5,6 +5,12 @@
use ruma_macros::EventContent;
use serde::{Deserialize, Serialize};
#[cfg(feature = "unstable-msc3552")]
use super::{
file::FileContent,
image::{ImageContent, ThumbnailContent},
message::MessageContent,
};
use crate::{events::room::ImageInfo, MxcUri};
/// The content of an `m.sticker` event.
@ -25,11 +31,80 @@ pub struct StickerEventContent {
/// The URL to the sticker image.
pub url: Box<MxcUri>,
/// Extensible-event text representation of the message.
///
/// If present, this should be preferred over the `body` field.
#[cfg(feature = "unstable-msc3552")]
#[serde(flatten, skip_serializing_if = "Option::is_none")]
pub message: Option<MessageContent>,
/// Extensible-event file content of the message.
///
/// If present, this should be preferred over the `url`, `file` and `info` fields.
#[cfg(feature = "unstable-msc3552")]
#[serde(
rename = "org.matrix.msc1767.file",
alias = "m.file",
skip_serializing_if = "Option::is_none"
)]
pub file: Option<FileContent>,
/// Extensible-event image info of the message.
///
/// If present, this should be preferred over the `info` field.
#[cfg(feature = "unstable-msc3552")]
#[serde(
rename = "org.matrix.msc1767.image",
alias = "m.image",
skip_serializing_if = "Option::is_none"
)]
pub image: Option<Box<ImageContent>>,
/// Extensible-event thumbnails of the message.
///
/// If present, this should be preferred over the `info` field.
#[cfg(feature = "unstable-msc3552")]
#[serde(
rename = "org.matrix.msc1767.thumbnail",
alias = "m.thumbnail",
skip_serializing_if = "Option::is_none"
)]
pub thumbnail: Option<Vec<ThumbnailContent>>,
/// Extensible-event captions of the message.
#[cfg(feature = "unstable-msc3552")]
#[serde(
rename = "org.matrix.msc1767.caption",
alias = "m.caption",
with = "super::message::content_serde::as_vec",
default,
skip_serializing_if = "Option::is_none"
)]
pub caption: Option<MessageContent>,
}
impl StickerEventContent {
/// Creates a new `StickerEventContent` with the given body, image info and URL.
pub fn new(body: String, info: ImageInfo, url: Box<MxcUri>) -> Self {
Self { body, info, url }
Self {
#[cfg(feature = "unstable-msc3552")]
message: Some(MessageContent::plain(body.clone())),
#[cfg(feature = "unstable-msc3552")]
file: Some(FileContent::plain(url.clone(), Some(Box::new((&info).into())))),
#[cfg(feature = "unstable-msc3552")]
image: Some(Box::new((&info).into())),
#[cfg(feature = "unstable-msc3552")]
thumbnail: ThumbnailContent::from_room_message_content(
info.thumbnail_source.as_ref(),
info.thumbnail_info.as_deref(),
)
.map(|thumbnail| vec![thumbnail]),
#[cfg(feature = "unstable-msc3552")]
caption: None,
body,
info,
url,
}
}
}

View File

@ -44,6 +44,8 @@ fn message_serialize_sticker() {
};
let actual = to_json_value(&aliases_event).unwrap();
#[cfg(not(feature = "unstable-msc3552"))]
let expected = json!({
"content": {
"body": "Hello",
@ -69,6 +71,51 @@ fn message_serialize_sticker() {
"type": "m.sticker",
});
#[cfg(feature = "unstable-msc3552")]
let expected = json!({
"content": {
"body": "Hello",
"info": {
"h": 423,
"mimetype": "image/png",
"size": 84242,
"thumbnail_info": {
"h": 334,
"mimetype": "image/png",
"size": 82595,
"w": 800
},
"thumbnail_url": "mxc://matrix.org/irsns989Rrsn",
"w": 1011
},
"url": "mxc://matrix.org/rnsldl8srs98IRrs",
"org.matrix.msc1767.text": "Hello",
"org.matrix.msc1767.file": {
"url": "mxc://matrix.org/rnsldl8srs98IRrs",
"mimetype": "image/png",
"size": 84242,
},
"org.matrix.msc1767.image": {
"height": 423,
"width": 1011,
},
"org.matrix.msc1767.thumbnail": [
{
"url": "mxc://matrix.org/irsns989Rrsn",
"mimetype": "image/png",
"size": 82595,
"height": 334,
"width": 800,
}
],
},
"event_id": "$h29iv0s8:example.com",
"origin_server_ts": 1,
"room_id": "!roomid:room.com",
"sender": "@carl:example.com",
"type": "m.sticker",
});
assert_eq!(actual, expected);
}

View File

@ -19,6 +19,7 @@ mod redaction;
mod relations;
mod room_message;
mod state_event;
mod sticker;
mod stripped;
mod to_device;
mod video;

View File

@ -0,0 +1,78 @@
#![cfg(feature = "unstable-msc3552")]
use ruma_common::{
events::{room::ImageInfo, sticker::StickerEventContent},
mxc_uri,
};
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
#[test]
fn content_serialization() {
let message_event_content = StickerEventContent::new(
"Upload: my_image.jpg".to_owned(),
ImageInfo::new(),
mxc_uri!("mxc://notareal.hs/file").to_owned(),
);
assert_eq!(
to_json_value(&message_event_content).unwrap(),
json!({
"body": "Upload: my_image.jpg",
"url": "mxc://notareal.hs/file",
"info": {},
"org.matrix.msc1767.text": "Upload: my_image.jpg",
"org.matrix.msc1767.file": {
"url": "mxc://notareal.hs/file",
},
"org.matrix.msc1767.image": {},
})
);
}
#[test]
fn content_stable_deserialization() {
let json_data = json!({
"body": "Upload: my_image.jpg",
"url": "mxc://notareal.hs/file",
"info": {},
"m.text": "Upload: my_image.jpg",
"m.file": {
"url": "mxc://notareal.hs/file",
},
"m.image": {},
});
let content = from_json_value::<StickerEventContent>(json_data).unwrap();
assert_eq!(content.body, "Upload: my_image.jpg");
assert_eq!(content.url, "mxc://notareal.hs/file");
let message = content.message.unwrap();
assert_eq!(message.len(), 1);
assert_eq!(message[0].body, "Upload: my_image.jpg");
let file = content.file.unwrap();
assert_eq!(file.url, "mxc://notareal.hs/file");
assert!(!file.is_encrypted());
}
#[test]
fn content_unstable_deserialization() {
let json_data = json!({
"body": "Upload: my_image.jpg",
"url": "mxc://notareal.hs/file",
"info": {},
"org.matrix.msc1767.text": "Upload: my_image.jpg",
"org.matrix.msc1767.file": {
"url": "mxc://notareal.hs/file",
},
"org.matrix.msc1767.image": {},
});
let content = from_json_value::<StickerEventContent>(json_data).unwrap();
assert_eq!(content.body, "Upload: my_image.jpg");
assert_eq!(content.url, "mxc://notareal.hs/file");
let message = content.message.unwrap();
assert_eq!(message.len(), 1);
assert_eq!(message[0].body, "Upload: my_image.jpg");
let file = content.file.unwrap();
assert_eq!(file.url, "mxc://notareal.hs/file");
assert!(!file.is_encrypted());
}