1use std::time::Duration;
18
19use ruma::{
20 assign,
21 events::{
22 room::{
23 message::{AudioInfo, FileInfo, FormattedBody, VideoInfo},
24 ImageInfo, ThumbnailInfo,
25 },
26 Mentions,
27 },
28 OwnedTransactionId, TransactionId, UInt,
29};
30
31#[derive(Debug, Clone, Default)]
33pub struct BaseImageInfo {
34 pub height: Option<UInt>,
36 pub width: Option<UInt>,
38 pub size: Option<UInt>,
40 pub blurhash: Option<String>,
42 pub is_animated: Option<bool>,
44}
45
46#[derive(Debug, Clone, Default)]
48pub struct BaseVideoInfo {
49 pub duration: Option<Duration>,
51 pub height: Option<UInt>,
53 pub width: Option<UInt>,
55 pub size: Option<UInt>,
57 pub blurhash: Option<String>,
59}
60
61#[derive(Debug, Clone, Default)]
63pub struct BaseAudioInfo {
64 pub duration: Option<Duration>,
66 pub size: Option<UInt>,
68}
69
70#[derive(Debug, Clone, Default)]
72pub struct BaseFileInfo {
73 pub size: Option<UInt>,
75}
76
77#[derive(Debug)]
79pub enum AttachmentInfo {
80 Image(BaseImageInfo),
82 Video(BaseVideoInfo),
84 Audio(BaseAudioInfo),
86 File(BaseFileInfo),
88 Voice {
90 audio_info: BaseAudioInfo,
92 waveform: Option<Vec<u16>>,
94 },
95}
96
97impl From<AttachmentInfo> for ImageInfo {
98 fn from(info: AttachmentInfo) -> Self {
99 match info {
100 AttachmentInfo::Image(info) => assign!(ImageInfo::new(), {
101 height: info.height,
102 width: info.width,
103 size: info.size,
104 blurhash: info.blurhash,
105 is_animated: info.is_animated,
106 }),
107 _ => ImageInfo::new(),
108 }
109 }
110}
111
112impl From<AttachmentInfo> for VideoInfo {
113 fn from(info: AttachmentInfo) -> Self {
114 match info {
115 AttachmentInfo::Video(info) => assign!(VideoInfo::new(), {
116 duration: info.duration,
117 height: info.height,
118 width: info.width,
119 size: info.size,
120 blurhash: info.blurhash,
121 }),
122 _ => VideoInfo::new(),
123 }
124 }
125}
126
127impl From<AttachmentInfo> for AudioInfo {
128 fn from(info: AttachmentInfo) -> Self {
129 match info {
130 AttachmentInfo::Audio(info) => assign!(AudioInfo::new(), {
131 duration: info.duration,
132 size: info.size,
133 }),
134 AttachmentInfo::Voice { audio_info, .. } => assign!(AudioInfo::new(), {
135 duration: audio_info.duration,
136 size: audio_info.size,
137 }),
138 _ => AudioInfo::new(),
139 }
140 }
141}
142
143impl From<AttachmentInfo> for FileInfo {
144 fn from(info: AttachmentInfo) -> Self {
145 match info {
146 AttachmentInfo::File(info) => assign!(FileInfo::new(), {
147 size: info.size,
148 }),
149 _ => FileInfo::new(),
150 }
151 }
152}
153
154#[derive(Debug)]
156pub struct Thumbnail {
157 pub data: Vec<u8>,
159 pub content_type: mime::Mime,
161 pub height: UInt,
163 pub width: UInt,
165 pub size: UInt,
167}
168
169impl Thumbnail {
170 pub fn into_parts(self) -> (Vec<u8>, mime::Mime, Box<ThumbnailInfo>) {
172 let thumbnail_info = assign!(ThumbnailInfo::new(), {
173 height: Some(self.height),
174 width: Some(self.width),
175 size: Some(self.size),
176 mimetype: Some(self.content_type.to_string())
177 });
178 (self.data, self.content_type, Box::new(thumbnail_info))
179 }
180}
181
182#[derive(Debug, Default)]
184pub struct AttachmentConfig {
185 pub(crate) txn_id: Option<OwnedTransactionId>,
186 pub(crate) info: Option<AttachmentInfo>,
187 pub(crate) thumbnail: Option<Thumbnail>,
188 pub(crate) caption: Option<String>,
189 pub(crate) formatted_caption: Option<FormattedBody>,
190 pub(crate) mentions: Option<Mentions>,
191}
192
193impl AttachmentConfig {
194 pub fn new() -> Self {
196 Self::default()
197 }
198
199 #[must_use]
206 pub fn thumbnail(mut self, thumbnail: Option<Thumbnail>) -> Self {
207 self.thumbnail = thumbnail;
208 self
209 }
210
211 #[must_use]
219 pub fn txn_id(mut self, txn_id: &TransactionId) -> Self {
220 self.txn_id = Some(txn_id.to_owned());
221 self
222 }
223
224 #[must_use]
231 pub fn info(mut self, info: AttachmentInfo) -> Self {
232 self.info = Some(info);
233 self
234 }
235
236 pub fn caption(mut self, caption: Option<String>) -> Self {
242 self.caption = caption;
243 self
244 }
245
246 pub fn formatted_caption(mut self, formatted_caption: Option<FormattedBody>) -> Self {
252 self.formatted_caption = formatted_caption;
253 self
254 }
255
256 pub fn mentions(mut self, mentions: Option<Mentions>) -> Self {
262 self.mentions = mentions;
263 self
264 }
265}