ruma_client_api/room/
get_summary.rs1pub mod v1 {
6 use ruma_common::{
11 api::{request, Metadata},
12 metadata,
13 room::RoomSummary,
14 OwnedRoomOrAliasId, OwnedServerName,
15 };
16 use ruma_events::room::member::MembershipState;
17
18 const METADATA: Metadata = 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(error = crate::Error)]
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 #[cfg(feature = "server")]
79 impl ruma_common::api::OutgoingResponse for Response {
80 fn try_into_http_response<T: Default + bytes::BufMut>(
81 self,
82 ) -> Result<http::Response<T>, ruma_common::api::error::IntoHttpError> {
83 #[derive(serde::Serialize)]
84 struct ResponseSerHelper {
85 #[serde(flatten)]
86 summary: RoomSummary,
87 #[serde(skip_serializing_if = "Option::is_none")]
88 membership: Option<MembershipState>,
89 }
90
91 let body = ResponseSerHelper { summary: self.summary, membership: self.membership };
92
93 http::Response::builder()
94 .header(http::header::CONTENT_TYPE, "application/json")
95 .body(ruma_common::serde::json_to_buf(&body)?)
96 .map_err(Into::into)
97 }
98 }
99
100 #[cfg(feature = "client")]
101 impl ruma_common::api::IncomingResponse for Response {
102 type EndpointError = crate::Error;
103
104 fn try_from_http_response<T: AsRef<[u8]>>(
105 response: http::Response<T>,
106 ) -> Result<Self, ruma_common::api::error::FromHttpResponseError<Self::EndpointError>>
107 {
108 use ruma_common::{api::EndpointError, serde::from_raw_json_value};
109
110 #[derive(serde::Deserialize)]
111 struct ResponseDeHelper {
112 membership: Option<MembershipState>,
113 }
114
115 if response.status().as_u16() >= 400 {
116 return Err(ruma_common::api::error::FromHttpResponseError::Server(
117 Self::EndpointError::from_http_response(response),
118 ));
119 }
120
121 let raw_json = serde_json::from_slice::<Box<serde_json::value::RawValue>>(
122 response.body().as_ref(),
123 )?;
124 let summary = from_raw_json_value::<RoomSummary, serde_json::Error>(&raw_json)?;
125 let membership =
126 from_raw_json_value::<ResponseDeHelper, serde_json::Error>(&raw_json)?.membership;
127
128 Ok(Self { summary, membership })
129 }
130 }
131}
132
133#[cfg(all(test, feature = "client"))]
134mod tests {
135 use ruma_common::api::IncomingResponse;
136 use ruma_events::room::member::MembershipState;
137 use serde_json::{json, to_vec as to_json_vec};
138
139 use super::v1::Response;
140
141 #[test]
142 fn deserialize_response() {
143 let body = json!({
144 "room_id": "!room:localhost",
145 "num_joined_members": 5,
146 "world_readable": false,
147 "guest_can_join": false,
148 "join_rule": "restricted",
149 "allowed_room_ids": ["!otherroom:localhost"],
150 "membership": "invite",
151 });
152 let response = http::Response::new(to_json_vec(&body).unwrap());
153
154 let response = Response::try_from_http_response(response).unwrap();
155 assert_eq!(response.summary.room_id, "!room:localhost");
156 assert_eq!(response.membership, Some(MembershipState::Invite));
157 }
158}