ruma_client_api/backup/
get_backup_info.rs

1//! `GET /_matrix/client/*/room_keys/version/{version}`
2//!
3//! Get information about a specific backup.
4
5#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/112615
6pub mod v3 {
7    //! `/v3/` ([spec])
8    //!
9    //! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv3room_keysversionversion
10
11    use js_int::UInt;
12    use ruma_common::{
13        api::{request, response, Metadata},
14        metadata,
15        serde::Raw,
16    };
17    use serde::{ser, Deserialize, Deserializer, Serialize};
18    use serde_json::value::{to_raw_value as to_raw_json_value, RawValue as RawJsonValue};
19
20    use crate::backup::BackupAlgorithm;
21
22    const METADATA: Metadata = metadata! {
23        method: GET,
24        rate_limited: true,
25        authentication: AccessToken,
26        history: {
27            unstable => "/_matrix/client/unstable/room_keys/version/:version",
28            1.1 => "/_matrix/client/v3/room_keys/version/:version",
29        }
30    };
31
32    /// Request type for the `get_backup_info` endpoint.
33    #[request(error = crate::Error)]
34    pub struct Request {
35        /// The backup version to retrieve info from.
36        #[ruma_api(path)]
37        pub version: String,
38    }
39
40    /// Response type for the `get_backup_info` endpoint.
41    #[response(error = crate::Error)]
42    #[ruma_api(manual_body_serde)]
43    pub struct Response {
44        /// The algorithm used for storing backups.
45        pub algorithm: Raw<BackupAlgorithm>,
46
47        /// The number of keys stored in the backup.
48        pub count: UInt,
49
50        /// An opaque string representing stored keys in the backup.
51        ///
52        /// Clients can compare it with the etag value they received in the request of their last
53        /// key storage request.
54        pub etag: String,
55
56        /// The backup version.
57        pub version: String,
58    }
59
60    impl Request {
61        /// Creates a new `Request` with the given version.
62        pub fn new(version: String) -> Self {
63            Self { version }
64        }
65    }
66
67    impl Response {
68        /// Creates a new `Response` with the given algorithm, key count, etag and version.
69        pub fn new(
70            algorithm: Raw<BackupAlgorithm>,
71            count: UInt,
72            etag: String,
73            version: String,
74        ) -> Self {
75            Self { algorithm, count, etag, version }
76        }
77    }
78
79    #[derive(Deserialize)]
80    pub(in crate::backup) struct ResponseBodyRepr {
81        pub algorithm: Box<RawJsonValue>,
82        pub auth_data: Box<RawJsonValue>,
83        pub count: UInt,
84        pub etag: String,
85        pub version: String,
86    }
87
88    #[derive(Serialize)]
89    pub(in crate::backup) struct RefResponseBodyRepr<'a> {
90        pub algorithm: &'a RawJsonValue,
91        pub auth_data: &'a RawJsonValue,
92        pub count: UInt,
93        pub etag: &'a str,
94        pub version: &'a str,
95    }
96
97    #[derive(Deserialize, Serialize)]
98    pub(in crate::backup) struct AlgorithmWithData {
99        pub algorithm: Box<RawJsonValue>,
100        pub auth_data: Box<RawJsonValue>,
101    }
102
103    impl<'de> Deserialize<'de> for ResponseBody {
104        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
105        where
106            D: Deserializer<'de>,
107        {
108            let ResponseBodyRepr { algorithm, auth_data, count, etag, version } =
109                ResponseBodyRepr::deserialize(deserializer)?;
110
111            let algorithm = Raw::from_json(
112                to_raw_json_value(&AlgorithmWithData { algorithm, auth_data }).unwrap(),
113            );
114
115            Ok(Self { algorithm, count, etag, version })
116        }
117    }
118
119    impl Serialize for ResponseBody {
120        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
121        where
122            S: serde::Serializer,
123        {
124            let ResponseBody { algorithm, count, etag, version } = self;
125            let AlgorithmWithData { algorithm, auth_data } =
126                algorithm.deserialize_as().map_err(ser::Error::custom)?;
127
128            let repr = RefResponseBodyRepr {
129                algorithm: &algorithm,
130                auth_data: &auth_data,
131                count: *count,
132                etag,
133                version,
134            };
135
136            repr.serialize(serializer)
137        }
138    }
139}