ruma_events/
media_preview_config.rs1use ruma_common::serde::JsonCastable;
6use ruma_macros::StringEnum;
7use serde::{Deserialize, Serialize};
8
9use crate::{macros::EventContent, PrivOwnedStr};
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, PartialEq, Eq, PartialOrd, Ord, 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, PartialEq, Eq, PartialOrd, Ord, 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 serde_json::{from_value as from_json_value, json, to_value as to_json_value};
126
127 use super::{MediaPreviewConfigEventContent, UnstableMediaPreviewConfigEventContent};
128 use crate::{
129 media_preview_config::{InviteAvatars, MediaPreviews},
130 AnyGlobalAccountDataEvent, GlobalAccountDataEvent,
131 };
132
133 #[test]
134 fn deserialize() {
135 let raw_unstable_media_preview_config = json!({
136 "type": "io.element.msc4278.media_preview_config",
137 "content": {
138 "media_previews": "private",
139 "invite_avatars": "off",
140 },
141 });
142 let unstable_media_preview_config_data =
143 from_json_value::<AnyGlobalAccountDataEvent>(raw_unstable_media_preview_config)
144 .unwrap();
145 assert_matches!(
146 unstable_media_preview_config_data,
147 AnyGlobalAccountDataEvent::UnstableMediaPreviewConfig(unstable_media_preview_config)
148 );
149 assert_eq!(
150 unstable_media_preview_config.content.media_previews,
151 Some(MediaPreviews::Private)
152 );
153 assert_eq!(unstable_media_preview_config.content.invite_avatars, Some(InviteAvatars::Off));
154
155 let raw_media_preview_config = json!({
156 "type": "m.media_preview_config",
157 "content": {
158 "media_previews": "on",
159 "invite_avatars": "on",
160 },
161 });
162 let media_preview_config_data =
163 from_json_value::<AnyGlobalAccountDataEvent>(raw_media_preview_config).unwrap();
164 assert_matches!(
165 media_preview_config_data,
166 AnyGlobalAccountDataEvent::MediaPreviewConfig(media_preview_config)
167 );
168 assert_eq!(media_preview_config.content.media_previews, Some(MediaPreviews::On));
169 assert_eq!(media_preview_config.content.invite_avatars, Some(InviteAvatars::On));
170 }
171
172 #[test]
173 fn serialize() {
174 let unstable_media_preview_config = UnstableMediaPreviewConfigEventContent(
175 MediaPreviewConfigEventContent::new()
176 .media_previews(Some(MediaPreviews::Off))
177 .invite_avatars(Some(InviteAvatars::On)),
178 );
179 let unstable_media_preview_config_account_data =
180 GlobalAccountDataEvent { content: unstable_media_preview_config };
181 assert_eq!(
182 to_json_value(unstable_media_preview_config_account_data).unwrap(),
183 json!({
184 "type": "io.element.msc4278.media_preview_config",
185 "content": {
186 "media_previews": "off",
187 "invite_avatars": "on",
188 },
189 })
190 );
191
192 let media_preview_config = MediaPreviewConfigEventContent::new()
193 .media_previews(Some(MediaPreviews::On))
194 .invite_avatars(Some(InviteAvatars::Off));
195 let media_preview_config_account_data =
196 GlobalAccountDataEvent { content: media_preview_config };
197 assert_eq!(
198 to_json_value(media_preview_config_account_data).unwrap(),
199 json!({
200 "type": "m.media_preview_config",
201 "content": {
202 "media_previews": "on",
203 "invite_avatars": "off",
204 },
205 })
206 );
207 }
208}