ruma_federation_api/authenticated_media/get_content_thumbnail/
v1.rs

1//! `/v1/` ([spec])
2//!
3//! [spec]: https://spec.matrix.org/latest/server-server-api/#get_matrixfederationv1mediathumbnailmediaid
4
5use std::time::Duration;
6
7use js_int::UInt;
8use ruma_common::{api::request, media::Method, metadata};
9
10use crate::{
11    authenticated_media::{ContentMetadata, FileOrLocation},
12    authentication::ServerSignatures,
13};
14
15metadata! {
16    method: GET,
17    rate_limited: true,
18    authentication: ServerSignatures,
19    path: "/_matrix/federation/v1/media/thumbnail/{media_id}",
20}
21
22/// Request type for the `get_content_thumbnail` endpoint.
23#[request]
24pub struct Request {
25    /// The media ID from the `mxc://` URI (the path component).
26    #[ruma_api(path)]
27    pub media_id: String,
28
29    /// The desired resizing method.
30    #[ruma_api(query)]
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub method: Option<Method>,
33
34    /// The *desired* width of the thumbnail.
35    ///
36    /// The actual thumbnail may not match the size specified.
37    #[ruma_api(query)]
38    pub width: UInt,
39
40    /// The *desired* height of the thumbnail.
41    ///
42    /// The actual thumbnail may not match the size specified.
43    #[ruma_api(query)]
44    pub height: UInt,
45
46    /// The maximum duration that the client is willing to wait to start receiving data, in the
47    /// case that the content has not yet been uploaded.
48    ///
49    /// The default value is 20 seconds.
50    #[ruma_api(query)]
51    #[serde(
52        with = "ruma_common::serde::duration::ms",
53        default = "ruma_common::media::default_download_timeout",
54        skip_serializing_if = "ruma_common::media::is_default_download_timeout"
55    )]
56    pub timeout_ms: Duration,
57
58    /// Whether the server should return an animated thumbnail.
59    ///
60    /// When `Some(true)`, the server should return an animated thumbnail if possible and
61    /// supported. When `Some(false)`, the server must not return an animated
62    /// thumbnail. When `None`, the server should not return an animated thumbnail.
63    #[ruma_api(query)]
64    #[serde(skip_serializing_if = "Option::is_none")]
65    pub animated: Option<bool>,
66}
67
68impl Request {
69    /// Creates a new `Request` with the given media ID, desired thumbnail width
70    /// and desired thumbnail height.
71    pub fn new(media_id: String, width: UInt, height: UInt) -> Self {
72        Self {
73            media_id,
74            method: None,
75            width,
76            height,
77            timeout_ms: ruma_common::media::default_download_timeout(),
78            animated: None,
79        }
80    }
81}
82
83/// Response type for the `get_content_thumbnail` endpoint.
84#[derive(Debug, Clone)]
85#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
86pub struct Response {
87    /// The metadata of the thumbnail.
88    pub metadata: ContentMetadata,
89
90    /// The content of the thumbnail.
91    pub content: FileOrLocation,
92}
93
94impl Response {
95    /// Creates a new `Response` with the given metadata and content.
96    pub fn new(metadata: ContentMetadata, content: FileOrLocation) -> Self {
97        Self { metadata, content }
98    }
99}
100
101#[cfg(feature = "client")]
102impl ruma_common::api::IncomingResponse for Response {
103    type EndpointError = ruma_common::api::error::MatrixError;
104
105    fn try_from_http_response<T: AsRef<[u8]>>(
106        http_response: http::Response<T>,
107    ) -> Result<Self, ruma_common::api::error::FromHttpResponseError<Self::EndpointError>> {
108        use ruma_common::api::EndpointError;
109
110        if http_response.status().as_u16() < 400 {
111            let (metadata, content) =
112                crate::authenticated_media::try_from_multipart_mixed_response(http_response)?;
113            Ok(Self { metadata, content })
114        } else {
115            Err(ruma_common::api::error::FromHttpResponseError::Server(
116                ruma_common::api::error::MatrixError::from_http_response(http_response),
117            ))
118        }
119    }
120}
121
122#[cfg(feature = "server")]
123impl ruma_common::api::OutgoingResponse for Response {
124    fn try_into_http_response<T: Default + bytes::BufMut>(
125        self,
126    ) -> Result<http::Response<T>, ruma_common::api::error::IntoHttpError> {
127        crate::authenticated_media::try_into_multipart_mixed_response(&self.metadata, &self.content)
128    }
129}