events: Provide type for historical m.message content block instead of serde helper

This commit is contained in:
Kévin Commaille 2023-06-25 14:07:25 +02:00 committed by Kévin Commaille
parent 201f0027d4
commit df11c6d46a
2 changed files with 43 additions and 19 deletions

View File

@ -6,6 +6,24 @@ use serde::{Deserialize, Serialize};
use super::{TextContentBlock, TextRepresentation};
/// Historical `m.message` text content block from MSC1767.
#[derive(Clone, Default, Serialize, Deserialize)]
#[serde(try_from = "MessageContentBlockSerDeHelper")]
#[serde(into = "MessageContentBlockSerDeHelper")]
pub(in crate::events) struct MessageContentBlock(Vec<TextRepresentation>);
impl From<MessageContentBlock> for TextContentBlock {
fn from(value: MessageContentBlock) -> Self {
Self(value.0)
}
}
impl From<TextContentBlock> for MessageContentBlock {
fn from(value: TextContentBlock) -> Self {
Self(value.0)
}
}
#[derive(Default, Serialize, Deserialize)]
pub(in crate::events) struct MessageContentBlockSerDeHelper {
/// Plain text short form.
@ -21,14 +39,14 @@ pub(in crate::events) struct MessageContentBlockSerDeHelper {
message: Option<Vec<TextRepresentation>>,
}
impl TryFrom<MessageContentBlockSerDeHelper> for TextContentBlock {
impl TryFrom<MessageContentBlockSerDeHelper> for Vec<TextRepresentation> {
type Error = &'static str;
fn try_from(value: MessageContentBlockSerDeHelper) -> Result<Self, Self::Error> {
let MessageContentBlockSerDeHelper { text, html, message } = value;
if let Some(message) = message {
Ok(Self(message))
Ok(message)
} else {
let message: Vec<_> = html
.map(TextRepresentation::html)
@ -36,7 +54,7 @@ impl TryFrom<MessageContentBlockSerDeHelper> for TextContentBlock {
.chain(text.map(TextRepresentation::plain))
.collect();
if !message.is_empty() {
Ok(Self(message))
Ok(message)
} else {
Err("missing at least one of fields `org.matrix.msc1767.text`, `org.matrix.msc1767.html` or `org.matrix.msc1767.message`")
}
@ -44,15 +62,23 @@ impl TryFrom<MessageContentBlockSerDeHelper> for TextContentBlock {
}
}
impl From<TextContentBlock> for MessageContentBlockSerDeHelper {
fn from(value: TextContentBlock) -> Self {
impl TryFrom<MessageContentBlockSerDeHelper> for MessageContentBlock {
type Error = &'static str;
fn try_from(value: MessageContentBlockSerDeHelper) -> Result<Self, Self::Error> {
Ok(Self(value.try_into()?))
}
}
impl From<Vec<TextRepresentation>> for MessageContentBlockSerDeHelper {
fn from(value: Vec<TextRepresentation>) -> Self {
let has_shortcut =
|message: &TextRepresentation| matches!(&*message.mimetype, "text/plain" | "text/html");
if value.iter().all(has_shortcut) {
let mut helper = Self::default();
for message in value.0.into_iter() {
for message in value.into_iter() {
if message.mimetype == "text/plain" {
helper.text = Some(message.body);
} else if message.mimetype == "text/html" {
@ -62,7 +88,13 @@ impl From<TextContentBlock> for MessageContentBlockSerDeHelper {
helper
} else {
Self { message: Some(value.0), ..Default::default() }
Self { message: Some(value), ..Default::default() }
}
}
}
impl From<MessageContentBlock> for MessageContentBlockSerDeHelper {
fn from(value: MessageContentBlock) -> Self {
value.0.into()
}
}

View File

@ -83,7 +83,7 @@ pub(in super::super) mod msc3488 {
use crate::{
events::{
location::{AssetContent, LocationContent},
message::historical_serde::MessageContentBlockSerDeHelper,
message::historical_serde::MessageContentBlock,
room::message::{LocationInfo, LocationMessageEventContent},
},
MilliSecondsSinceUnixEpoch,
@ -101,7 +101,7 @@ pub(in super::super) mod msc3488 {
pub info: Option<Box<LocationInfo>>,
#[serde(flatten)]
pub message: MessageContentBlockSerDeHelper,
pub message: Option<MessageContentBlock>,
#[serde(rename = "org.matrix.msc3488.location", skip_serializing_if = "Option::is_none")]
pub location: Option<LocationContent>,
@ -118,15 +118,7 @@ pub(in super::super) mod msc3488 {
let LocationMessageEventContent { body, geo_uri, info, message, location, asset, ts } =
value;
Self {
body,
geo_uri,
info,
message: message.map(Into::into).unwrap_or_default(),
location,
asset,
ts,
}
Self { body, geo_uri, info, message: message.map(Into::into), location, asset, ts }
}
}
@ -146,7 +138,7 @@ pub(in super::super) mod msc3488 {
body,
geo_uri,
info,
message: message.try_into().ok(),
message: message.map(Into::into),
location,
asset,
ts,