twilight_model/channel/
attachment.rs

1use super::AttachmentFlags;
2use crate::{
3    id::{marker::AttachmentMarker, Id},
4    util::is_false,
5};
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
9pub struct Attachment {
10    /// Attachment's [media type].
11    ///
12    /// [media type]: https://en.wikipedia.org/wiki/Media_type
13    pub content_type: Option<String>,
14    /// Whether this attachment is ephemeral.
15    ///
16    /// Ephemeral attachments will automatically be removed after a set period
17    /// of time. Ephemeral attachments on messages are guaranteed to be
18    /// available as long as the message itself exists.
19    #[serde(default, skip_serializing_if = "is_false")]
20    pub ephemeral: bool,
21    /// Duration of the audio file (currently for voice messages).
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub duration_secs: Option<f64>,
24    pub filename: String,
25    // Flags for this attachment.
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub flags: Option<AttachmentFlags>,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub description: Option<String>,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub height: Option<u64>,
32    pub id: Id<AttachmentMarker>,
33    pub proxy_url: String,
34    pub size: u64,
35    /// The title of the file.
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub title: Option<String>,
38    pub url: String,
39    /// Base64 encoded bytearray representing a sampled waveform (currently for voice messages).
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub waveform: Option<String>,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub width: Option<u64>,
44}
45
46#[cfg(test)]
47mod tests {
48    use super::Attachment;
49    use crate::{channel::AttachmentFlags, id::Id};
50    use serde::{Deserialize, Serialize};
51    use serde_test::Token;
52    use static_assertions::{assert_fields, assert_impl_all};
53    use std::fmt::Debug;
54
55    assert_fields!(
56        Attachment: content_type,
57        ephemeral,
58        filename,
59        height,
60        id,
61        proxy_url,
62        size,
63        url,
64        width
65    );
66
67    assert_impl_all!(
68        Attachment: Clone,
69        Debug,
70        Deserialize<'static>,
71        PartialEq,
72        Serialize
73    );
74
75    #[test]
76    fn attachment() {
77        let value = Attachment {
78            content_type: Some("image/png".to_owned()),
79            ephemeral: false,
80            filename: "a.png".to_owned(),
81            flags: Some(AttachmentFlags::IS_REMIX),
82            description: Some("a image".to_owned()),
83            duration_secs: Some(3.2),
84            height: Some(184),
85            id: Id::new(700_000_000_000_000_000),
86            proxy_url: "https://cdn.example.com/1.png".to_owned(),
87            size: 13_593,
88            title: Some("a title".to_owned()),
89            url: "https://example.com/1.png".to_owned(),
90            waveform: Some(String::from("waveform")),
91            width: Some(184),
92        };
93
94        serde_test::assert_tokens(
95            &value,
96            &[
97                Token::Struct {
98                    name: "Attachment",
99                    len: 13,
100                },
101                Token::Str("content_type"),
102                Token::Some,
103                Token::Str("image/png"),
104                Token::Str("duration_secs"),
105                Token::Some,
106                Token::F64(3.2),
107                Token::Str("filename"),
108                Token::Str("a.png"),
109                Token::Str("flags"),
110                Token::Some,
111                Token::U64(4),
112                Token::Str("description"),
113                Token::Some,
114                Token::Str("a image"),
115                Token::Str("height"),
116                Token::Some,
117                Token::U64(184),
118                Token::Str("id"),
119                Token::NewtypeStruct { name: "Id" },
120                Token::Str("700000000000000000"),
121                Token::Str("proxy_url"),
122                Token::Str("https://cdn.example.com/1.png"),
123                Token::Str("size"),
124                Token::U64(13_593),
125                Token::Str("title"),
126                Token::Some,
127                Token::Str("a title"),
128                Token::Str("url"),
129                Token::Str("https://example.com/1.png"),
130                Token::Str("waveform"),
131                Token::Some,
132                Token::Str("waveform"),
133                Token::Str("width"),
134                Token::Some,
135                Token::U64(184),
136                Token::StructEnd,
137            ],
138        );
139    }
140}