ruma_client_api/room/
get_summary.rs1pub mod v1 {
6 use ruma_common::{
11 api::request, metadata, room::RoomSummary, OwnedRoomOrAliasId, OwnedServerName,
12 };
13 use ruma_events::room::member::MembershipState;
14
15 metadata! {
16 method: GET,
17 rate_limited: false,
18 authentication: AccessTokenOptional,
19 history: {
20 unstable => "/_matrix/client/unstable/im.nheko.summary/rooms/{room_id_or_alias}/summary",
21 1.15 => "/_matrix/client/v1/room_summary/{room_id_or_alias}",
22 }
23 }
24
25 #[request(error = crate::Error)]
27 pub struct Request {
28 #[ruma_api(path)]
30 pub room_id_or_alias: OwnedRoomOrAliasId,
31
32 #[serde(default, skip_serializing_if = "Vec::is_empty")]
36 #[ruma_api(query)]
37 pub via: Vec<OwnedServerName>,
38 }
39
40 impl Request {
41 pub fn new(room_id_or_alias: OwnedRoomOrAliasId, via: Vec<OwnedServerName>) -> Self {
43 Self { room_id_or_alias, via }
44 }
45 }
46
47 #[derive(Debug, Clone)]
49 #[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
50 pub struct Response {
51 pub summary: RoomSummary,
53
54 pub membership: Option<MembershipState>,
60 }
61
62 impl Response {
63 pub fn new(summary: RoomSummary) -> Self {
65 Self { summary, membership: None }
66 }
67 }
68
69 impl From<RoomSummary> for Response {
70 fn from(value: RoomSummary) -> Self {
71 Self::new(value)
72 }
73 }
74
75 #[cfg(feature = "server")]
76 impl ruma_common::api::OutgoingResponse for Response {
77 fn try_into_http_response<T: Default + bytes::BufMut>(
78 self,
79 ) -> Result<http::Response<T>, ruma_common::api::error::IntoHttpError> {
80 #[derive(serde::Serialize)]
81 struct ResponseSerHelper {
82 #[serde(flatten)]
83 summary: RoomSummary,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 membership: Option<MembershipState>,
86 }
87
88 let body = ResponseSerHelper { summary: self.summary, membership: self.membership };
89
90 http::Response::builder()
91 .header(http::header::CONTENT_TYPE, "application/json")
92 .body(ruma_common::serde::json_to_buf(&body)?)
93 .map_err(Into::into)
94 }
95 }
96
97 #[cfg(feature = "client")]
98 impl ruma_common::api::IncomingResponse for Response {
99 type EndpointError = crate::Error;
100
101 fn try_from_http_response<T: AsRef<[u8]>>(
102 response: http::Response<T>,
103 ) -> Result<Self, ruma_common::api::error::FromHttpResponseError<Self::EndpointError>>
104 {
105 use ruma_common::{api::EndpointError, serde::from_raw_json_value};
106
107 #[derive(serde::Deserialize)]
108 struct ResponseDeHelper {
109 membership: Option<MembershipState>,
110 }
111
112 if response.status().as_u16() >= 400 {
113 return Err(ruma_common::api::error::FromHttpResponseError::Server(
114 Self::EndpointError::from_http_response(response),
115 ));
116 }
117
118 let raw_json = serde_json::from_slice::<Box<serde_json::value::RawValue>>(
119 response.body().as_ref(),
120 )?;
121 let summary = from_raw_json_value::<RoomSummary, serde_json::Error>(&raw_json)?;
122 let membership =
123 from_raw_json_value::<ResponseDeHelper, serde_json::Error>(&raw_json)?.membership;
124
125 Ok(Self { summary, membership })
126 }
127 }
128}
129
130#[cfg(all(test, feature = "client"))]
131mod tests {
132 use ruma_common::api::IncomingResponse;
133 use ruma_events::room::member::MembershipState;
134 use serde_json::{json, to_vec as to_json_vec};
135
136 use super::v1::Response;
137
138 #[test]
139 fn deserialize_response() {
140 let body = json!({
141 "room_id": "!room:localhost",
142 "num_joined_members": 5,
143 "world_readable": false,
144 "guest_can_join": false,
145 "join_rule": "restricted",
146 "allowed_room_ids": ["!otherroom:localhost"],
147 "membership": "invite",
148 });
149 let response = http::Response::new(to_json_vec(&body).unwrap());
150
151 let response = Response::try_from_http_response(response).unwrap();
152 assert_eq!(response.summary.room_id, "!room:localhost");
153 assert_eq!(response.membership, Some(MembershipState::Invite));
154 }
155}