1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use serde_json::Value;
use serde_json::Error as SerdeError;
#[cfg(feature="gitm_deny_unknown")]
use serde::de;
pub mod room;
pub mod root;
pub mod call;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct PublicKey {
pub public_key: String,
pub key_validity_url: Option<String>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(untagged)]
pub enum Content {
RoomAliases(room::Aliases),
RoomAvatar(room::Avatar),
RoomCanonicalAlias(room::CanonicalAlias),
RoomCreate(room::Create),
RoomGuestAccess(room::GuestAccess),
RoomHistoryVisibility(room::HistoryVisibility),
RoomJoinRules(room::JoinRules),
RoomMember(room::Member),
RoomName(room::Name),
RoomPowerLevels(room::PowerLevels),
RoomRedaction(room::Redaction),
RoomTopic(room::Topic),
RoomMessage(room::Message),
RootDirect(root::Direct),
RootPresence(root::Presence),
RootReceipt(root::Receipt),
RootTag(root::Tag),
RootTyping(root::Typing),
CallInvite(call::Invite),
CallCandidates(call::Candidates),
CallAnswer(call::Answer),
CallHangup(call::Hangup),
#[cfg(not(feature="gitm_deny_unknown"))]
Unknown(::serde_json::Value),
}
macro_rules! matchy_matchy {
($in:ident, $val:ident, $($a:pat, $t:ident),*) => {
match $in {
$(
$a => Content::$t(::serde_json::from_value($val)?),
)*
#[cfg(not(feature="gitm_deny_unknown"))]
_ => Content::Unknown($val),
#[cfg(feature="gitm_deny_unknown")]
x => de::Error::custom(format!("Unknown content type {}", $in))?
}
}
}
pub fn deserialize_content(typ: &str, val: Value) -> Result<Content, SerdeError> {
let res = matchy_matchy! {
typ, val,
"m.room.aliases", RoomAliases,
"m.room.avatar", RoomAvatar,
"m.room.canonical_alias", RoomCanonicalAlias,
"m.room.create", RoomCreate,
"m.room.guest_access", RoomGuestAccess,
"m.room.history_visibility", RoomHistoryVisibility,
"m.room.join_rules", RoomJoinRules,
"m.room.member", RoomMember,
"m.room.name", RoomName,
"m.room.power_levels", RoomPowerLevels,
"m.room.redaction", RoomRedaction,
"m.room.topic", RoomTopic,
"m.room.message", RoomMessage,
"m.direct", RootDirect,
"m.presence", RootPresence,
"m.receipt", RootReceipt,
"m.tag", RootTag,
"m.typing", RootTyping,
"m.call.invite", CallInvite,
"m.call.candidates", CallCandidates,
"m.call.answer", CallAnswer,
"m.call.hangup", CallHangup
};
Ok(res)
}