Skip to main content

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::{Metadata, path_builder::SinglePath, request};
8
9use crate::authenticated_media::{ContentMetadata, FileOrLocation, ResponseBody};
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_inner(
85        http_response: http::Response<&[u8]>,
86    ) -> Result<Self, ruma_common::api::error::DeserializationError> {
87        let ResponseBody { metadata, content, .. } =
88            ResponseBody::try_from_http_response(http_response)?;
89        Ok(Self { metadata, content })
90    }
91}
92
93#[cfg(feature = "server")]
94impl ruma_common::api::OutgoingResponse for Response {
95    type Body = ResponseBody;
96
97    fn try_into_http_response_inner(
98        self,
99    ) -> Result<http::Response<Self::Body>, ruma_common::api::error::IntoHttpError> {
100        ResponseBody::new(self.metadata, self.content).try_into_http_response()
101    }
102}
103
104impl From<super::v1::Response> for Response {
105    fn from(value: super::v1::Response) -> Self {
106        let super::v1::Response { metadata, content } = value;
107        Self { metadata, content }
108    }
109}
110
111impl From<Response> for super::v1::Response {
112    fn from(value: Response) -> Self {
113        let Response { metadata, content } = value;
114        Self { metadata, content }
115    }
116}