ruma_federation_api/authenticated_media/get_content_thumbnail/
unstable.rs

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