events: Support m.html shortcut for MessageContent
This commit is contained in:
parent
ed8990c3fd
commit
6f3d9fd327
@ -14,6 +14,14 @@ pub(crate) struct MessageContentSerDeHelper {
|
|||||||
#[serde(rename = "org.matrix.msc1767.text")]
|
#[serde(rename = "org.matrix.msc1767.text")]
|
||||||
text_unstable: Option<String>,
|
text_unstable: Option<String>,
|
||||||
|
|
||||||
|
/// HTML short form, stable name.
|
||||||
|
#[serde(rename = "m.html")]
|
||||||
|
html_stable: Option<String>,
|
||||||
|
|
||||||
|
/// HTML short form, unstable name.
|
||||||
|
#[serde(rename = "org.matrix.msc1767.html")]
|
||||||
|
html_unstable: Option<String>,
|
||||||
|
|
||||||
/// Long form, stable name.
|
/// Long form, stable name.
|
||||||
#[serde(rename = "m.message")]
|
#[serde(rename = "m.message")]
|
||||||
message_stable: Option<Vec<Text>>,
|
message_stable: Option<Vec<Text>>,
|
||||||
@ -30,16 +38,26 @@ impl TryFrom<MessageContentSerDeHelper> for MessageContent {
|
|||||||
let MessageContentSerDeHelper {
|
let MessageContentSerDeHelper {
|
||||||
text_stable,
|
text_stable,
|
||||||
text_unstable,
|
text_unstable,
|
||||||
|
html_stable,
|
||||||
|
html_unstable,
|
||||||
message_stable,
|
message_stable,
|
||||||
message_unstable,
|
message_unstable,
|
||||||
} = helper;
|
} = helper;
|
||||||
|
|
||||||
if let Some(message) = message_stable.or(message_unstable) {
|
if let Some(message) = message_stable.or(message_unstable) {
|
||||||
Ok(Self(message))
|
Ok(Self(message))
|
||||||
} else if let Some(text) = text_stable.or(text_unstable) {
|
|
||||||
Ok(Self::plain(text))
|
|
||||||
} else {
|
} else {
|
||||||
Err(TryFromExtensibleError::MissingField("m.message or m.text".to_owned()))
|
let message: Vec<_> = html_stable
|
||||||
|
.or(html_unstable)
|
||||||
|
.map(Text::html)
|
||||||
|
.into_iter()
|
||||||
|
.chain(text_stable.or(text_unstable).map(Text::plain))
|
||||||
|
.collect();
|
||||||
|
if !message.is_empty() {
|
||||||
|
Ok(Self(message))
|
||||||
|
} else {
|
||||||
|
Err(TryFromExtensibleError::MissingField("m.message, m.text or m.html".to_owned()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,13 +67,30 @@ impl Serialize for MessageContent {
|
|||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
{
|
{
|
||||||
let mut st = serializer.serialize_struct("MessageContent", 1)?;
|
#[cfg(feature = "unstable-msc3554")]
|
||||||
if self.len() == 1 && self[0].mimetype == "text/plain" {
|
let has_shortcut = |message: &Text| {
|
||||||
st.serialize_field("org.matrix.msc1767.text", &self[0].body)?;
|
matches!(&*message.mimetype, "text/plain" | "text/html") && message.lang.is_none()
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "unstable-msc3554"))]
|
||||||
|
let has_shortcut =
|
||||||
|
|message: &Text| matches!(&*message.mimetype, "text/plain" | "text/html");
|
||||||
|
|
||||||
|
if self.iter().all(has_shortcut) {
|
||||||
|
let mut st = serializer.serialize_struct("MessageContent", self.len())?;
|
||||||
|
for message in self.iter() {
|
||||||
|
if message.mimetype == "text/plain" {
|
||||||
|
st.serialize_field("org.matrix.msc1767.text", &message.body)?;
|
||||||
|
} else if message.mimetype == "text/html" {
|
||||||
|
st.serialize_field("org.matrix.msc1767.html", &message.body)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
st.end()
|
||||||
} else {
|
} else {
|
||||||
|
let mut st = serializer.serialize_struct("MessageContent", 1)?;
|
||||||
st.serialize_field("org.matrix.msc1767.message", &self.0)?;
|
st.serialize_field("org.matrix.msc1767.message", &self.0)?;
|
||||||
|
st.end()
|
||||||
}
|
}
|
||||||
st.end()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,10 +172,8 @@ fn event_serialization() {
|
|||||||
to_json_value(&event).unwrap(),
|
to_json_value(&event).unwrap(),
|
||||||
json!({
|
json!({
|
||||||
"content": {
|
"content": {
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "Upload: <strong>my_mix.mp3</strong>",
|
||||||
{ "body": "Upload: <strong>my_mix.mp3</strong>", "mimetype": "text/html"},
|
"org.matrix.msc1767.text": "Upload: my_mix.mp3",
|
||||||
{ "body": "Upload: my_mix.mp3", "mimetype": "text/plain"},
|
|
||||||
],
|
|
||||||
"m.file": {
|
"m.file": {
|
||||||
"url": "mxc://notareal.hs/abcdef",
|
"url": "mxc://notareal.hs/abcdef",
|
||||||
"name": "my_mix.mp3",
|
"name": "my_mix.mp3",
|
||||||
|
@ -126,10 +126,8 @@ fn file_event_serialization() {
|
|||||||
to_json_value(&event).unwrap(),
|
to_json_value(&event).unwrap(),
|
||||||
json!({
|
json!({
|
||||||
"content": {
|
"content": {
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "Upload: <strong>my_file.txt</strong>",
|
||||||
{ "body": "Upload: <strong>my_file.txt</strong>", "mimetype": "text/html"},
|
"org.matrix.msc1767.text": "Upload: my_file.txt",
|
||||||
{ "body": "Upload: my_file.txt", "mimetype": "text/plain"},
|
|
||||||
],
|
|
||||||
"m.file": {
|
"m.file": {
|
||||||
"url": "mxc://notareal.hs/abcdef",
|
"url": "mxc://notareal.hs/abcdef",
|
||||||
"name": "my_file.txt",
|
"name": "my_file.txt",
|
||||||
|
@ -147,10 +147,8 @@ fn image_event_serialization() {
|
|||||||
to_json_value(&event).unwrap(),
|
to_json_value(&event).unwrap(),
|
||||||
json!({
|
json!({
|
||||||
"content": {
|
"content": {
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "Upload: <strong>my_house.jpg</strong>",
|
||||||
{ "body": "Upload: <strong>my_house.jpg</strong>", "mimetype": "text/html"},
|
"org.matrix.msc1767.text": "Upload: my_house.jpg",
|
||||||
{ "body": "Upload: my_house.jpg", "mimetype": "text/plain"},
|
|
||||||
],
|
|
||||||
"m.file": {
|
"m.file": {
|
||||||
"url": "mxc://notareal.hs/abcdef",
|
"url": "mxc://notareal.hs/abcdef",
|
||||||
"name": "my_house.jpg",
|
"name": "my_house.jpg",
|
||||||
|
@ -70,16 +70,8 @@ fn event_serialization() {
|
|||||||
to_json_value(&event).unwrap(),
|
to_json_value(&event).unwrap(),
|
||||||
json!({
|
json!({
|
||||||
"content": {
|
"content": {
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "Alice was at <strong>geo:51.5008,0.1247;u=35</strong> as of <em>Sat Nov 13 18:50:58 2021</em>",
|
||||||
{
|
"org.matrix.msc1767.text": "Alice was at geo:51.5008,0.1247;u=35 as of Sat Nov 13 18:50:58 2021",
|
||||||
"body": "Alice was at <strong>geo:51.5008,0.1247;u=35</strong> as of <em>Sat Nov 13 18:50:58 2021</em>",
|
|
||||||
"mimetype": "text/html",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"body": "Alice was at geo:51.5008,0.1247;u=35 as of Sat Nov 13 18:50:58 2021",
|
|
||||||
"mimetype": "text/plain",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"m.location": {
|
"m.location": {
|
||||||
"uri": "geo:51.5008,0.1247;u=35",
|
"uri": "geo:51.5008,0.1247;u=35",
|
||||||
"description": "Alice's whereabouts",
|
"description": "Alice's whereabouts",
|
||||||
|
@ -37,10 +37,8 @@ fn html_content_serialization() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
to_json_value(&message_event_content).unwrap(),
|
to_json_value(&message_event_content).unwrap(),
|
||||||
json!({
|
json!({
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "Hello, <em>World</em>!",
|
||||||
{ "body": "Hello, <em>World</em>!", "mimetype": "text/html"},
|
"org.matrix.msc1767.text": "Hello, World!",
|
||||||
{ "body": "Hello, World!", "mimetype": "text/plain"},
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -96,10 +94,8 @@ fn markdown_content_serialization() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
to_json_value(&formatted_message).unwrap(),
|
to_json_value(&formatted_message).unwrap(),
|
||||||
json!({
|
json!({
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "<p>Testing <strong>bold</strong> and <em>italic</em>!</p>\n",
|
||||||
{ "body": "<p>Testing <strong>bold</strong> and <em>italic</em>!</p>\n", "mimetype": "text/html"},
|
"org.matrix.msc1767.text": "Testing **bold** and _italic_!",
|
||||||
{ "body": "Testing **bold** and _italic_!", "mimetype": "text/plain"},
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -118,10 +114,8 @@ fn markdown_content_serialization() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
to_json_value(&plain_message_paragraphs).unwrap(),
|
to_json_value(&plain_message_paragraphs).unwrap(),
|
||||||
json!({
|
json!({
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "<p>Testing</p>\n<p>Several</p>\n<p>Paragraphs.</p>\n",
|
||||||
{ "body": "<p>Testing</p>\n<p>Several</p>\n<p>Paragraphs.</p>\n", "mimetype": "text/html"},
|
"org.matrix.msc1767.text": "Testing\n\nSeveral\n\nParagraphs.",
|
||||||
{ "body": "Testing\n\nSeveral\n\nParagraphs.", "mimetype": "text/plain"},
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -198,7 +192,53 @@ fn plain_text_content_stable_deserialization() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn html_text_content_unstable_deserialization() {
|
fn html_content_unstable_deserialization() {
|
||||||
|
let json_data = json!({
|
||||||
|
"org.matrix.msc1767.html": "Hello, <em>New World</em>!",
|
||||||
|
});
|
||||||
|
|
||||||
|
let content = from_json_value::<MessageEventContent>(json_data).unwrap();
|
||||||
|
assert_eq!(content.message.find_plain(), None);
|
||||||
|
assert_eq!(content.message.find_html(), Some("Hello, <em>New World</em>!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn html_content_stable_deserialization() {
|
||||||
|
let json_data = json!({
|
||||||
|
"m.html": "Hello, <em>New World</em>!",
|
||||||
|
});
|
||||||
|
|
||||||
|
let content = from_json_value::<MessageEventContent>(json_data).unwrap();
|
||||||
|
assert_eq!(content.message.find_plain(), None);
|
||||||
|
assert_eq!(content.message.find_html(), Some("Hello, <em>New World</em>!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn html_and_text_content_unstable_deserialization() {
|
||||||
|
let json_data = json!({
|
||||||
|
"org.matrix.msc1767.html": "Hello, <em>New World</em>!",
|
||||||
|
"org.matrix.msc1767.text": "Hello, New World!",
|
||||||
|
});
|
||||||
|
|
||||||
|
let content = from_json_value::<MessageEventContent>(json_data).unwrap();
|
||||||
|
assert_eq!(content.message.find_plain(), Some("Hello, New World!"));
|
||||||
|
assert_eq!(content.message.find_html(), Some("Hello, <em>New World</em>!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn html_and_text_content_stable_deserialization() {
|
||||||
|
let json_data = json!({
|
||||||
|
"m.html": "Hello, <em>New World</em>!",
|
||||||
|
"m.text": "Hello, New World!",
|
||||||
|
});
|
||||||
|
|
||||||
|
let content = from_json_value::<MessageEventContent>(json_data).unwrap();
|
||||||
|
assert_eq!(content.message.find_plain(), Some("Hello, New World!"));
|
||||||
|
assert_eq!(content.message.find_html(), Some("Hello, <em>New World</em>!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn message_content_unstable_deserialization() {
|
||||||
let json_data = json!({
|
let json_data = json!({
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.message": [
|
||||||
{ "body": "Hello, <em>New World</em>!", "mimetype": "text/html"},
|
{ "body": "Hello, <em>New World</em>!", "mimetype": "text/html"},
|
||||||
@ -212,7 +252,7 @@ fn html_text_content_unstable_deserialization() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn html_text_content_stable_deserialization() {
|
fn message_content_stable_deserialization() {
|
||||||
let json_data = json!({
|
let json_data = json!({
|
||||||
"m.message": [
|
"m.message": [
|
||||||
{ "body": "Hello, <em>New World</em>!", "mimetype": "text/html"},
|
{ "body": "Hello, <em>New World</em>!", "mimetype": "text/html"},
|
||||||
@ -315,7 +355,61 @@ fn room_message_plain_text_unstable_deserialization() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn room_message_html_text_stable_deserialization() {
|
fn room_message_html_and_text_stable_deserialization() {
|
||||||
|
let json_data = json!({
|
||||||
|
"body": "test",
|
||||||
|
"formatted_body": "<h1>test</h1>",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"m.html": "<h1>test</h1>",
|
||||||
|
"m.text": "test",
|
||||||
|
});
|
||||||
|
|
||||||
|
let content = assert_matches!(
|
||||||
|
from_json_value::<RoomMessageEventContent>(json_data),
|
||||||
|
Ok(RoomMessageEventContent {
|
||||||
|
msgtype: MessageType::Text(content),
|
||||||
|
..
|
||||||
|
}) => content
|
||||||
|
);
|
||||||
|
assert_eq!(content.body, "test");
|
||||||
|
let formatted = content.formatted.unwrap();
|
||||||
|
assert_eq!(formatted.body, "<h1>test</h1>");
|
||||||
|
let message = content.message.unwrap();
|
||||||
|
assert_eq!(message.len(), 2);
|
||||||
|
assert_eq!(message[0].body, "<h1>test</h1>");
|
||||||
|
assert_eq!(message[1].body, "test");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn room_message_html_and_text_unstable_deserialization() {
|
||||||
|
let json_data = json!({
|
||||||
|
"body": "test",
|
||||||
|
"formatted_body": "<h1>test</h1>",
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"org.matrix.msc1767.html": "<h1>test</h1>",
|
||||||
|
"org.matrix.msc1767.text": "test",
|
||||||
|
});
|
||||||
|
|
||||||
|
let content = assert_matches!(
|
||||||
|
from_json_value::<RoomMessageEventContent>(json_data),
|
||||||
|
Ok(RoomMessageEventContent {
|
||||||
|
msgtype: MessageType::Text(content),
|
||||||
|
..
|
||||||
|
}) => content
|
||||||
|
);
|
||||||
|
assert_eq!(content.body, "test");
|
||||||
|
let formatted = content.formatted.unwrap();
|
||||||
|
assert_eq!(formatted.body, "<h1>test</h1>");
|
||||||
|
let message = content.message.unwrap();
|
||||||
|
assert_eq!(message.len(), 2);
|
||||||
|
assert_eq!(message[0].body, "<h1>test</h1>");
|
||||||
|
assert_eq!(message[1].body, "test");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn room_message_message_stable_deserialization() {
|
||||||
let json_data = json!({
|
let json_data = json!({
|
||||||
"body": "test",
|
"body": "test",
|
||||||
"formatted_body": "<h1>test</h1>",
|
"formatted_body": "<h1>test</h1>",
|
||||||
@ -344,7 +438,7 @@ fn room_message_html_text_stable_deserialization() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn room_message_html_text_unstable_deserialization() {
|
fn room_message_message_unstable_deserialization() {
|
||||||
let json_data = json!({
|
let json_data = json!({
|
||||||
"body": "test",
|
"body": "test",
|
||||||
"formatted_body": "<h1>test</h1>",
|
"formatted_body": "<h1>test</h1>",
|
||||||
@ -537,10 +631,8 @@ fn emote_event_serialization() {
|
|||||||
to_json_value(&event).unwrap(),
|
to_json_value(&event).unwrap(),
|
||||||
json!({
|
json!({
|
||||||
"content": {
|
"content": {
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "is testing some <code>code</code>…",
|
||||||
{ "body": "is testing some <code>code</code>…", "mimetype": "text/html" },
|
"org.matrix.msc1767.text": "is testing some code…",
|
||||||
{ "body": "is testing some code…", "mimetype": "text/plain" },
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"event_id": "$event:notareal.hs",
|
"event_id": "$event:notareal.hs",
|
||||||
"origin_server_ts": 134_829_848,
|
"origin_server_ts": 134_829_848,
|
||||||
|
@ -192,10 +192,8 @@ fn formatted_body_serialization() {
|
|||||||
"msgtype": "m.text",
|
"msgtype": "m.text",
|
||||||
"format": "org.matrix.custom.html",
|
"format": "org.matrix.custom.html",
|
||||||
"formatted_body": "Hello, <em>World</em>!",
|
"formatted_body": "Hello, <em>World</em>!",
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "Hello, <em>World</em>!",
|
||||||
{ "body": "Hello, <em>World</em>!", "mimetype": "text/html" },
|
"org.matrix.msc1767.text": "Hello, World!",
|
||||||
{ "body": "Hello, World!", "mimetype": "text/plain" },
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -253,10 +251,8 @@ fn markdown_content_serialization() {
|
|||||||
"formatted_body": "<p>Testing <strong>bold</strong> and <em>italic</em>!</p>\n",
|
"formatted_body": "<p>Testing <strong>bold</strong> and <em>italic</em>!</p>\n",
|
||||||
"format": "org.matrix.custom.html",
|
"format": "org.matrix.custom.html",
|
||||||
"msgtype": "m.text",
|
"msgtype": "m.text",
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "<p>Testing <strong>bold</strong> and <em>italic</em>!</p>\n",
|
||||||
{ "body": "<p>Testing <strong>bold</strong> and <em>italic</em>!</p>\n", "mimetype": "text/html" },
|
"org.matrix.msc1767.text": "Testing **bold** and _italic_!",
|
||||||
{ "body": "Testing **bold** and _italic_!", "mimetype": "text/plain" },
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -306,10 +302,8 @@ fn markdown_content_serialization() {
|
|||||||
"formatted_body": "<p>Testing</p>\n<p>Several</p>\n<p>Paragraphs.</p>\n",
|
"formatted_body": "<p>Testing</p>\n<p>Several</p>\n<p>Paragraphs.</p>\n",
|
||||||
"format": "org.matrix.custom.html",
|
"format": "org.matrix.custom.html",
|
||||||
"msgtype": "m.text",
|
"msgtype": "m.text",
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "<p>Testing</p>\n<p>Several</p>\n<p>Paragraphs.</p>\n",
|
||||||
{ "body": "<p>Testing</p>\n<p>Several</p>\n<p>Paragraphs.</p>\n", "mimetype": "text/html" },
|
"org.matrix.msc1767.text": "Testing\n\nSeveral\n\nParagraphs.",
|
||||||
{ "body": "Testing\n\nSeveral\n\nParagraphs.", "mimetype": "text/plain" },
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -154,10 +154,8 @@ fn event_serialization() {
|
|||||||
to_json_value(&event).unwrap(),
|
to_json_value(&event).unwrap(),
|
||||||
json!({
|
json!({
|
||||||
"content": {
|
"content": {
|
||||||
"org.matrix.msc1767.message": [
|
"org.matrix.msc1767.html": "Upload: <strong>my_lava_lamp.webm</strong>",
|
||||||
{ "body": "Upload: <strong>my_lava_lamp.webm</strong>", "mimetype": "text/html"},
|
"org.matrix.msc1767.text": "Upload: my_lava_lamp.webm",
|
||||||
{ "body": "Upload: my_lava_lamp.webm", "mimetype": "text/plain"},
|
|
||||||
],
|
|
||||||
"m.file": {
|
"m.file": {
|
||||||
"url": "mxc://notareal.hs/abcdef",
|
"url": "mxc://notareal.hs/abcdef",
|
||||||
"name": "my_lava_lamp.webm",
|
"name": "my_lava_lamp.webm",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user