events: Update types according to changes in MSC3552
This commit is contained in:
		
							parent
							
								
									2de1cecec6
								
							
						
					
					
						commit
						5985bbe803
					
				| @ -55,7 +55,8 @@ event_enum! { | ||||
|         #[ruma_enum(alias = "m.file")] | ||||
|         "org.matrix.msc1767.file" => super::file, | ||||
|         #[cfg(feature = "unstable-msc3552")] | ||||
|         "m.image" => super::image, | ||||
|         #[ruma_enum(alias = "m.image")] | ||||
|         "org.matrix.msc1767.image" => super::image, | ||||
|         "m.key.verification.ready" => super::key::verification::ready, | ||||
|         "m.key.verification.start" => super::key::verification::start, | ||||
|         "m.key.verification.cancel" => super::key::verification::cancel, | ||||
|  | ||||
| @ -2,12 +2,14 @@ | ||||
| //!
 | ||||
| //! [MSC3552]: https://github.com/matrix-org/matrix-spec-proposals/pull/3552
 | ||||
| 
 | ||||
| use std::ops::Deref; | ||||
| 
 | ||||
| use js_int::UInt; | ||||
| use ruma_macros::EventContent; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| 
 | ||||
| use super::{ | ||||
|     file::{EncryptedContent, FileContentBlock}, | ||||
|     file::{CaptionContentBlock, EncryptedContent, FileContentBlock}, | ||||
|     message::TextContentBlock, | ||||
|     room::message::Relation, | ||||
| }; | ||||
| @ -16,13 +18,15 @@ use crate::OwnedMxcUri; | ||||
| /// The payload for an extensible image message.
 | ||||
| ///
 | ||||
| /// This is the new primary type introduced in [MSC3552] and should only be sent in rooms with a
 | ||||
| /// version that supports it. See the documentation of the [`message`] module for more information.
 | ||||
| /// version that supports it. This type replaces both the `m.room.message` type with `msgtype:
 | ||||
| /// "m.image"` and the `m.sticker` type. To replace the latter, `sticker` must be set to `true` in
 | ||||
| /// `image_details`. See the documentation of the [`message`] module for more information.
 | ||||
| ///
 | ||||
| /// [MSC3552]: https://github.com/matrix-org/matrix-spec-proposals/pull/3552
 | ||||
| /// [`message`]: super::message
 | ||||
| #[derive(Clone, Debug, Serialize, Deserialize, EventContent)] | ||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||
| #[ruma_event(type = "m.image", kind = MessageLike, without_relation)] | ||||
| #[ruma_event(type = "org.matrix.msc1767.image", kind = MessageLike, without_relation)] | ||||
| pub struct ImageEventContent { | ||||
|     /// The text representation of the message.
 | ||||
|     #[serde(rename = "org.matrix.msc1767.text")] | ||||
| @ -32,17 +36,36 @@ pub struct ImageEventContent { | ||||
|     #[serde(rename = "org.matrix.msc1767.file")] | ||||
|     pub file: FileContentBlock, | ||||
| 
 | ||||
|     /// The image content of the message.
 | ||||
|     #[serde(rename = "m.image")] | ||||
|     pub image: Box<ImageContent>, | ||||
|     /// The image details of the message, if any.
 | ||||
|     #[serde(rename = "org.matrix.msc1767.image_details", skip_serializing_if = "Option::is_none")] | ||||
|     pub image_details: Option<ImageDetailsContentBlock>, | ||||
| 
 | ||||
|     /// The thumbnails of the message.
 | ||||
|     #[serde(rename = "m.thumbnail", default, skip_serializing_if = "Vec::is_empty")] | ||||
|     pub thumbnail: Vec<ThumbnailContent>, | ||||
|     /// The thumbnails of the message, if any.
 | ||||
|     ///
 | ||||
|     /// This is optional and defaults to an empty array.
 | ||||
|     #[serde(
 | ||||
|         rename = "org.matrix.msc1767.thumbnail", | ||||
|         default, | ||||
|         skip_serializing_if = "ThumbnailContentBlock::is_empty" | ||||
|     )] | ||||
|     pub thumbnail: ThumbnailContentBlock, | ||||
| 
 | ||||
|     /// The captions of the message.
 | ||||
|     #[serde(rename = "m.caption", default, skip_serializing_if = "TextContentBlock::is_empty")] | ||||
|     pub caption: TextContentBlock, | ||||
|     /// The caption of the message, if any.
 | ||||
|     #[serde(rename = "org.matrix.msc1767.caption", skip_serializing_if = "Option::is_none")] | ||||
|     pub caption: Option<CaptionContentBlock>, | ||||
| 
 | ||||
|     /// The alternative text of the image, for accessibility considerations, if any.
 | ||||
|     #[serde(rename = "org.matrix.msc1767.alt_text", skip_serializing_if = "Option::is_none")] | ||||
|     pub alt_text: Option<AltTextContentBlock>, | ||||
| 
 | ||||
|     /// Whether this message is automated.
 | ||||
|     #[cfg(feature = "unstable-msc3955")] | ||||
|     #[serde(
 | ||||
|         default, | ||||
|         skip_serializing_if = "crate::serde::is_default", | ||||
|         rename = "org.matrix.msc1767.automated" | ||||
|     )] | ||||
|     pub automated: bool, | ||||
| 
 | ||||
|     /// Information about related messages.
 | ||||
|     #[serde(
 | ||||
| @ -60,87 +83,136 @@ impl ImageEventContent { | ||||
|         Self { | ||||
|             text, | ||||
|             file, | ||||
|             image: Default::default(), | ||||
|             image_details: None, | ||||
|             thumbnail: Default::default(), | ||||
|             caption: Default::default(), | ||||
|             caption: None, | ||||
|             alt_text: None, | ||||
|             #[cfg(feature = "unstable-msc3955")] | ||||
|             automated: false, | ||||
|             relates_to: None, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Creates a new `ImageEventContent` with the given plain text fallback representation and
 | ||||
|     /// file.
 | ||||
|     pub fn plain(text_fallback: impl Into<String>, file: FileContentBlock) -> Self { | ||||
|     pub fn with_plain_text(plain_text: impl Into<String>, file: FileContentBlock) -> Self { | ||||
|         Self { | ||||
|             text: TextContentBlock::plain(text_fallback), | ||||
|             text: TextContentBlock::plain(plain_text), | ||||
|             file, | ||||
|             image: Default::default(), | ||||
|             image_details: None, | ||||
|             thumbnail: Default::default(), | ||||
|             caption: Default::default(), | ||||
|             caption: None, | ||||
|             alt_text: None, | ||||
|             #[cfg(feature = "unstable-msc3955")] | ||||
|             automated: false, | ||||
|             relates_to: None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Image content.
 | ||||
| /// A block for details of image content.
 | ||||
| #[derive(Default, Clone, Debug, Serialize, Deserialize)] | ||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||
| pub struct ImageContent { | ||||
| pub struct ImageDetailsContentBlock { | ||||
|     /// The height of the image in pixels.
 | ||||
|     #[serde(skip_serializing_if = "Option::is_none")] | ||||
|     pub height: Option<UInt>, | ||||
|     pub height: UInt, | ||||
| 
 | ||||
|     /// The width of the image in pixels.
 | ||||
|     #[serde(skip_serializing_if = "Option::is_none")] | ||||
|     pub width: Option<UInt>, | ||||
|     pub width: UInt, | ||||
| 
 | ||||
|     /// Whether the image should be presented as sticker.
 | ||||
|     #[serde(
 | ||||
|         rename = "org.matrix.msc1767.sticker", | ||||
|         default, | ||||
|         skip_serializing_if = "crate::serde::is_default" | ||||
|     )] | ||||
|     pub sticker: bool, | ||||
| } | ||||
| 
 | ||||
| impl ImageContent { | ||||
|     /// Creates a new empty `ImageContent`.
 | ||||
|     pub fn new() -> Self { | ||||
|         Self::default() | ||||
| impl ImageDetailsContentBlock { | ||||
|     /// Creates a new `ImageDetailsContentBlock` with the given width and height.
 | ||||
|     pub fn new(width: UInt, height: UInt) -> Self { | ||||
|         Self { height, width, sticker: Default::default() } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|     /// Creates a new `ImageContent` with the given width and height.
 | ||||
|     pub fn with_size(width: UInt, height: UInt) -> Self { | ||||
|         Self { height: Some(height), width: Some(width) } | ||||
|     } | ||||
| /// A block for thumbnail content.
 | ||||
| ///
 | ||||
| /// This is an array of [`Thumbnail`].
 | ||||
| ///
 | ||||
| /// To construct a `ThumbnailContentBlock` convert a `Vec<Thumbnail>` with
 | ||||
| /// `ThumbnailContentBlock::from()` / `.into()`.
 | ||||
| #[derive(Clone, Debug, Default, Serialize, Deserialize)] | ||||
| #[allow(clippy::exhaustive_structs)] | ||||
| pub struct ThumbnailContentBlock(Vec<Thumbnail>); | ||||
| 
 | ||||
|     /// Whether this `ImageContent` is empty.
 | ||||
| impl ThumbnailContentBlock { | ||||
|     /// Whether this content block is empty.
 | ||||
|     pub fn is_empty(&self) -> bool { | ||||
|         self.height.is_none() && self.width.is_none() | ||||
|         self.0.is_empty() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<Vec<Thumbnail>> for ThumbnailContentBlock { | ||||
|     fn from(thumbnails: Vec<Thumbnail>) -> Self { | ||||
|         Self(thumbnails) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl FromIterator<Thumbnail> for ThumbnailContentBlock { | ||||
|     fn from_iter<T: IntoIterator<Item = Thumbnail>>(iter: T) -> Self { | ||||
|         Self(iter.into_iter().collect()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Deref for ThumbnailContentBlock { | ||||
|     type Target = [Thumbnail]; | ||||
| 
 | ||||
|     fn deref(&self) -> &Self::Target { | ||||
|         &self.0 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Thumbnail content.
 | ||||
| #[derive(Clone, Debug, Deserialize, Serialize)] | ||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||
| pub struct ThumbnailContent { | ||||
| pub struct Thumbnail { | ||||
|     /// The file info of the thumbnail.
 | ||||
|     #[serde(flatten)] | ||||
|     pub file: ThumbnailFileContent, | ||||
|     #[serde(rename = "org.matrix.msc1767.file")] | ||||
|     pub file: ThumbnailFileContentBlock, | ||||
| 
 | ||||
|     /// The image info of the thumbnail.
 | ||||
|     #[serde(flatten, skip_serializing_if = "Option::is_none")] | ||||
|     pub image: Option<Box<ImageContent>>, | ||||
|     #[serde(rename = "org.matrix.msc1767.image_details")] | ||||
|     pub image_details: ThumbnailImageDetailsContentBlock, | ||||
| } | ||||
| 
 | ||||
| impl ThumbnailContent { | ||||
|     /// Creates a `ThumbnailContent` with the given file and image info.
 | ||||
|     pub fn new(file: ThumbnailFileContent, image: Option<Box<ImageContent>>) -> Self { | ||||
|         Self { file, image } | ||||
| impl Thumbnail { | ||||
|     /// Creates a `Thumbnail` with the given file and image details.
 | ||||
|     pub fn new( | ||||
|         file: ThumbnailFileContentBlock, | ||||
|         image_details: ThumbnailImageDetailsContentBlock, | ||||
|     ) -> Self { | ||||
|         Self { file, image_details } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Thumbnail file content.
 | ||||
| /// A block for thumbnail file content.
 | ||||
| #[derive(Clone, Debug, Serialize, Deserialize)] | ||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||
| pub struct ThumbnailFileContent { | ||||
| pub struct ThumbnailFileContentBlock { | ||||
|     /// The URL to the thumbnail.
 | ||||
|     pub url: OwnedMxcUri, | ||||
| 
 | ||||
|     /// Information about the uploaded thumbnail.
 | ||||
|     #[serde(flatten, skip_serializing_if = "Option::is_none")] | ||||
|     pub info: Option<Box<ThumbnailFileContentInfo>>, | ||||
|     /// The mimetype of the file, e.g. "image/png".
 | ||||
|     pub mimetype: String, | ||||
| 
 | ||||
|     /// The original filename of the uploaded file.
 | ||||
|     #[serde(skip_serializing_if = "Option::is_none")] | ||||
|     pub name: Option<String>, | ||||
| 
 | ||||
|     /// The size of the file in bytes.
 | ||||
|     #[serde(skip_serializing_if = "Option::is_none")] | ||||
|     pub size: Option<UInt>, | ||||
| 
 | ||||
|     /// Information on the encrypted thumbnail.
 | ||||
|     ///
 | ||||
| @ -149,20 +221,26 @@ pub struct ThumbnailFileContent { | ||||
|     pub encryption_info: Option<Box<EncryptedContent>>, | ||||
| } | ||||
| 
 | ||||
| impl ThumbnailFileContent { | ||||
|     /// Creates a new non-encrypted `ThumbnailFileContent` with the given url and file info.
 | ||||
|     pub fn plain(url: OwnedMxcUri, info: Option<Box<ThumbnailFileContentInfo>>) -> Self { | ||||
|         Self { url, info, encryption_info: None } | ||||
| impl ThumbnailFileContentBlock { | ||||
|     /// Creates a new non-encrypted `ThumbnailFileContentBlock` with the given url and mimetype.
 | ||||
|     pub fn plain(url: OwnedMxcUri, mimetype: String) -> Self { | ||||
|         Self { url, mimetype, name: None, size: None, encryption_info: None } | ||||
|     } | ||||
| 
 | ||||
|     /// Creates a new encrypted `ThumbnailFileContent` with the given url, encryption info and
 | ||||
|     /// thumbnail file info.
 | ||||
|     /// Creates a new encrypted `ThumbnailFileContentBlock` with the given url, mimetype and
 | ||||
|     /// encryption info.
 | ||||
|     pub fn encrypted( | ||||
|         url: OwnedMxcUri, | ||||
|         mimetype: String, | ||||
|         encryption_info: EncryptedContent, | ||||
|         info: Option<Box<ThumbnailFileContentInfo>>, | ||||
|     ) -> Self { | ||||
|         Self { url, info, encryption_info: Some(Box::new(encryption_info)) } | ||||
|         Self { | ||||
|             url, | ||||
|             mimetype, | ||||
|             name: None, | ||||
|             size: None, | ||||
|             encryption_info: Some(Box::new(encryption_info)), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Whether the thumbnail file is encrypted.
 | ||||
| @ -171,22 +249,47 @@ impl ThumbnailFileContent { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Information about a thumbnail file content.
 | ||||
| #[derive(Clone, Debug, Default, Serialize, Deserialize)] | ||||
| /// A block for details of thumbnail image content.
 | ||||
| #[derive(Default, Clone, Debug, Serialize, Deserialize)] | ||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||
| pub struct ThumbnailFileContentInfo { | ||||
|     /// The mimetype of the thumbnail, e.g. `image/png`.
 | ||||
|     #[serde(skip_serializing_if = "Option::is_none")] | ||||
|     pub mimetype: Option<String>, | ||||
| pub struct ThumbnailImageDetailsContentBlock { | ||||
|     /// The height of the image in pixels.
 | ||||
|     pub height: UInt, | ||||
| 
 | ||||
|     /// The size of the thumbnail in bytes.
 | ||||
|     #[serde(skip_serializing_if = "Option::is_none")] | ||||
|     pub size: Option<UInt>, | ||||
|     /// The width of the image in pixels.
 | ||||
|     pub width: UInt, | ||||
| } | ||||
| 
 | ||||
| impl ThumbnailFileContentInfo { | ||||
|     /// Creates an empty `ThumbnailFileContentInfo`.
 | ||||
|     pub fn new() -> Self { | ||||
|         Self::default() | ||||
| impl ThumbnailImageDetailsContentBlock { | ||||
|     /// Creates a new `ThumbnailImageDetailsContentBlock` with the given width and height.
 | ||||
|     pub fn new(width: UInt, height: UInt) -> Self { | ||||
|         Self { height, width } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// A block for alternative text content.
 | ||||
| ///
 | ||||
| /// The content should only contain plain text messages. Non-plain text messages should be ignored.
 | ||||
| ///
 | ||||
| /// To construct an `AltTextContentBlock` with a custom [`TextContentBlock`], convert it with
 | ||||
| /// `AltTextContentBlock::from()` / `.into()`.
 | ||||
| #[derive(Clone, Debug, Serialize, Deserialize)] | ||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||
| pub struct AltTextContentBlock { | ||||
|     /// The alternative text.
 | ||||
|     #[serde(rename = "org.matrix.msc1767.text")] | ||||
|     pub text: TextContentBlock, | ||||
| } | ||||
| 
 | ||||
| impl AltTextContentBlock { | ||||
|     /// A convenience constructor to create a plain text alternative text content block.
 | ||||
|     pub fn plain(body: impl Into<String>) -> Self { | ||||
|         Self { text: TextContentBlock::plain(body) } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<TextContentBlock> for AltTextContentBlock { | ||||
|     fn from(text: TextContentBlock) -> Self { | ||||
|         Self { text } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -9,7 +9,7 @@ use ruma_macros::EventContent; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| 
 | ||||
| use super::{ | ||||
|     file::FileContentBlock, image::ThumbnailContent, message::TextContentBlock, | ||||
|     file::FileContentBlock, image::ThumbnailContentBlock, message::TextContentBlock, | ||||
|     room::message::Relation, | ||||
| }; | ||||
| 
 | ||||
| @ -37,8 +37,12 @@ pub struct VideoEventContent { | ||||
|     pub video: Box<VideoContent>, | ||||
| 
 | ||||
|     /// The thumbnails of the message.
 | ||||
|     #[serde(rename = "m.thumbnail", default, skip_serializing_if = "Vec::is_empty")] | ||||
|     pub thumbnail: Vec<ThumbnailContent>, | ||||
|     #[serde(
 | ||||
|         rename = "org.matrix.msc1767.thumbnail", | ||||
|         default, | ||||
|         skip_serializing_if = "ThumbnailContentBlock::is_empty" | ||||
|     )] | ||||
|     pub thumbnail: ThumbnailContentBlock, | ||||
| 
 | ||||
|     /// The captions of the message.
 | ||||
|     #[serde(rename = "m.caption", default, skip_serializing_if = "TextContentBlock::is_empty")] | ||||
|  | ||||
| @ -1,15 +1,14 @@ | ||||
| #![cfg(feature = "unstable-msc3552")] | ||||
| 
 | ||||
| use assert_matches::assert_matches; | ||||
| use assign::assign; | ||||
| use js_int::uint; | ||||
| use ruma_common::{ | ||||
|     event_id, | ||||
|     events::{ | ||||
|         file::{EncryptedContentInit, FileContentBlock}, | ||||
|         file::{CaptionContentBlock, EncryptedContentInit, FileContentBlock}, | ||||
|         image::{ | ||||
|             ImageContent, ImageEventContent, ThumbnailContent, ThumbnailFileContent, | ||||
|             ThumbnailFileContentInfo, | ||||
|             ImageDetailsContentBlock, ImageEventContent, Thumbnail, ThumbnailFileContentBlock, | ||||
|             ThumbnailImageDetailsContentBlock, | ||||
|         }, | ||||
|         message::TextContentBlock, | ||||
|         relation::InReplyTo, | ||||
| @ -24,7 +23,7 @@ use serde_json::{from_value as from_json_value, json, to_value as to_json_value} | ||||
| 
 | ||||
| #[test] | ||||
| fn plain_content_serialization() { | ||||
|     let event_content = ImageEventContent::plain( | ||||
|     let event_content = ImageEventContent::with_plain_text( | ||||
|         "Upload: my_image.jpg", | ||||
|         FileContentBlock::plain( | ||||
|             mxc_uri!("mxc://notareal.hs/abcdef").to_owned(), | ||||
| @ -42,14 +41,13 @@ fn plain_content_serialization() { | ||||
|                 "url": "mxc://notareal.hs/abcdef", | ||||
|                 "name": "my_image.jpg", | ||||
|             }, | ||||
|             "m.image": {} | ||||
|         }) | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| fn encrypted_content_serialization() { | ||||
|     let event_content = ImageEventContent::plain( | ||||
|     let event_content = ImageEventContent::with_plain_text( | ||||
|         "Upload: my_image.jpg", | ||||
|         FileContentBlock::encrypted( | ||||
|             mxc_uri!("mxc://notareal.hs/abcdef").to_owned(), | ||||
| @ -97,7 +95,6 @@ fn encrypted_content_serialization() { | ||||
|                 }, | ||||
|                 "v": "v2" | ||||
|             }, | ||||
|             "m.image": {} | ||||
|         }) | ||||
|     ); | ||||
| } | ||||
| @ -114,18 +111,17 @@ fn image_event_serialization() { | ||||
| 
 | ||||
|     content.file.mimetype = Some("image/jpeg".to_owned()); | ||||
|     content.file.size = Some(uint!(897_774)); | ||||
|     content.image = Box::new(ImageContent::with_size(uint!(1920), uint!(1080))); | ||||
|     content.thumbnail = vec![ThumbnailContent::new( | ||||
|         ThumbnailFileContent::plain( | ||||
|     content.image_details = Some(ImageDetailsContentBlock::new(uint!(1920), uint!(1080))); | ||||
|     let mut thumbnail = Thumbnail::new( | ||||
|         ThumbnailFileContentBlock::plain( | ||||
|             mxc_uri!("mxc://notareal.hs/thumbnail").to_owned(), | ||||
|             Some(Box::new(assign!(ThumbnailFileContentInfo::new(), { | ||||
|                 mimetype: Some("image/jpeg".to_owned()), | ||||
|                 size: Some(uint!(334_593)), | ||||
|             }))), | ||||
|             "image/jpeg".to_owned(), | ||||
|         ), | ||||
|         None, | ||||
|     )]; | ||||
|     content.caption = TextContentBlock::plain("This is my house"); | ||||
|         ThumbnailImageDetailsContentBlock::new(uint!(560), uint!(480)), | ||||
|     ); | ||||
|     thumbnail.file.size = Some(uint!(334_593)); | ||||
|     content.thumbnail = vec![thumbnail].into(); | ||||
|     content.caption = Some(CaptionContentBlock::plain("This is my house")); | ||||
|     content.relates_to = Some(Relation::Reply { | ||||
|         in_reply_to: InReplyTo::new(event_id!("$replyevent:example.com").to_owned()), | ||||
|     }); | ||||
| @ -143,22 +139,28 @@ fn image_event_serialization() { | ||||
|                 "mimetype": "image/jpeg", | ||||
|                 "size": 897_774, | ||||
|             }, | ||||
|             "m.image": { | ||||
|             "org.matrix.msc1767.image_details": { | ||||
|                 "width": 1920, | ||||
|                 "height": 1080, | ||||
|             }, | ||||
|             "m.thumbnail": [ | ||||
|             "org.matrix.msc1767.thumbnail": [ | ||||
|                 { | ||||
|                     "url": "mxc://notareal.hs/thumbnail", | ||||
|                     "mimetype": "image/jpeg", | ||||
|                     "size": 334_593, | ||||
|                 } | ||||
|             ], | ||||
|             "m.caption": [ | ||||
|                 { | ||||
|                     "body": "This is my house", | ||||
|                 } | ||||
|                     "org.matrix.msc1767.file": { | ||||
|                         "url": "mxc://notareal.hs/thumbnail", | ||||
|                         "mimetype": "image/jpeg", | ||||
|                         "size": 334_593, | ||||
|                     }, | ||||
|                     "org.matrix.msc1767.image_details": { | ||||
|                         "width": 560, | ||||
|                         "height": 480, | ||||
|                     }, | ||||
|                 }, | ||||
|             ], | ||||
|             "org.matrix.msc1767.caption": { | ||||
|                 "org.matrix.msc1767.text": [ | ||||
|                     { "body": "This is my house" }, | ||||
|                 ], | ||||
|             }, | ||||
|             "m.relates_to": { | ||||
|                 "m.in_reply_to": { | ||||
|                     "event_id": "$replyevent:example.com" | ||||
| @ -178,14 +180,15 @@ fn plain_content_deserialization() { | ||||
|             "url": "mxc://notareal.hs/abcdef", | ||||
|             "name": "my_cat.png", | ||||
|         }, | ||||
|         "m.image": { | ||||
|         "org.matrix.msc1767.image_details": { | ||||
|             "width": 668, | ||||
|             "height": 1023, | ||||
|         }, | ||||
|         "org.matrix.msc1767.caption": { | ||||
|             "org.matrix.msc1767.text": [ | ||||
|                 { "body": "Look at my cat!" }, | ||||
|             ], | ||||
|         }, | ||||
|         "m.caption": [ | ||||
|             { | ||||
|                 "body": "Look at my cat!", | ||||
|             } | ||||
|         ] | ||||
|     }); | ||||
| 
 | ||||
|     let content = from_json_value::<ImageEventContent>(json_data).unwrap(); | ||||
| @ -194,11 +197,13 @@ fn plain_content_deserialization() { | ||||
|     assert_eq!(content.file.url, "mxc://notareal.hs/abcdef"); | ||||
|     assert_eq!(content.file.name, "my_cat.png"); | ||||
|     assert_matches!(content.file.encryption_info, None); | ||||
|     assert_eq!(content.image.width, Some(uint!(668))); | ||||
|     assert_eq!(content.image.height, None); | ||||
|     let image_details = content.image_details.unwrap(); | ||||
|     assert_eq!(image_details.width, uint!(668)); | ||||
|     assert_eq!(image_details.height, uint!(1023)); | ||||
|     assert_eq!(content.thumbnail.len(), 0); | ||||
|     assert_eq!(content.caption.len(), 1); | ||||
|     assert_eq!(content.caption.find_plain(), Some("Look at my cat!")); | ||||
|     let caption = content.caption.unwrap(); | ||||
|     assert_eq!(caption.text.len(), 1); | ||||
|     assert_eq!(caption.text.find_plain(), Some("Look at my cat!")); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| @ -223,10 +228,16 @@ fn encrypted_content_deserialization() { | ||||
|             }, | ||||
|             "v": "v2" | ||||
|         }, | ||||
|         "m.image": {}, | ||||
|         "m.thumbnail": [ | ||||
|         "org.matrix.msc1767.thumbnail": [ | ||||
|             { | ||||
|                 "url": "mxc://notareal.hs/thumbnail", | ||||
|                 "org.matrix.msc1767.file": { | ||||
|                     "url": "mxc://notareal.hs/thumbnail", | ||||
|                     "mimetype": "image/png", | ||||
|                 }, | ||||
|                 "org.matrix.msc1767.image_details": { | ||||
|                     "width": 480, | ||||
|                     "height": 560, | ||||
|                 } | ||||
|             } | ||||
|         ] | ||||
|     }); | ||||
| @ -237,11 +248,14 @@ fn encrypted_content_deserialization() { | ||||
|     assert_eq!(content.file.url, "mxc://notareal.hs/abcdef"); | ||||
|     assert_eq!(content.file.name, "my_cat.png"); | ||||
|     assert!(content.file.encryption_info.is_some()); | ||||
|     assert_eq!(content.image.width, None); | ||||
|     assert_eq!(content.image.height, None); | ||||
|     assert!(content.image_details.is_none()); | ||||
|     assert_eq!(content.thumbnail.len(), 1); | ||||
|     assert_eq!(content.thumbnail[0].file.url, "mxc://notareal.hs/thumbnail"); | ||||
|     assert!(content.caption.is_empty()); | ||||
|     let thumbnail = &content.thumbnail[0]; | ||||
|     assert_eq!(thumbnail.file.url, "mxc://notareal.hs/thumbnail"); | ||||
|     assert_eq!(thumbnail.file.mimetype, "image/png"); | ||||
|     assert_eq!(thumbnail.image_details.width, uint!(480)); | ||||
|     assert_eq!(thumbnail.image_details.height, uint!(560)); | ||||
|     assert!(content.caption.is_none()); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| @ -257,7 +271,7 @@ fn message_event_deserialization() { | ||||
|                 "mimetype": "image/webp", | ||||
|                 "size": 123_774, | ||||
|             }, | ||||
|             "m.image": { | ||||
|             "org.matrix.msc1767.image_details": { | ||||
|                 "width": 1300, | ||||
|                 "height": 837, | ||||
|             } | ||||
| @ -266,7 +280,7 @@ fn message_event_deserialization() { | ||||
|         "origin_server_ts": 134_829_848, | ||||
|         "room_id": "!roomid:notareal.hs", | ||||
|         "sender": "@user:notareal.hs", | ||||
|         "type": "m.image", | ||||
|         "type": "org.matrix.msc1767.image", | ||||
|     }); | ||||
| 
 | ||||
|     let message_event = assert_matches!( | ||||
| @ -286,7 +300,8 @@ fn message_event_deserialization() { | ||||
|     assert_eq!(content.file.name, "my_gnome.webp"); | ||||
|     assert_eq!(content.file.mimetype.as_deref(), Some("image/webp")); | ||||
|     assert_eq!(content.file.size, Some(uint!(123_774))); | ||||
|     assert_eq!(content.image.width, Some(uint!(1300))); | ||||
|     assert_eq!(content.image.height, Some(uint!(837))); | ||||
|     let image_details = content.image_details.unwrap(); | ||||
|     assert_eq!(image_details.width, uint!(1300)); | ||||
|     assert_eq!(image_details.height, uint!(837)); | ||||
|     assert_eq!(content.thumbnail.len(), 0); | ||||
| } | ||||
|  | ||||
| @ -9,7 +9,7 @@ use ruma_common::{ | ||||
|     event_id, | ||||
|     events::{ | ||||
|         file::{EncryptedContentInit, FileContentBlock}, | ||||
|         image::{ThumbnailContent, ThumbnailFileContent, ThumbnailFileContentInfo}, | ||||
|         image::{Thumbnail, ThumbnailFileContentBlock, ThumbnailImageDetailsContentBlock}, | ||||
|         message::TextContentBlock, | ||||
|         relation::InReplyTo, | ||||
|         room::{message::Relation, JsonWebKeyInit}, | ||||
| @ -125,16 +125,15 @@ fn event_serialization() { | ||||
|             duration: Some(Duration::from_secs(15)), | ||||
|         } | ||||
|     )); | ||||
|     content.thumbnail = vec![ThumbnailContent::new( | ||||
|         ThumbnailFileContent::plain( | ||||
|     let mut thumbnail = Thumbnail::new( | ||||
|         ThumbnailFileContentBlock::plain( | ||||
|             mxc_uri!("mxc://notareal.hs/thumbnail").to_owned(), | ||||
|             Some(Box::new(assign!(ThumbnailFileContentInfo::new(), { | ||||
|                 mimetype: Some("image/jpeg".to_owned()), | ||||
|                 size: Some(uint!(334_593)), | ||||
|             }))), | ||||
|             "image/jpeg".to_owned(), | ||||
|         ), | ||||
|         None, | ||||
|     )]; | ||||
|         ThumbnailImageDetailsContentBlock::new(uint!(560), uint!(480)), | ||||
|     ); | ||||
|     thumbnail.file.size = Some(uint!(334_593)); | ||||
|     content.thumbnail = vec![thumbnail].into(); | ||||
|     content.caption = TextContentBlock::plain("This is my awesome vintage lava lamp"); | ||||
|     content.relates_to = Some(Relation::Reply { | ||||
|         in_reply_to: InReplyTo::new(event_id!("$replyevent:example.com").to_owned()), | ||||
| @ -158,11 +157,17 @@ fn event_serialization() { | ||||
|                 "height": 1080, | ||||
|                 "duration": 15_000, | ||||
|             }, | ||||
|             "m.thumbnail": [ | ||||
|             "org.matrix.msc1767.thumbnail": [ | ||||
|                 { | ||||
|                     "url": "mxc://notareal.hs/thumbnail", | ||||
|                     "mimetype": "image/jpeg", | ||||
|                     "size": 334_593, | ||||
|                     "org.matrix.msc1767.file": { | ||||
|                         "url": "mxc://notareal.hs/thumbnail", | ||||
|                         "mimetype": "image/jpeg", | ||||
|                         "size": 334_593, | ||||
|                     }, | ||||
|                     "org.matrix.msc1767.image_details": { | ||||
|                         "width": 560, | ||||
|                         "height": 480, | ||||
|                     }, | ||||
|                 } | ||||
|             ], | ||||
|             "m.caption": [ | ||||
| @ -236,9 +241,16 @@ fn encrypted_content_deserialization() { | ||||
|             "v": "v2" | ||||
|         }, | ||||
|         "m.video": {}, | ||||
|         "m.thumbnail": [ | ||||
|         "org.matrix.msc1767.thumbnail": [ | ||||
|             { | ||||
|                 "url": "mxc://notareal.hs/thumbnail", | ||||
|                 "org.matrix.msc1767.file": { | ||||
|                     "url": "mxc://notareal.hs/thumbnail", | ||||
|                     "mimetype": "image/png", | ||||
|                 }, | ||||
|                 "org.matrix.msc1767.image_details": { | ||||
|                     "width": 560, | ||||
|                     "height": 480, | ||||
|                 }, | ||||
|             } | ||||
|         ] | ||||
|     }); | ||||
| @ -253,7 +265,11 @@ fn encrypted_content_deserialization() { | ||||
|     assert_eq!(content.video.height, None); | ||||
|     assert_eq!(content.video.duration, None); | ||||
|     assert_eq!(content.thumbnail.len(), 1); | ||||
|     assert_eq!(content.thumbnail[0].file.url, "mxc://notareal.hs/thumbnail"); | ||||
|     let thumbnail = &content.thumbnail[0]; | ||||
|     assert_eq!(thumbnail.file.url, "mxc://notareal.hs/thumbnail"); | ||||
|     assert_eq!(thumbnail.file.mimetype, "image/png"); | ||||
|     assert_eq!(thumbnail.image_details.width, uint!(560)); | ||||
|     assert_eq!(thumbnail.image_details.height, uint!(480)); | ||||
|     assert!(content.caption.is_empty()); | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user