ruma_events/room/message/
content_serde.rs1use ruma_common::serde::from_raw_json_value;
4use serde::{de, Deserialize};
5use serde_json::value::RawValue as RawJsonValue;
6
7use super::{
8 relation_serde::deserialize_relation, MessageType, RoomMessageEventContent,
9 RoomMessageEventContentWithoutRelation,
10};
11use crate::Mentions;
12
13impl<'de> Deserialize<'de> for RoomMessageEventContent {
14 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
15 where
16 D: de::Deserializer<'de>,
17 {
18 let json = Box::<RawJsonValue>::deserialize(deserializer)?;
19
20 let mut deserializer = serde_json::Deserializer::from_str(json.get());
21 let relates_to = deserialize_relation(&mut deserializer).map_err(de::Error::custom)?;
22
23 let MentionsDeHelper { mentions } = from_raw_json_value(&json)?;
24
25 Ok(Self { msgtype: from_raw_json_value(&json)?, relates_to, mentions })
26 }
27}
28
29impl<'de> Deserialize<'de> for RoomMessageEventContentWithoutRelation {
30 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
31 where
32 D: de::Deserializer<'de>,
33 {
34 let json = Box::<RawJsonValue>::deserialize(deserializer)?;
35
36 let MentionsDeHelper { mentions } = from_raw_json_value(&json)?;
37
38 Ok(Self { msgtype: from_raw_json_value(&json)?, mentions })
39 }
40}
41
42#[derive(Deserialize)]
43struct MentionsDeHelper {
44 #[serde(rename = "m.mentions")]
45 mentions: Option<Mentions>,
46}
47
48#[derive(Debug, Deserialize)]
50struct MessageTypeDeHelper {
51 msgtype: String,
53}
54
55impl<'de> Deserialize<'de> for MessageType {
56 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
57 where
58 D: de::Deserializer<'de>,
59 {
60 let json = Box::<RawJsonValue>::deserialize(deserializer)?;
61 let MessageTypeDeHelper { msgtype } = from_raw_json_value(&json)?;
62
63 Ok(match msgtype.as_ref() {
64 "m.audio" => Self::Audio(from_raw_json_value(&json)?),
65 "m.emote" => Self::Emote(from_raw_json_value(&json)?),
66 "m.file" => Self::File(from_raw_json_value(&json)?),
67 "m.image" => Self::Image(from_raw_json_value(&json)?),
68 "m.location" => Self::Location(from_raw_json_value(&json)?),
69 "m.notice" => Self::Notice(from_raw_json_value(&json)?),
70 "m.server_notice" => Self::ServerNotice(from_raw_json_value(&json)?),
71 "m.text" => Self::Text(from_raw_json_value(&json)?),
72 "m.video" => Self::Video(from_raw_json_value(&json)?),
73 "m.key.verification.request" => Self::VerificationRequest(from_raw_json_value(&json)?),
74 _ => Self::_Custom(from_raw_json_value(&json)?),
75 })
76 }
77}
78
79#[allow(unreachable_pub)] #[cfg(feature = "unstable-msc3488")]
81pub(in super::super) mod msc3488 {
82 use ruma_common::MilliSecondsSinceUnixEpoch;
83 use serde::{Deserialize, Serialize};
84
85 use crate::{
86 location::{AssetContent, LocationContent},
87 message::historical_serde::MessageContentBlock,
88 room::message::{LocationInfo, LocationMessageEventContent},
89 };
90
91 #[derive(Serialize, Deserialize)]
93 #[serde(tag = "msgtype", rename = "m.location")]
94 pub(in super::super) struct LocationMessageEventContentSerDeHelper {
95 pub body: String,
96
97 pub geo_uri: String,
98
99 #[serde(skip_serializing_if = "Option::is_none")]
100 pub info: Option<Box<LocationInfo>>,
101
102 #[serde(flatten)]
103 pub message: Option<MessageContentBlock>,
104
105 #[serde(rename = "org.matrix.msc3488.location", skip_serializing_if = "Option::is_none")]
106 pub location: Option<LocationContent>,
107
108 #[serde(rename = "org.matrix.msc3488.asset", skip_serializing_if = "Option::is_none")]
109 pub asset: Option<AssetContent>,
110
111 #[serde(rename = "org.matrix.msc3488.ts", skip_serializing_if = "Option::is_none")]
112 pub ts: Option<MilliSecondsSinceUnixEpoch>,
113 }
114
115 impl From<LocationMessageEventContent> for LocationMessageEventContentSerDeHelper {
116 fn from(value: LocationMessageEventContent) -> Self {
117 let LocationMessageEventContent { body, geo_uri, info, message, location, asset, ts } =
118 value;
119
120 Self { body, geo_uri, info, message: message.map(Into::into), location, asset, ts }
121 }
122 }
123
124 impl From<LocationMessageEventContentSerDeHelper> for LocationMessageEventContent {
125 fn from(value: LocationMessageEventContentSerDeHelper) -> Self {
126 let LocationMessageEventContentSerDeHelper {
127 body,
128 geo_uri,
129 info,
130 message,
131 location,
132 asset,
133 ts,
134 } = value;
135
136 LocationMessageEventContent {
137 body,
138 geo_uri,
139 info,
140 message: message.map(Into::into),
141 location,
142 asset,
143 ts,
144 }
145 }
146 }
147}