events: Deref MessageContent to a slice

This commit is contained in:
Kévin Commaille 2022-03-25 17:45:55 +01:00 committed by Kévin Commaille
parent e4463dda22
commit 93b4114a82
4 changed files with 39 additions and 40 deletions

View File

@ -47,6 +47,8 @@
//! [MSC3245]: https://github.com/matrix-org/matrix-spec-proposals/pull/3245 //! [MSC3245]: https://github.com/matrix-org/matrix-spec-proposals/pull/3245
//! [MSC3381]: https://github.com/matrix-org/matrix-spec-proposals/pull/3381 //! [MSC3381]: https://github.com/matrix-org/matrix-spec-proposals/pull/3381
//! [`RoomMessageEventContent`]: super::room::message::RoomMessageEventContent //! [`RoomMessageEventContent`]: super::room::message::RoomMessageEventContent
use std::ops::Deref;
use ruma_macros::EventContent; use ruma_macros::EventContent;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -162,24 +164,17 @@ impl MessageContent {
/// Get the plain text representation of this message. /// Get the plain text representation of this message.
pub fn find_plain(&self) -> Option<&str> { pub fn find_plain(&self) -> Option<&str> {
self.variants() self.iter()
.iter()
.find(|content| content.mimetype == "text/plain") .find(|content| content.mimetype == "text/plain")
.map(|content| content.body.as_ref()) .map(|content| content.body.as_ref())
} }
/// Get the HTML representation of this message. /// Get the HTML representation of this message.
pub fn find_html(&self) -> Option<&str> { pub fn find_html(&self) -> Option<&str> {
self.variants() self.iter()
.iter()
.find(|content| content.mimetype == "text/html") .find(|content| content.mimetype == "text/html")
.map(|content| content.body.as_ref()) .map(|content| content.body.as_ref())
} }
/// Get all the text representations of this message.
pub fn variants(&self) -> &[Text] {
&self.0
}
} }
impl From<Vec<Text>> for MessageContent { impl From<Vec<Text>> for MessageContent {
@ -188,6 +183,14 @@ impl From<Vec<Text>> for MessageContent {
} }
} }
impl Deref for MessageContent {
type Target = [Text];
fn deref(&self) -> &Self::Target {
&self.0
}
}
/// Text message content. /// Text message 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)]

View File

@ -59,11 +59,10 @@ impl Serialize for MessageContent {
S: serde::Serializer, S: serde::Serializer,
{ {
let mut st = serializer.serialize_struct("MessageContent", 1)?; let mut st = serializer.serialize_struct("MessageContent", 1)?;
let variants = self.variants(); if self.len() == 1 && self[0].mimetype == "text/plain" {
if variants.len() == 1 && variants[0].mimetype == "text/plain" { st.serialize_field("org.matrix.msc1767.text", &self[0].body)?;
st.serialize_field("org.matrix.msc1767.text", &variants[0].body)?;
} else { } else {
st.serialize_field("org.matrix.msc1767.message", variants)?; st.serialize_field("org.matrix.msc1767.message", &self.0)?;
} }
st.end() st.end()
} }

View File

@ -586,8 +586,7 @@ impl EmoteMessageEventContent {
#[cfg(feature = "unstable-msc1767")] #[cfg(feature = "unstable-msc1767")]
impl From<MessageContent> for EmoteMessageEventContent { impl From<MessageContent> for EmoteMessageEventContent {
fn from(message: MessageContent) -> Self { fn from(message: MessageContent) -> Self {
let body = let body = if let Some(body) = message.find_plain() { body } else { &message[0].body };
if let Some(body) = message.find_plain() { body } else { &message.variants()[0].body };
let formatted = message.find_html().map(FormattedBody::html); let formatted = message.find_html().map(FormattedBody::html);
Self { body: body.to_owned(), formatted, message: Some(message) } Self { body: body.to_owned(), formatted, message: Some(message) }
@ -798,8 +797,7 @@ impl NoticeMessageEventContent {
#[cfg(feature = "unstable-msc1767")] #[cfg(feature = "unstable-msc1767")]
impl From<MessageContent> for NoticeMessageEventContent { impl From<MessageContent> for NoticeMessageEventContent {
fn from(message: MessageContent) -> Self { fn from(message: MessageContent) -> Self {
let body = let body = if let Some(body) = message.find_plain() { body } else { &message[0].body };
if let Some(body) = message.find_plain() { body } else { &message.variants()[0].body };
let formatted = message.find_html().map(FormattedBody::html); let formatted = message.find_html().map(FormattedBody::html);
Self { body: body.to_owned(), formatted, message: Some(message) } Self { body: body.to_owned(), formatted, message: Some(message) }
@ -1000,8 +998,7 @@ impl TextMessageEventContent {
#[cfg(feature = "unstable-msc1767")] #[cfg(feature = "unstable-msc1767")]
impl From<MessageContent> for TextMessageEventContent { impl From<MessageContent> for TextMessageEventContent {
fn from(message: MessageContent) -> Self { fn from(message: MessageContent) -> Self {
let body = let body = if let Some(body) = message.find_plain() { body } else { &message[0].body };
if let Some(body) = message.find_plain() { body } else { &message.variants()[0].body };
let formatted = message.find_html().map(FormattedBody::html); let formatted = message.find_html().map(FormattedBody::html);
Self { body: body.to_owned(), formatted, message: Some(message) } Self { body: body.to_owned(), formatted, message: Some(message) }

View File

@ -280,8 +280,8 @@ fn room_message_plain_text_stable_deserialization() {
}), }),
.. ..
} if body == "test" } if body == "test"
&& message.variants().len() == 1 && message.len() == 1
&& message.variants()[0].body == "test" && message[0].body == "test"
); );
} }
@ -305,8 +305,8 @@ fn room_message_plain_text_unstable_deserialization() {
}), }),
.. ..
} if body == "test" } if body == "test"
&& message.variants().len() == 1 && message.len() == 1
&& message.variants()[0].body == "test" && message[0].body == "test"
); );
} }
@ -336,9 +336,9 @@ fn room_message_html_text_stable_deserialization() {
.. ..
} if body == "test" } if body == "test"
&& formatted.body == "<h1>test</h1>" && formatted.body == "<h1>test</h1>"
&& message.variants().len() == 2 && message.len() == 2
&& message.variants()[0].body == "<h1>test</h1>" && message[0].body == "<h1>test</h1>"
&& message.variants()[1].body == "test" && message[1].body == "test"
); );
} }
@ -368,9 +368,9 @@ fn room_message_html_text_unstable_deserialization() {
.. ..
} if body == "test" } if body == "test"
&& formatted.body == "<h1>test</h1>" && formatted.body == "<h1>test</h1>"
&& message.variants().len() == 2 && message.len() == 2
&& message.variants()[0].body == "<h1>test</h1>" && message[0].body == "<h1>test</h1>"
&& message.variants()[1].body == "test" && message[1].body == "test"
); );
} }
@ -511,8 +511,8 @@ fn room_message_notice_stable_deserialization() {
}), }),
.. ..
} if body == "test" } if body == "test"
&& message.variants().len() == 1 && message.len() == 1
&& message.variants()[0].body == "test" && message[0].body == "test"
); );
} }
@ -536,8 +536,8 @@ fn room_message_notice_unstable_deserialization() {
}), }),
.. ..
} if body == "test" } if body == "test"
&& message.variants().len() == 1 && message.len() == 1
&& message.variants()[0].body == "test" && message[0].body == "test"
); );
} }
@ -679,8 +679,8 @@ fn room_message_emote_stable_deserialization() {
}), }),
.. ..
} if body == "test" } if body == "test"
&& message.variants().len() == 1 && message.len() == 1
&& message.variants()[0].body == "test" && message[0].body == "test"
); );
} }
@ -704,8 +704,8 @@ fn room_message_emote_unstable_deserialization() {
}), }),
.. ..
} if body == "test" } if body == "test"
&& message.variants().len() == 1 && message.len() == 1
&& message.variants()[0].body == "test" && message[0].body == "test"
); );
} }
@ -746,7 +746,7 @@ fn lang_deserialization() {
}); });
let content = from_json_value::<MessageContent>(json_data).unwrap(); let content = from_json_value::<MessageContent>(json_data).unwrap();
assert_eq!(content.variants()[0].lang.as_deref(), Some("fr")); assert_eq!(content[0].lang.as_deref(), Some("fr"));
assert_eq!(content.variants()[1].lang.as_deref(), Some("de")); assert_eq!(content[1].lang.as_deref(), Some("de"));
assert_eq!(content.variants()[2].lang.as_deref(), Some("en")); assert_eq!(content[2].lang.as_deref(), Some("en"));
} }