logo
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//! `GET /_matrix/media/*/thumbnail/{serverName}/{mediaId}`

pub mod v3 {
    //! `/v3/` ([spec])
    //!
    //! [spec]: https://spec.matrix.org/v1.2/client-server-api/#get_matrixmediav3thumbnailservernamemediaid

    use js_int::UInt;
    use ruma_common::{api::ruma_api, serde::StringEnum, IdParseError, MxcUri, ServerName};

    use crate::PrivOwnedStr;

    ruma_api! {
        metadata: {
            description: "Get a thumbnail of content from the media store.",
            method: GET,
            name: "get_content_thumbnail",
            r0_path: "/_matrix/media/r0/thumbnail/:server_name/:media_id",
            stable_path: "/_matrix/media/v3/thumbnail/:server_name/:media_id",
            rate_limited: true,
            authentication: None,
            added: 1.0,
        }

        request: {
            /// The media ID from the mxc:// URI (the path component).
            #[ruma_api(path)]
            pub media_id: &'a str,

            /// The server name from the mxc:// URI (the authoritory component).
            #[ruma_api(path)]
            pub server_name: &'a ServerName,

            /// The desired resizing method.
            #[ruma_api(query)]
            #[serde(skip_serializing_if = "Option::is_none")]
            pub method: Option<Method>,

            /// The *desired* width of the thumbnail.
            ///
            /// The actual thumbnail may not match the size specified.
            #[ruma_api(query)]
            pub width: UInt,

            /// The *desired* height of the thumbnail.
            ///
            /// The actual thumbnail may not match the size specified.
            #[ruma_api(query)]
            pub height: UInt,

            /// Whether to fetch media deemed remote.
            ///
            /// Used to prevent routing loops. Defaults to `true`.
            #[ruma_api(query)]
            #[serde(default = "ruma_common::serde::default_true", skip_serializing_if = "ruma_common::serde::is_true")]
            pub allow_remote: bool,

            /// How long to wait for the media to be uploaded
            ///
            /// This uses the unstable prefix in
            /// [MSC2246](https://github.com/matrix-org/matrix-spec-proposals/pull/2246)
            #[ruma_api(query)]
            #[cfg(feature = "unstable-msc2246")]
            #[serde(
                default,
                skip_serializing_if = "ruma_common::serde::is_default",
                rename = "fi.mau.msc2246.max_stall_ms",
                alias = "max_stall_ms"
            )]
            pub max_stall_ms: Option<UInt>,
        }

        response: {
            /// A thumbnail of the requested content.
            #[ruma_api(raw_body)]
            pub file: Vec<u8>,

            /// The content type of the thumbnail.
            #[ruma_api(header = CONTENT_TYPE)]
            pub content_type: Option<String>,
        }

        error: crate::Error
    }

    impl<'a> Request<'a> {
        /// Creates a new `Request` with the given media ID, server name, desired thumbnail width
        /// and desired thumbnail height.
        pub fn new(
            media_id: &'a str,
            server_name: &'a ServerName,
            width: UInt,
            height: UInt,
        ) -> Self {
            Self {
                media_id,
                server_name,
                method: None,
                width,
                height,
                allow_remote: true,
                #[cfg(feature = "unstable-msc2246")]
                max_stall_ms: None,
            }
        }

        /// Creates a new `Request` with the given url, desired thumbnail width and
        /// desired thumbnail height.
        pub fn from_url(url: &'a MxcUri, width: UInt, height: UInt) -> Result<Self, IdParseError> {
            let (server_name, media_id) = url.parts()?;

            Ok(Self::new(media_id, server_name, width, height))
        }
    }

    impl Response {
        /// Creates a new `Response` with the given thumbnail.
        pub fn new(file: Vec<u8>) -> Self {
            Self { file, content_type: None }
        }
    }

    /// The desired resizing method.
    #[doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/doc/string_enum.md"))]
    #[derive(Clone, Debug, StringEnum)]
    #[ruma_enum(rename_all = "snake_case")]
    #[non_exhaustive]
    pub enum Method {
        /// Crop the original to produce the requested image dimensions.
        Crop,

        /// Maintain the original aspect ratio of the source image.
        Scale,

        #[doc(hidden)]
        _Custom(PrivOwnedStr),
    }
}