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")] |         #[ruma_enum(alias = "m.file")] | ||||||
|         "org.matrix.msc1767.file" => super::file, |         "org.matrix.msc1767.file" => super::file, | ||||||
|         #[cfg(feature = "unstable-msc3552")] |         #[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.ready" => super::key::verification::ready, | ||||||
|         "m.key.verification.start" => super::key::verification::start, |         "m.key.verification.start" => super::key::verification::start, | ||||||
|         "m.key.verification.cancel" => super::key::verification::cancel, |         "m.key.verification.cancel" => super::key::verification::cancel, | ||||||
|  | |||||||
| @ -2,12 +2,14 @@ | |||||||
| //!
 | //!
 | ||||||
| //! [MSC3552]: https://github.com/matrix-org/matrix-spec-proposals/pull/3552
 | //! [MSC3552]: https://github.com/matrix-org/matrix-spec-proposals/pull/3552
 | ||||||
| 
 | 
 | ||||||
|  | use std::ops::Deref; | ||||||
|  | 
 | ||||||
| use js_int::UInt; | use js_int::UInt; | ||||||
| use ruma_macros::EventContent; | use ruma_macros::EventContent; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| 
 | 
 | ||||||
| use super::{ | use super::{ | ||||||
|     file::{EncryptedContent, FileContentBlock}, |     file::{CaptionContentBlock, EncryptedContent, FileContentBlock}, | ||||||
|     message::TextContentBlock, |     message::TextContentBlock, | ||||||
|     room::message::Relation, |     room::message::Relation, | ||||||
| }; | }; | ||||||
| @ -16,13 +18,15 @@ use crate::OwnedMxcUri; | |||||||
| /// The payload for an extensible image message.
 | /// 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
 | /// 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
 | /// [MSC3552]: https://github.com/matrix-org/matrix-spec-proposals/pull/3552
 | ||||||
| /// [`message`]: super::message
 | /// [`message`]: super::message
 | ||||||
| #[derive(Clone, Debug, Serialize, Deserialize, EventContent)] | #[derive(Clone, Debug, Serialize, Deserialize, EventContent)] | ||||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | #[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 { | pub struct ImageEventContent { | ||||||
|     /// The text representation of the message.
 |     /// The text representation of the message.
 | ||||||
|     #[serde(rename = "org.matrix.msc1767.text")] |     #[serde(rename = "org.matrix.msc1767.text")] | ||||||
| @ -32,17 +36,36 @@ pub struct ImageEventContent { | |||||||
|     #[serde(rename = "org.matrix.msc1767.file")] |     #[serde(rename = "org.matrix.msc1767.file")] | ||||||
|     pub file: FileContentBlock, |     pub file: FileContentBlock, | ||||||
| 
 | 
 | ||||||
|     /// The image content of the message.
 |     /// The image details of the message, if any.
 | ||||||
|     #[serde(rename = "m.image")] |     #[serde(rename = "org.matrix.msc1767.image_details", skip_serializing_if = "Option::is_none")] | ||||||
|     pub image: Box<ImageContent>, |     pub image_details: Option<ImageDetailsContentBlock>, | ||||||
| 
 | 
 | ||||||
|     /// The thumbnails of the message.
 |     /// The thumbnails of the message, if any.
 | ||||||
|     #[serde(rename = "m.thumbnail", default, skip_serializing_if = "Vec::is_empty")] |     ///
 | ||||||
|     pub thumbnail: Vec<ThumbnailContent>, |     /// 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.
 |     /// The caption of the message, if any.
 | ||||||
|     #[serde(rename = "m.caption", default, skip_serializing_if = "TextContentBlock::is_empty")] |     #[serde(rename = "org.matrix.msc1767.caption", skip_serializing_if = "Option::is_none")] | ||||||
|     pub caption: TextContentBlock, |     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.
 |     /// Information about related messages.
 | ||||||
|     #[serde(
 |     #[serde(
 | ||||||
| @ -60,87 +83,136 @@ impl ImageEventContent { | |||||||
|         Self { |         Self { | ||||||
|             text, |             text, | ||||||
|             file, |             file, | ||||||
|             image: Default::default(), |             image_details: None, | ||||||
|             thumbnail: Default::default(), |             thumbnail: Default::default(), | ||||||
|             caption: Default::default(), |             caption: None, | ||||||
|  |             alt_text: None, | ||||||
|  |             #[cfg(feature = "unstable-msc3955")] | ||||||
|  |             automated: false, | ||||||
|             relates_to: None, |             relates_to: None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Creates a new `ImageEventContent` with the given plain text fallback representation and
 |     /// Creates a new `ImageEventContent` with the given plain text fallback representation and
 | ||||||
|     /// file.
 |     /// 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 { |         Self { | ||||||
|             text: TextContentBlock::plain(text_fallback), |             text: TextContentBlock::plain(plain_text), | ||||||
|             file, |             file, | ||||||
|             image: Default::default(), |             image_details: None, | ||||||
|             thumbnail: Default::default(), |             thumbnail: Default::default(), | ||||||
|             caption: Default::default(), |             caption: None, | ||||||
|  |             alt_text: None, | ||||||
|  |             #[cfg(feature = "unstable-msc3955")] | ||||||
|  |             automated: false, | ||||||
|             relates_to: None, |             relates_to: None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Image content.
 | /// A block for details of image content.
 | ||||||
| #[derive(Default, Clone, Debug, Serialize, Deserialize)] | #[derive(Default, Clone, Debug, Serialize, Deserialize)] | ||||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||||
| pub struct ImageContent { | pub struct ImageDetailsContentBlock { | ||||||
|     /// The height of the image in pixels.
 |     /// The height of the image in pixels.
 | ||||||
|     #[serde(skip_serializing_if = "Option::is_none")] |     pub height: UInt, | ||||||
|     pub height: Option<UInt>, |  | ||||||
| 
 | 
 | ||||||
|     /// The width of the image in pixels.
 |     /// The width of the image in pixels.
 | ||||||
|     #[serde(skip_serializing_if = "Option::is_none")] |     pub width: UInt, | ||||||
|     pub width: Option<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 { | impl ImageDetailsContentBlock { | ||||||
|     /// Creates a new empty `ImageContent`.
 |     /// Creates a new `ImageDetailsContentBlock` with the given width and height.
 | ||||||
|     pub fn new() -> Self { |     pub fn new(width: UInt, height: UInt) -> Self { | ||||||
|         Self::default() |         Self { height, width, sticker: Default::default() } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|     /// Creates a new `ImageContent` with the given width and height.
 | /// A block for thumbnail content.
 | ||||||
|     pub fn with_size(width: UInt, height: UInt) -> Self { | ///
 | ||||||
|         Self { height: Some(height), width: Some(width) } | /// 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 { |     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.
 | /// Thumbnail content.
 | ||||||
| #[derive(Clone, Debug, Deserialize, Serialize)] | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||||
| pub struct ThumbnailContent { | pub struct Thumbnail { | ||||||
|     /// The file info of the thumbnail.
 |     /// The file info of the thumbnail.
 | ||||||
|     #[serde(flatten)] |     #[serde(rename = "org.matrix.msc1767.file")] | ||||||
|     pub file: ThumbnailFileContent, |     pub file: ThumbnailFileContentBlock, | ||||||
| 
 | 
 | ||||||
|     /// The image info of the thumbnail.
 |     /// The image info of the thumbnail.
 | ||||||
|     #[serde(flatten, skip_serializing_if = "Option::is_none")] |     #[serde(rename = "org.matrix.msc1767.image_details")] | ||||||
|     pub image: Option<Box<ImageContent>>, |     pub image_details: ThumbnailImageDetailsContentBlock, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl ThumbnailContent { | impl Thumbnail { | ||||||
|     /// Creates a `ThumbnailContent` with the given file and image info.
 |     /// Creates a `Thumbnail` with the given file and image details.
 | ||||||
|     pub fn new(file: ThumbnailFileContent, image: Option<Box<ImageContent>>) -> Self { |     pub fn new( | ||||||
|         Self { file, image } |         file: ThumbnailFileContentBlock, | ||||||
|  |         image_details: ThumbnailImageDetailsContentBlock, | ||||||
|  |     ) -> Self { | ||||||
|  |         Self { file, image_details } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Thumbnail file content.
 | /// A block for thumbnail file content.
 | ||||||
| #[derive(Clone, Debug, Serialize, Deserialize)] | #[derive(Clone, Debug, Serialize, Deserialize)] | ||||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||||
| pub struct ThumbnailFileContent { | pub struct ThumbnailFileContentBlock { | ||||||
|     /// The URL to the thumbnail.
 |     /// The URL to the thumbnail.
 | ||||||
|     pub url: OwnedMxcUri, |     pub url: OwnedMxcUri, | ||||||
| 
 | 
 | ||||||
|     /// Information about the uploaded thumbnail.
 |     /// The mimetype of the file, e.g. "image/png".
 | ||||||
|     #[serde(flatten, skip_serializing_if = "Option::is_none")] |     pub mimetype: String, | ||||||
|     pub info: Option<Box<ThumbnailFileContentInfo>>, | 
 | ||||||
|  |     /// 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.
 |     /// Information on the encrypted thumbnail.
 | ||||||
|     ///
 |     ///
 | ||||||
| @ -149,20 +221,26 @@ pub struct ThumbnailFileContent { | |||||||
|     pub encryption_info: Option<Box<EncryptedContent>>, |     pub encryption_info: Option<Box<EncryptedContent>>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl ThumbnailFileContent { | impl ThumbnailFileContentBlock { | ||||||
|     /// Creates a new non-encrypted `ThumbnailFileContent` with the given url and file info.
 |     /// Creates a new non-encrypted `ThumbnailFileContentBlock` with the given url and mimetype.
 | ||||||
|     pub fn plain(url: OwnedMxcUri, info: Option<Box<ThumbnailFileContentInfo>>) -> Self { |     pub fn plain(url: OwnedMxcUri, mimetype: String) -> Self { | ||||||
|         Self { url, info, encryption_info: None } |         Self { url, mimetype, name: None, size: None, encryption_info: None } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Creates a new encrypted `ThumbnailFileContent` with the given url, encryption info and
 |     /// Creates a new encrypted `ThumbnailFileContentBlock` with the given url, mimetype and
 | ||||||
|     /// thumbnail file info.
 |     /// encryption info.
 | ||||||
|     pub fn encrypted( |     pub fn encrypted( | ||||||
|         url: OwnedMxcUri, |         url: OwnedMxcUri, | ||||||
|  |         mimetype: String, | ||||||
|         encryption_info: EncryptedContent, |         encryption_info: EncryptedContent, | ||||||
|         info: Option<Box<ThumbnailFileContentInfo>>, |  | ||||||
|     ) -> Self { |     ) -> 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.
 |     /// Whether the thumbnail file is encrypted.
 | ||||||
| @ -171,22 +249,47 @@ impl ThumbnailFileContent { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Information about a thumbnail file content.
 | /// A block for details of thumbnail image content.
 | ||||||
| #[derive(Clone, Debug, Default, Serialize, Deserialize)] | #[derive(Default, Clone, Debug, Serialize, Deserialize)] | ||||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||||
| pub struct ThumbnailFileContentInfo { | pub struct ThumbnailImageDetailsContentBlock { | ||||||
|     /// The mimetype of the thumbnail, e.g. `image/png`.
 |     /// The height of the image in pixels.
 | ||||||
|     #[serde(skip_serializing_if = "Option::is_none")] |     pub height: UInt, | ||||||
|     pub mimetype: Option<String>, |  | ||||||
| 
 | 
 | ||||||
|     /// The size of the thumbnail in bytes.
 |     /// The width of the image in pixels.
 | ||||||
|     #[serde(skip_serializing_if = "Option::is_none")] |     pub width: UInt, | ||||||
|     pub size: Option<UInt>, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl ThumbnailFileContentInfo { | impl ThumbnailImageDetailsContentBlock { | ||||||
|     /// Creates an empty `ThumbnailFileContentInfo`.
 |     /// Creates a new `ThumbnailImageDetailsContentBlock` with the given width and height.
 | ||||||
|     pub fn new() -> Self { |     pub fn new(width: UInt, height: UInt) -> Self { | ||||||
|         Self::default() |         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 serde::{Deserialize, Serialize}; | ||||||
| 
 | 
 | ||||||
| use super::{ | use super::{ | ||||||
|     file::FileContentBlock, image::ThumbnailContent, message::TextContentBlock, |     file::FileContentBlock, image::ThumbnailContentBlock, message::TextContentBlock, | ||||||
|     room::message::Relation, |     room::message::Relation, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -37,8 +37,12 @@ pub struct VideoEventContent { | |||||||
|     pub video: Box<VideoContent>, |     pub video: Box<VideoContent>, | ||||||
| 
 | 
 | ||||||
|     /// The thumbnails of the message.
 |     /// The thumbnails of the message.
 | ||||||
|     #[serde(rename = "m.thumbnail", default, skip_serializing_if = "Vec::is_empty")] |     #[serde(
 | ||||||
|     pub thumbnail: Vec<ThumbnailContent>, |         rename = "org.matrix.msc1767.thumbnail", | ||||||
|  |         default, | ||||||
|  |         skip_serializing_if = "ThumbnailContentBlock::is_empty" | ||||||
|  |     )] | ||||||
|  |     pub thumbnail: ThumbnailContentBlock, | ||||||
| 
 | 
 | ||||||
|     /// The captions of the message.
 |     /// The captions of the message.
 | ||||||
|     #[serde(rename = "m.caption", default, skip_serializing_if = "TextContentBlock::is_empty")] |     #[serde(rename = "m.caption", default, skip_serializing_if = "TextContentBlock::is_empty")] | ||||||
|  | |||||||
| @ -1,15 +1,14 @@ | |||||||
| #![cfg(feature = "unstable-msc3552")] | #![cfg(feature = "unstable-msc3552")] | ||||||
| 
 | 
 | ||||||
| use assert_matches::assert_matches; | use assert_matches::assert_matches; | ||||||
| use assign::assign; |  | ||||||
| use js_int::uint; | use js_int::uint; | ||||||
| use ruma_common::{ | use ruma_common::{ | ||||||
|     event_id, |     event_id, | ||||||
|     events::{ |     events::{ | ||||||
|         file::{EncryptedContentInit, FileContentBlock}, |         file::{CaptionContentBlock, EncryptedContentInit, FileContentBlock}, | ||||||
|         image::{ |         image::{ | ||||||
|             ImageContent, ImageEventContent, ThumbnailContent, ThumbnailFileContent, |             ImageDetailsContentBlock, ImageEventContent, Thumbnail, ThumbnailFileContentBlock, | ||||||
|             ThumbnailFileContentInfo, |             ThumbnailImageDetailsContentBlock, | ||||||
|         }, |         }, | ||||||
|         message::TextContentBlock, |         message::TextContentBlock, | ||||||
|         relation::InReplyTo, |         relation::InReplyTo, | ||||||
| @ -24,7 +23,7 @@ use serde_json::{from_value as from_json_value, json, to_value as to_json_value} | |||||||
| 
 | 
 | ||||||
| #[test] | #[test] | ||||||
| fn plain_content_serialization() { | fn plain_content_serialization() { | ||||||
|     let event_content = ImageEventContent::plain( |     let event_content = ImageEventContent::with_plain_text( | ||||||
|         "Upload: my_image.jpg", |         "Upload: my_image.jpg", | ||||||
|         FileContentBlock::plain( |         FileContentBlock::plain( | ||||||
|             mxc_uri!("mxc://notareal.hs/abcdef").to_owned(), |             mxc_uri!("mxc://notareal.hs/abcdef").to_owned(), | ||||||
| @ -42,14 +41,13 @@ fn plain_content_serialization() { | |||||||
|                 "url": "mxc://notareal.hs/abcdef", |                 "url": "mxc://notareal.hs/abcdef", | ||||||
|                 "name": "my_image.jpg", |                 "name": "my_image.jpg", | ||||||
|             }, |             }, | ||||||
|             "m.image": {} |  | ||||||
|         }) |         }) | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[test] | #[test] | ||||||
| fn encrypted_content_serialization() { | fn encrypted_content_serialization() { | ||||||
|     let event_content = ImageEventContent::plain( |     let event_content = ImageEventContent::with_plain_text( | ||||||
|         "Upload: my_image.jpg", |         "Upload: my_image.jpg", | ||||||
|         FileContentBlock::encrypted( |         FileContentBlock::encrypted( | ||||||
|             mxc_uri!("mxc://notareal.hs/abcdef").to_owned(), |             mxc_uri!("mxc://notareal.hs/abcdef").to_owned(), | ||||||
| @ -97,7 +95,6 @@ fn encrypted_content_serialization() { | |||||||
|                 }, |                 }, | ||||||
|                 "v": "v2" |                 "v": "v2" | ||||||
|             }, |             }, | ||||||
|             "m.image": {} |  | ||||||
|         }) |         }) | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| @ -114,18 +111,17 @@ fn image_event_serialization() { | |||||||
| 
 | 
 | ||||||
|     content.file.mimetype = Some("image/jpeg".to_owned()); |     content.file.mimetype = Some("image/jpeg".to_owned()); | ||||||
|     content.file.size = Some(uint!(897_774)); |     content.file.size = Some(uint!(897_774)); | ||||||
|     content.image = Box::new(ImageContent::with_size(uint!(1920), uint!(1080))); |     content.image_details = Some(ImageDetailsContentBlock::new(uint!(1920), uint!(1080))); | ||||||
|     content.thumbnail = vec![ThumbnailContent::new( |     let mut thumbnail = Thumbnail::new( | ||||||
|         ThumbnailFileContent::plain( |         ThumbnailFileContentBlock::plain( | ||||||
|             mxc_uri!("mxc://notareal.hs/thumbnail").to_owned(), |             mxc_uri!("mxc://notareal.hs/thumbnail").to_owned(), | ||||||
|             Some(Box::new(assign!(ThumbnailFileContentInfo::new(), { |             "image/jpeg".to_owned(), | ||||||
|                 mimetype: Some("image/jpeg".to_owned()), |  | ||||||
|                 size: Some(uint!(334_593)), |  | ||||||
|             }))), |  | ||||||
|         ), |         ), | ||||||
|         None, |         ThumbnailImageDetailsContentBlock::new(uint!(560), uint!(480)), | ||||||
|     )]; |     ); | ||||||
|     content.caption = TextContentBlock::plain("This is my house"); |     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 { |     content.relates_to = Some(Relation::Reply { | ||||||
|         in_reply_to: InReplyTo::new(event_id!("$replyevent:example.com").to_owned()), |         in_reply_to: InReplyTo::new(event_id!("$replyevent:example.com").to_owned()), | ||||||
|     }); |     }); | ||||||
| @ -143,22 +139,28 @@ fn image_event_serialization() { | |||||||
|                 "mimetype": "image/jpeg", |                 "mimetype": "image/jpeg", | ||||||
|                 "size": 897_774, |                 "size": 897_774, | ||||||
|             }, |             }, | ||||||
|             "m.image": { |             "org.matrix.msc1767.image_details": { | ||||||
|                 "width": 1920, |                 "width": 1920, | ||||||
|                 "height": 1080, |                 "height": 1080, | ||||||
|             }, |             }, | ||||||
|             "m.thumbnail": [ |             "org.matrix.msc1767.thumbnail": [ | ||||||
|                 { |                 { | ||||||
|  |                     "org.matrix.msc1767.file": { | ||||||
|                         "url": "mxc://notareal.hs/thumbnail", |                         "url": "mxc://notareal.hs/thumbnail", | ||||||
|                         "mimetype": "image/jpeg", |                         "mimetype": "image/jpeg", | ||||||
|                         "size": 334_593, |                         "size": 334_593, | ||||||
|                 } |                     }, | ||||||
|  |                     "org.matrix.msc1767.image_details": { | ||||||
|  |                         "width": 560, | ||||||
|  |                         "height": 480, | ||||||
|  |                     }, | ||||||
|  |                 }, | ||||||
|             ], |             ], | ||||||
|             "m.caption": [ |             "org.matrix.msc1767.caption": { | ||||||
|                 { |                 "org.matrix.msc1767.text": [ | ||||||
|                     "body": "This is my house", |                     { "body": "This is my house" }, | ||||||
|                 } |  | ||||||
|                 ], |                 ], | ||||||
|  |             }, | ||||||
|             "m.relates_to": { |             "m.relates_to": { | ||||||
|                 "m.in_reply_to": { |                 "m.in_reply_to": { | ||||||
|                     "event_id": "$replyevent:example.com" |                     "event_id": "$replyevent:example.com" | ||||||
| @ -178,14 +180,15 @@ fn plain_content_deserialization() { | |||||||
|             "url": "mxc://notareal.hs/abcdef", |             "url": "mxc://notareal.hs/abcdef", | ||||||
|             "name": "my_cat.png", |             "name": "my_cat.png", | ||||||
|         }, |         }, | ||||||
|         "m.image": { |         "org.matrix.msc1767.image_details": { | ||||||
|             "width": 668, |             "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(); |     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.url, "mxc://notareal.hs/abcdef"); | ||||||
|     assert_eq!(content.file.name, "my_cat.png"); |     assert_eq!(content.file.name, "my_cat.png"); | ||||||
|     assert_matches!(content.file.encryption_info, None); |     assert_matches!(content.file.encryption_info, None); | ||||||
|     assert_eq!(content.image.width, Some(uint!(668))); |     let image_details = content.image_details.unwrap(); | ||||||
|     assert_eq!(content.image.height, None); |     assert_eq!(image_details.width, uint!(668)); | ||||||
|  |     assert_eq!(image_details.height, uint!(1023)); | ||||||
|     assert_eq!(content.thumbnail.len(), 0); |     assert_eq!(content.thumbnail.len(), 0); | ||||||
|     assert_eq!(content.caption.len(), 1); |     let caption = content.caption.unwrap(); | ||||||
|     assert_eq!(content.caption.find_plain(), Some("Look at my cat!")); |     assert_eq!(caption.text.len(), 1); | ||||||
|  |     assert_eq!(caption.text.find_plain(), Some("Look at my cat!")); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[test] | #[test] | ||||||
| @ -223,10 +228,16 @@ fn encrypted_content_deserialization() { | |||||||
|             }, |             }, | ||||||
|             "v": "v2" |             "v": "v2" | ||||||
|         }, |         }, | ||||||
|         "m.image": {}, |         "org.matrix.msc1767.thumbnail": [ | ||||||
|         "m.thumbnail": [ |  | ||||||
|             { |             { | ||||||
|  |                 "org.matrix.msc1767.file": { | ||||||
|                     "url": "mxc://notareal.hs/thumbnail", |                     "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.url, "mxc://notareal.hs/abcdef"); | ||||||
|     assert_eq!(content.file.name, "my_cat.png"); |     assert_eq!(content.file.name, "my_cat.png"); | ||||||
|     assert!(content.file.encryption_info.is_some()); |     assert!(content.file.encryption_info.is_some()); | ||||||
|     assert_eq!(content.image.width, None); |     assert!(content.image_details.is_none()); | ||||||
|     assert_eq!(content.image.height, None); |  | ||||||
|     assert_eq!(content.thumbnail.len(), 1); |     assert_eq!(content.thumbnail.len(), 1); | ||||||
|     assert_eq!(content.thumbnail[0].file.url, "mxc://notareal.hs/thumbnail"); |     let thumbnail = &content.thumbnail[0]; | ||||||
|     assert!(content.caption.is_empty()); |     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] | #[test] | ||||||
| @ -257,7 +271,7 @@ fn message_event_deserialization() { | |||||||
|                 "mimetype": "image/webp", |                 "mimetype": "image/webp", | ||||||
|                 "size": 123_774, |                 "size": 123_774, | ||||||
|             }, |             }, | ||||||
|             "m.image": { |             "org.matrix.msc1767.image_details": { | ||||||
|                 "width": 1300, |                 "width": 1300, | ||||||
|                 "height": 837, |                 "height": 837, | ||||||
|             } |             } | ||||||
| @ -266,7 +280,7 @@ fn message_event_deserialization() { | |||||||
|         "origin_server_ts": 134_829_848, |         "origin_server_ts": 134_829_848, | ||||||
|         "room_id": "!roomid:notareal.hs", |         "room_id": "!roomid:notareal.hs", | ||||||
|         "sender": "@user:notareal.hs", |         "sender": "@user:notareal.hs", | ||||||
|         "type": "m.image", |         "type": "org.matrix.msc1767.image", | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     let message_event = assert_matches!( |     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.name, "my_gnome.webp"); | ||||||
|     assert_eq!(content.file.mimetype.as_deref(), Some("image/webp")); |     assert_eq!(content.file.mimetype.as_deref(), Some("image/webp")); | ||||||
|     assert_eq!(content.file.size, Some(uint!(123_774))); |     assert_eq!(content.file.size, Some(uint!(123_774))); | ||||||
|     assert_eq!(content.image.width, Some(uint!(1300))); |     let image_details = content.image_details.unwrap(); | ||||||
|     assert_eq!(content.image.height, Some(uint!(837))); |     assert_eq!(image_details.width, uint!(1300)); | ||||||
|  |     assert_eq!(image_details.height, uint!(837)); | ||||||
|     assert_eq!(content.thumbnail.len(), 0); |     assert_eq!(content.thumbnail.len(), 0); | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ use ruma_common::{ | |||||||
|     event_id, |     event_id, | ||||||
|     events::{ |     events::{ | ||||||
|         file::{EncryptedContentInit, FileContentBlock}, |         file::{EncryptedContentInit, FileContentBlock}, | ||||||
|         image::{ThumbnailContent, ThumbnailFileContent, ThumbnailFileContentInfo}, |         image::{Thumbnail, ThumbnailFileContentBlock, ThumbnailImageDetailsContentBlock}, | ||||||
|         message::TextContentBlock, |         message::TextContentBlock, | ||||||
|         relation::InReplyTo, |         relation::InReplyTo, | ||||||
|         room::{message::Relation, JsonWebKeyInit}, |         room::{message::Relation, JsonWebKeyInit}, | ||||||
| @ -125,16 +125,15 @@ fn event_serialization() { | |||||||
|             duration: Some(Duration::from_secs(15)), |             duration: Some(Duration::from_secs(15)), | ||||||
|         } |         } | ||||||
|     )); |     )); | ||||||
|     content.thumbnail = vec![ThumbnailContent::new( |     let mut thumbnail = Thumbnail::new( | ||||||
|         ThumbnailFileContent::plain( |         ThumbnailFileContentBlock::plain( | ||||||
|             mxc_uri!("mxc://notareal.hs/thumbnail").to_owned(), |             mxc_uri!("mxc://notareal.hs/thumbnail").to_owned(), | ||||||
|             Some(Box::new(assign!(ThumbnailFileContentInfo::new(), { |             "image/jpeg".to_owned(), | ||||||
|                 mimetype: Some("image/jpeg".to_owned()), |  | ||||||
|                 size: Some(uint!(334_593)), |  | ||||||
|             }))), |  | ||||||
|         ), |         ), | ||||||
|         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.caption = TextContentBlock::plain("This is my awesome vintage lava lamp"); | ||||||
|     content.relates_to = Some(Relation::Reply { |     content.relates_to = Some(Relation::Reply { | ||||||
|         in_reply_to: InReplyTo::new(event_id!("$replyevent:example.com").to_owned()), |         in_reply_to: InReplyTo::new(event_id!("$replyevent:example.com").to_owned()), | ||||||
| @ -158,11 +157,17 @@ fn event_serialization() { | |||||||
|                 "height": 1080, |                 "height": 1080, | ||||||
|                 "duration": 15_000, |                 "duration": 15_000, | ||||||
|             }, |             }, | ||||||
|             "m.thumbnail": [ |             "org.matrix.msc1767.thumbnail": [ | ||||||
|                 { |                 { | ||||||
|  |                     "org.matrix.msc1767.file": { | ||||||
|                         "url": "mxc://notareal.hs/thumbnail", |                         "url": "mxc://notareal.hs/thumbnail", | ||||||
|                         "mimetype": "image/jpeg", |                         "mimetype": "image/jpeg", | ||||||
|                         "size": 334_593, |                         "size": 334_593, | ||||||
|  |                     }, | ||||||
|  |                     "org.matrix.msc1767.image_details": { | ||||||
|  |                         "width": 560, | ||||||
|  |                         "height": 480, | ||||||
|  |                     }, | ||||||
|                 } |                 } | ||||||
|             ], |             ], | ||||||
|             "m.caption": [ |             "m.caption": [ | ||||||
| @ -236,9 +241,16 @@ fn encrypted_content_deserialization() { | |||||||
|             "v": "v2" |             "v": "v2" | ||||||
|         }, |         }, | ||||||
|         "m.video": {}, |         "m.video": {}, | ||||||
|         "m.thumbnail": [ |         "org.matrix.msc1767.thumbnail": [ | ||||||
|             { |             { | ||||||
|  |                 "org.matrix.msc1767.file": { | ||||||
|                     "url": "mxc://notareal.hs/thumbnail", |                     "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.height, None); | ||||||
|     assert_eq!(content.video.duration, None); |     assert_eq!(content.video.duration, None); | ||||||
|     assert_eq!(content.thumbnail.len(), 1); |     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()); |     assert!(content.caption.is_empty()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user