ruma_federation_api/authenticated_media/get_content/
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 ruma_common::api::{path_builder::SinglePath, request, Metadata};
8
9use crate::authenticated_media::{ContentMetadata, FileOrLocation};
10
11/// Request type for the `get_content` endpoint.
12#[request]
13pub struct Request {
14    /// The media ID from the `mxc://` URI (the path component).
15    #[ruma_api(path)]
16    pub media_id: String,
17
18    /// The maximum duration that the client is willing to wait to start receiving data, in the
19    /// case that the content has not yet been uploaded.
20    ///
21    /// The default value is 20 seconds.
22    #[ruma_api(query)]
23    #[serde(
24        with = "ruma_common::serde::duration::ms",
25        default = "ruma_common::media::default_download_timeout",
26        skip_serializing_if = "ruma_common::media::is_default_download_timeout"
27    )]
28    pub timeout_ms: Duration,
29}
30
31impl Request {
32    /// Creates a new `Request` with the given media ID.
33    pub fn new(media_id: String) -> Self {
34        Self { media_id, timeout_ms: ruma_common::media::default_download_timeout() }
35    }
36}
37
38impl Metadata for Request {
39    const METHOD: http::Method = super::v1::Request::METHOD;
40    const RATE_LIMITED: bool = super::v1::Request::RATE_LIMITED;
41    type Authentication = <super::v1::Request as Metadata>::Authentication;
42    type PathBuilder = <super::v1::Request as Metadata>::PathBuilder;
43    const PATH_BUILDER: Self::PathBuilder = SinglePath::new(
44        "/_matrix/federation/unstable/org.matrix.msc3916.v2/media/download/{media_id}",
45    );
46}
47
48impl From<super::v1::Request> for Request {
49    fn from(value: super::v1::Request) -> Self {
50        let super::v1::Request { media_id, timeout_ms } = value;
51        Self { media_id, timeout_ms }
52    }
53}
54
55impl From<Request> for super::v1::Request {
56    fn from(value: Request) -> Self {
57        let Request { media_id, timeout_ms } = value;
58        Self { media_id, timeout_ms }
59    }
60}
61
62/// Response type for the `get_content` endpoint.
63#[derive(Debug, Clone)]
64#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
65pub struct Response {
66    /// The metadata of the media.
67    pub metadata: ContentMetadata,
68
69    /// The content of the media.
70    pub content: FileOrLocation,
71}
72
73impl Response {
74    /// Creates a new `Response` with the given metadata and content.
75    pub fn new(metadata: ContentMetadata, content: FileOrLocation) -> Self {
76        Self { metadata, content }
77    }
78}
79
80#[cfg(feature = "client")]
81impl ruma_common::api::IncomingResponse for Response {
82    type EndpointError = <super::v1::Response as ruma_common::api::IncomingResponse>::EndpointError;
83
84    fn try_from_http_response<T: AsRef<[u8]>>(
85        http_response: http::Response<T>,
86    ) -> Result<Self, ruma_common::api::error::FromHttpResponseError<Self::EndpointError>> {
87        // Reuse the custom deserialization.
88        Ok(super::v1::Response::try_from_http_response(http_response)?.into())
89    }
90}
91
92#[cfg(feature = "server")]
93impl ruma_common::api::OutgoingResponse for Response {
94    fn try_into_http_response<T: Default + bytes::BufMut>(
95        self,
96    ) -> Result<http::Response<T>, ruma_common::api::error::IntoHttpError> {
97        // Reuse the custom serialization.
98        super::v1::Response::from(self).try_into_http_response()
99    }
100}
101
102impl From<super::v1::Response> for Response {
103    fn from(value: super::v1::Response) -> Self {
104        let super::v1::Response { metadata, content } = value;
105        Self { metadata, content }
106    }
107}
108
109impl From<Response> for super::v1::Response {
110    fn from(value: Response) -> Self {
111        let Response { metadata, content } = value;
112        Self { metadata, content }
113    }
114}