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