ruma_client_api/room/
get_summary.rs1pub mod v1 {
6 use ruma_common::{
11 OwnedRoomOrAliasId, OwnedServerName,
12 api::{auth_scheme::AccessTokenOptional, request},
13 metadata,
14 room::RoomSummary,
15 };
16 use ruma_events::room::member::MembershipState;
17
18 metadata! {
19 method: GET,
20 rate_limited: false,
21 authentication: AccessTokenOptional,
22 history: {
23 unstable => "/_matrix/client/unstable/im.nheko.summary/rooms/{room_id_or_alias}/summary",
24 1.15 => "/_matrix/client/v1/room_summary/{room_id_or_alias}",
25 }
26 }
27
28 #[request]
30 pub struct Request {
31 #[ruma_api(path)]
33 pub room_id_or_alias: OwnedRoomOrAliasId,
34
35 #[serde(default, skip_serializing_if = "Vec::is_empty")]
39 #[ruma_api(query)]
40 pub via: Vec<OwnedServerName>,
41 }
42
43 impl Request {
44 pub fn new(room_id_or_alias: OwnedRoomOrAliasId, via: Vec<OwnedServerName>) -> Self {
46 Self { room_id_or_alias, via }
47 }
48 }
49
50 #[derive(Debug, Clone)]
52 #[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
53 pub struct Response {
54 pub summary: RoomSummary,
56
57 pub membership: Option<MembershipState>,
63 }
64
65 impl Response {
66 pub fn new(summary: RoomSummary) -> Self {
68 Self { summary, membership: None }
69 }
70 }
71
72 impl From<RoomSummary> for Response {
73 fn from(value: RoomSummary) -> Self {
74 Self::new(value)
75 }
76 }
77
78 #[doc(hidden)]
79 #[derive(ruma_common::serde::_FakeDeriveSerde)]
80 #[cfg_attr(feature = "server", derive(serde::Serialize, ruma_common::api::OutgoingBodyJson))]
81 pub struct ResponseBody {
82 #[serde(flatten)]
83 summary: RoomSummary,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 membership: Option<MembershipState>,
86 }
87
88 #[cfg(feature = "client")]
89 impl<'de> serde::Deserialize<'de> for ResponseBody {
90 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91 where
92 D: serde::Deserializer<'de>,
93 {
94 use ruma_common::serde::from_raw_json_value;
95 use serde_json::value::RawValue as RawJsonValue;
96
97 #[derive(serde::Deserialize)]
98 struct ResponseBodyDeHelper {
99 membership: Option<MembershipState>,
100 }
101
102 let json = Box::<RawJsonValue>::deserialize(deserializer)?;
103 let summary = from_raw_json_value(&json)?;
104 let membership = from_raw_json_value::<ResponseBodyDeHelper, _>(&json)?.membership;
105
106 Ok(Self { membership, summary })
107 }
108 }
109
110 #[cfg(feature = "server")]
111 impl ruma_common::api::OutgoingResponse for Response {
112 type Body = ResponseBody;
113
114 fn try_into_http_response_inner(
115 self,
116 ) -> Result<http::Response<Self::Body>, ruma_common::api::error::IntoHttpError> {
117 let Self { summary, membership } = self;
118
119 http::Response::builder()
120 .header(http::header::CONTENT_TYPE, ruma_common::http_headers::APPLICATION_JSON)
121 .body(ResponseBody { summary, membership })
122 .map_err(Into::into)
123 }
124 }
125
126 #[cfg(feature = "client")]
127 impl ruma_common::api::IncomingResponse for Response {
128 type EndpointError = ruma_common::api::error::Error;
129
130 fn try_from_http_response_inner(
131 response: http::Response<&[u8]>,
132 ) -> Result<Self, ruma_common::api::error::DeserializationError> {
133 let ResponseBody { summary, membership } = serde_json::from_slice(response.body())?;
134 Ok(Self { summary, membership })
135 }
136 }
137}
138
139#[cfg(all(test, feature = "client"))]
140mod tests {
141 use ruma_common::api::IncomingResponseExt as _;
142 use ruma_events::room::member::MembershipState;
143 use serde_json::json;
144
145 use super::v1::Response;
146
147 #[test]
148 fn deserialize_response() {
149 let body = json!({
150 "room_id": "!room:localhost",
151 "num_joined_members": 5,
152 "world_readable": false,
153 "guest_can_join": false,
154 "join_rule": "restricted",
155 "allowed_room_ids": ["!otherroom:localhost"],
156 "membership": "invite",
157 })
158 .to_string();
159 let response = http::Response::new(body.as_bytes());
160 let response = Response::try_from_http_response(response).unwrap();
161
162 assert_eq!(response.summary.room_id, "!room:localhost");
163 assert_eq!(response.membership, Some(MembershipState::Invite));
164 }
165}