ruma_events/
media_preview_config.rs1use ruma_common::serde::JsonCastable;
6use ruma_macros::StringEnum;
7use serde::{Deserialize, Serialize};
8
9use crate::{PrivOwnedStr, macros::EventContent};
10
11#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
13#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
14#[ruma_event(type = "m.media_preview_config", kind = GlobalAccountData + RoomAccountData)]
15pub struct MediaPreviewConfigEventContent {
16 #[serde(skip_serializing_if = "Option::is_none")]
18 pub media_previews: Option<MediaPreviews>,
19
20 #[serde(skip_serializing_if = "Option::is_none")]
22 pub invite_avatars: Option<InviteAvatars>,
23}
24
25impl JsonCastable<UnstableMediaPreviewConfigEventContent> for MediaPreviewConfigEventContent {}
26
27#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
30#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
31#[ruma_event(type = "io.element.msc4278.media_preview_config", kind = GlobalAccountData + RoomAccountData)]
32#[serde(transparent)]
33pub struct UnstableMediaPreviewConfigEventContent(pub MediaPreviewConfigEventContent);
34
35impl JsonCastable<MediaPreviewConfigEventContent> for UnstableMediaPreviewConfigEventContent {}
36
37#[derive(Clone, StringEnum, Default)]
39#[ruma_enum(rename_all = "lowercase")]
40#[non_exhaustive]
41pub enum MediaPreviews {
42 Off,
44
45 Private,
47
48 #[default]
50 On,
51
52 #[doc(hidden)]
53 _Custom(PrivOwnedStr),
54}
55
56#[derive(Clone, StringEnum, Default)]
58#[ruma_enum(rename_all = "lowercase")]
59#[non_exhaustive]
60pub enum InviteAvatars {
61 Off,
63
64 #[default]
66 On,
67
68 #[doc(hidden)]
69 _Custom(PrivOwnedStr),
70}
71
72impl MediaPreviewConfigEventContent {
73 pub fn new() -> Self {
75 Self::default()
76 }
77
78 pub fn media_previews(mut self, media_previews: Option<MediaPreviews>) -> Self {
80 self.media_previews = media_previews;
81 self
82 }
83
84 pub fn invite_avatars(mut self, invite_avatars: Option<InviteAvatars>) -> Self {
86 self.invite_avatars = invite_avatars;
87 self
88 }
89
90 pub fn merge_global_and_room_config(global_config: Self, room_config: Self) -> Self {
95 Self {
96 media_previews: room_config.media_previews.or(global_config.media_previews),
97 invite_avatars: room_config.invite_avatars.or(global_config.invite_avatars),
98 }
99 }
100}
101
102impl std::ops::Deref for UnstableMediaPreviewConfigEventContent {
103 type Target = MediaPreviewConfigEventContent;
104
105 fn deref(&self) -> &Self::Target {
106 &self.0
107 }
108}
109
110impl From<MediaPreviewConfigEventContent> for UnstableMediaPreviewConfigEventContent {
111 fn from(value: MediaPreviewConfigEventContent) -> Self {
112 Self(value)
113 }
114}
115
116impl From<UnstableMediaPreviewConfigEventContent> for MediaPreviewConfigEventContent {
117 fn from(value: UnstableMediaPreviewConfigEventContent) -> Self {
118 value.0
119 }
120}
121
122#[cfg(all(test, feature = "unstable-msc4278"))]
123mod tests {
124 use assert_matches2::assert_matches;
125 use ruma_common::canonical_json::assert_to_canonical_json_eq;
126 use serde_json::{from_value as from_json_value, json};
127
128 use super::{MediaPreviewConfigEventContent, UnstableMediaPreviewConfigEventContent};
129 use crate::{
130 AnyGlobalAccountDataEvent, GlobalAccountDataEvent,
131 media_preview_config::{InviteAvatars, MediaPreviews},
132 };
133
134 #[test]
135 fn deserialize() {
136 let raw_unstable_media_preview_config = json!({
137 "type": "io.element.msc4278.media_preview_config",
138 "content": {
139 "media_previews": "private",
140 "invite_avatars": "off",
141 },
142 });
143 let unstable_media_preview_config_data =
144 from_json_value::<AnyGlobalAccountDataEvent>(raw_unstable_media_preview_config)
145 .unwrap();
146 assert_matches!(
147 unstable_media_preview_config_data,
148 AnyGlobalAccountDataEvent::UnstableMediaPreviewConfig(unstable_media_preview_config)
149 );
150 assert_eq!(
151 unstable_media_preview_config.content.media_previews,
152 Some(MediaPreviews::Private)
153 );
154 assert_eq!(unstable_media_preview_config.content.invite_avatars, Some(InviteAvatars::Off));
155
156 let raw_media_preview_config = json!({
157 "type": "m.media_preview_config",
158 "content": {
159 "media_previews": "on",
160 "invite_avatars": "on",
161 },
162 });
163 let media_preview_config_data =
164 from_json_value::<AnyGlobalAccountDataEvent>(raw_media_preview_config).unwrap();
165 assert_matches!(
166 media_preview_config_data,
167 AnyGlobalAccountDataEvent::MediaPreviewConfig(media_preview_config)
168 );
169 assert_eq!(media_preview_config.content.media_previews, Some(MediaPreviews::On));
170 assert_eq!(media_preview_config.content.invite_avatars, Some(InviteAvatars::On));
171 }
172
173 #[test]
174 fn serialize() {
175 let unstable_media_preview_config = UnstableMediaPreviewConfigEventContent(
176 MediaPreviewConfigEventContent::new()
177 .media_previews(Some(MediaPreviews::Off))
178 .invite_avatars(Some(InviteAvatars::On)),
179 );
180 let unstable_media_preview_config_account_data =
181 GlobalAccountDataEvent { content: unstable_media_preview_config };
182 assert_to_canonical_json_eq!(
183 unstable_media_preview_config_account_data,
184 json!({
185 "type": "io.element.msc4278.media_preview_config",
186 "content": {
187 "media_previews": "off",
188 "invite_avatars": "on",
189 },
190 })
191 );
192
193 let media_preview_config = MediaPreviewConfigEventContent::new()
194 .media_previews(Some(MediaPreviews::On))
195 .invite_avatars(Some(InviteAvatars::Off));
196 let media_preview_config_account_data =
197 GlobalAccountDataEvent { content: media_preview_config };
198 assert_to_canonical_json_eq!(
199 media_preview_config_account_data,
200 json!({
201 "type": "m.media_preview_config",
202 "content": {
203 "media_previews": "on",
204 "invite_avatars": "off",
205 },
206 })
207 );
208 }
209}