1#include "mtx/events/collections.hpp"
2#include "mtx/events_impl.hpp"
3#include "mtx/log.hpp"
4
5#include <nlohmann/json.hpp>
6
7namespace mtx::events {
8using namespace mtx::events::collections;
9
10#define MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(EventType, Content) \
11 template void to_json<Content>(nlohmann::json &, const EventType<Content> &); \
12 template void from_json<Content>(const nlohmann::json &, EventType<Content> &);
13
14MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::Aliases)
15MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::Avatar)
16MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::CanonicalAlias)
17MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::Create)
18MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::Encryption)
19MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::GuestAccess)
20MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::HistoryVisibility)
21MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::JoinRules)
22MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::Member)
23MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::Name)
24MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::PinnedEvents)
25MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::PowerLevels)
26MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::Tombstone)
27MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::Topic)
28MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::Widget)
29MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::policy_rule::UserRule)
30MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::policy_rule::RoomRule)
31MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent,
32 mtx::events::state::policy_rule::ServerRule)
33MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::space::Child)
34MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::state::space::Parent)
35MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, mtx::events::msg::Redacted)
36MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, msc2545::ImagePack)
37MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StateEvent, Unknown)
38MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::EncryptedEvent, mtx::events::msg::Encrypted)
39MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::EncryptedEvent, mtx::events::msg::OlmEncrypted)
40MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::StickerImage)
41MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Reaction)
42MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Redacted)
43MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Audio)
44MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Confetti)
45MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Emote)
46MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::File)
47MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Image)
48MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Notice)
49MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Text)
50MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::Video)
51MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::KeyVerificationRequest)
52MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::KeyVerificationStart)
53MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::KeyVerificationReady)
54MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::KeyVerificationDone)
55MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::KeyVerificationAccept)
56MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::KeyVerificationCancel)
57MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::KeyVerificationKey)
58MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::msg::KeyVerificationMac)
59MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::voip::CallInvite)
60MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::voip::CallCandidates)
61MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::voip::CallAnswer)
62MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::voip::CallHangUp)
63MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::voip::CallSelectAnswer)
64MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::voip::CallReject)
65MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, mtx::events::voip::CallNegotiate)
66MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RoomEvent, Unknown)
67
68MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::Aliases)
69MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::Avatar)
70MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::CanonicalAlias)
71MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::Create)
72MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::Encryption)
73MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::GuestAccess)
74MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::HistoryVisibility)
75MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::JoinRules)
76MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::Member)
77MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::Name)
78MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::PinnedEvents)
79MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::PowerLevels)
80MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::Tombstone)
81MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::Topic)
82MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::Widget)
83MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent,
84 mtx::events::state::policy_rule::UserRule)
85MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent,
86 mtx::events::state::policy_rule::RoomRule)
87MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent,
88 mtx::events::state::policy_rule::ServerRule)
89MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::space::Child)
90MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, mtx::events::state::space::Parent)
91MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, msg::Redacted)
92MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::StrippedEvent, Unknown)
93
94MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::Encrypted)
95MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::OlmEncrypted)
96MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::KeyVerificationRequest)
97MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::KeyVerificationStart)
98MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::KeyVerificationReady)
99MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::KeyVerificationDone)
100MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::KeyVerificationAccept)
101MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::KeyVerificationCancel)
102MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::KeyVerificationKey)
103MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::KeyVerificationMac)
104MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::RoomKey)
105MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::ForwardedRoomKey)
106MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::KeyRequest)
107MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::SecretRequest)
108MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::SecretSend)
109MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, mtx::events::msg::Dummy)
110MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::DeviceEvent, Unknown)
111
112MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::EphemeralEvent, ephemeral::Typing)
113MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::EphemeralEvent, ephemeral::Receipt)
114MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::EphemeralEvent, Unknown)
115
116MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent, mtx::events::account_data::Direct)
117MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent, mtx::events::account_data::Tags)
118MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent, mtx::events::account_data::FullyRead)
119MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent, pushrules::GlobalRuleset)
120MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent,
121 mtx::events::account_data::nheko_extensions::HiddenEvents)
122MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent, msc2545::ImagePackRooms)
123MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::AccountDataEvent, msc2545::ImagePack)
124MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::Event, presence::Presence)
125
126MTXCLIENT_INSTANTIATE_JSON_FUNCTIONS(events::RedactionEvent, msg::Redaction)
127}
128
129namespace mtx::events::collections {
130void
131to_json(nlohmann::json &obj, const TimelineEvent &e)
132{
133 std::visit(visitor: [&obj](const auto &ev) { return to_json(obj, ev); }, variants: e.data);
134}
135
136void
137from_json(const nlohmann::json &obj, TimelineEvent &e)
138{
139 const auto type = mtx::events::getEventType(obj);
140 using namespace mtx::events::state;
141 using namespace mtx::events::msg;
142 using namespace mtx::events::voip;
143
144 try {
145 if (obj.contains(key: "unsigned") && obj["unsigned"].contains(key: "redacted_by")) {
146 if (obj.contains(key: "state_key"))
147 e.data = events::StateEvent<msg::Redacted>(obj);
148 else
149 e.data = events::RoomEvent<msg::Redacted>(obj);
150 return;
151 }
152
153 switch (type) {
154 case events::EventType::Reaction: {
155 e.data = events::RoomEvent<Reaction>(obj);
156 break;
157 }
158 case events::EventType::RoomAliases: {
159 e.data = events::StateEvent<Aliases>(obj);
160 break;
161 }
162 case events::EventType::RoomAvatar: {
163 e.data = events::StateEvent<Avatar>(obj);
164 break;
165 }
166 case events::EventType::RoomCanonicalAlias: {
167 e.data = events::StateEvent<CanonicalAlias>(obj);
168 break;
169 }
170 case events::EventType::RoomCreate: {
171 e.data = events::StateEvent<Create>(obj);
172 break;
173 }
174 case events::EventType::RoomEncrypted: {
175 e.data = events::EncryptedEvent<mtx::events::msg::Encrypted>(obj);
176 break;
177 }
178 case events::EventType::RoomEncryption: {
179 e.data = events::StateEvent<Encryption>(obj);
180 break;
181 }
182 case events::EventType::RoomGuestAccess: {
183 e.data = events::StateEvent<GuestAccess>(obj);
184 break;
185 }
186 case events::EventType::RoomHistoryVisibility: {
187 e.data = events::StateEvent<HistoryVisibility>(obj);
188 break;
189 }
190 case events::EventType::RoomJoinRules: {
191 e.data = events::StateEvent<JoinRules>(obj);
192 break;
193 }
194 case events::EventType::RoomMember: {
195 e.data = events::StateEvent<Member>(obj);
196 break;
197 }
198 case events::EventType::RoomName: {
199 e.data = events::StateEvent<Name>(obj);
200 break;
201 }
202 case events::EventType::RoomPowerLevels: {
203 e.data = events::StateEvent<PowerLevels>(obj);
204 break;
205 }
206 case events::EventType::RoomRedaction: {
207 e.data = events::RedactionEvent<mtx::events::msg::Redaction>(obj);
208 break;
209 }
210 case events::EventType::RoomTombstone: {
211 e.data = events::StateEvent<Tombstone>(obj);
212 break;
213 }
214 case events::EventType::RoomTopic: {
215 e.data = events::StateEvent<Topic>(obj);
216 break;
217 }
218 case events::EventType::Widget: {
219 e.data = events::StateEvent<Widget>(obj);
220 break;
221 }
222 case events::EventType::VectorWidget: {
223 e.data = events::StateEvent<Widget>(obj);
224 break;
225 }
226 case events::EventType::RoomPinnedEvents: {
227 e.data = events::StateEvent<PinnedEvents>(obj);
228 break;
229 }
230 case events::EventType::PolicyRuleUser: {
231 e.data = events::StateEvent<policy_rule::UserRule>(obj);
232 break;
233 }
234 case events::EventType::PolicyRuleRoom: {
235 e.data = events::StateEvent<policy_rule::RoomRule>(obj);
236 break;
237 }
238 case events::EventType::PolicyRuleServer: {
239 e.data = events::StateEvent<policy_rule::ServerRule>(obj);
240 break;
241 }
242 case events::EventType::SpaceChild: {
243 e.data = events::StateEvent<space::Child>(obj);
244 break;
245 }
246 case events::EventType::SpaceParent: {
247 e.data = events::StateEvent<space::Parent>(obj);
248 break;
249 }
250 case events::EventType::ImagePackInRoom: {
251 e.data = events::StateEvent<msc2545::ImagePack>(obj);
252 break;
253 }
254 case events::EventType::KeyVerificationCancel: {
255 e.data = events::RoomEvent<events::msg::KeyVerificationCancel>(obj);
256 break;
257 }
258 case events::EventType::KeyVerificationRequest: {
259 e.data = events::RoomEvent<events::msg::KeyVerificationRequest>(obj);
260 break;
261 }
262 case events::EventType::KeyVerificationReady: {
263 e.data = events::RoomEvent<events::msg::KeyVerificationReady>(obj);
264 break;
265 }
266 case events::EventType::KeyVerificationStart: {
267 e.data = events::RoomEvent<events::msg::KeyVerificationStart>(obj);
268 break;
269 }
270 case events::EventType::KeyVerificationDone: {
271 e.data = events::RoomEvent<events::msg::KeyVerificationDone>(obj);
272 break;
273 }
274 case events::EventType::KeyVerificationKey: {
275 e.data = events::RoomEvent<events::msg::KeyVerificationKey>(obj);
276 break;
277 }
278 case events::EventType::KeyVerificationMac: {
279 e.data = events::RoomEvent<events::msg::KeyVerificationMac>(obj);
280 break;
281 }
282 case events::EventType::KeyVerificationAccept: {
283 e.data = events::RoomEvent<events::msg::KeyVerificationAccept>(obj);
284 break;
285 }
286 case events::EventType::RoomMessage: {
287 using MsgType = mtx::events::MessageType;
288 const auto msg_type = mtx::events::getMessageType(obj: obj.at(key: "content"));
289
290 switch (msg_type) {
291 case MsgType::Audio: {
292 e.data = events::RoomEvent<events::msg::Audio>(obj);
293 break;
294 }
295 case MsgType::Confetti: {
296 e.data = events::RoomEvent<events::msg::Confetti>(obj);
297 break;
298 }
299 case MsgType::Emote: {
300 e.data = events::RoomEvent<events::msg::Emote>(obj);
301 break;
302 }
303 case MsgType::File: {
304 e.data = events::RoomEvent<events::msg::File>(obj);
305 break;
306 }
307 case MsgType::Image: {
308 e.data = events::RoomEvent<events::msg::Image>(obj);
309 break;
310 }
311 case MsgType::Location: {
312 /* events::RoomEvent<events::msg::Location> location = e; */
313 /* container.emplace_back(location); */
314 break;
315 }
316 case MsgType::Notice: {
317 e.data = events::RoomEvent<events::msg::Notice>(obj);
318 break;
319 }
320 case MsgType::Text: {
321 e.data = events::RoomEvent<events::msg::Text>(obj);
322 break;
323 }
324 case MsgType::Video: {
325 e.data = events::RoomEvent<events::msg::Video>(obj);
326 break;
327 }
328 case MsgType::KeyVerificationRequest: {
329 e.data = events::RoomEvent<events::msg::KeyVerificationRequest>(obj);
330 break;
331 }
332 case MsgType::Unknown: {
333 e.data = events::RoomEvent<events::Unknown>(obj);
334 break;
335 }
336 }
337 break;
338 }
339 case events::EventType::Sticker: {
340 e.data = events::Sticker(obj);
341 break;
342 }
343 case events::EventType::CallInvite: {
344 e.data = events::RoomEvent<events::voip::CallInvite>(obj);
345 break;
346 }
347 case events::EventType::CallCandidates: {
348 e.data = events::RoomEvent<events::voip::CallCandidates>(obj);
349 break;
350 }
351 case events::EventType::CallAnswer: {
352 e.data = events::RoomEvent<events::voip::CallAnswer>(obj);
353 break;
354 }
355 case events::EventType::CallHangUp: {
356 e.data = events::RoomEvent<events::voip::CallHangUp>(obj);
357 break;
358 }
359 case events::EventType::CallSelectAnswer: {
360 e.data = events::RoomEvent<events::voip::CallSelectAnswer>(obj);
361 break;
362 }
363 case events::EventType::CallReject: {
364 e.data = events::RoomEvent<events::voip::CallReject>(obj);
365 break;
366 }
367 case events::EventType::CallNegotiate: {
368 e.data = events::RoomEvent<events::voip::CallNegotiate>(obj);
369 break;
370 }
371 case events::EventType::Unsupported: {
372 e.data = events::RoomEvent<events::Unknown>(obj);
373 break;
374 }
375 case events::EventType::RoomKey: // not part of the timeline
376 case events::EventType::ForwardedRoomKey: // not part of the timeline
377 case events::EventType::RoomKeyRequest: // Not part of the timeline
378 case events::EventType::Direct: // Not part of the timeline
379 case events::EventType::Tag: // Not part of the timeline
380 case events::EventType::Presence: // Not part of the timeline
381 case events::EventType::PushRules: // Not part of the timeline
382 case events::EventType::SecretRequest: // Not part of the timeline
383 case events::EventType::SecretSend: // Not part of the timeline
384 case events::EventType::Typing:
385 case events::EventType::Receipt:
386 case events::EventType::FullyRead:
387 case events::EventType::NhekoHiddenEvents:
388 case events::EventType::ImagePackInAccountData:
389 case events::EventType::ImagePackRooms:
390 case events::EventType::Dummy:
391 break;
392 }
393 } catch (std::exception &err) {
394 mtx::utils::log::log()->error(fmt: "Invalid event type: {} {}", args: err.what(), args: obj.dump(indent: 2));
395 e.data = events::RoomEvent<events::Unknown>(obj);
396 }
397}
398}
399