pub mod v1 {
use ruma_common::{
OwnedRoomOrAliasId, OwnedServerName,
api::{auth_scheme::AccessTokenOptional, request},
metadata,
room::RoomSummary,
};
use ruma_events::room::member::MembershipState;
metadata! {
method: GET,
rate_limited: false,
authentication: AccessTokenOptional,
history: {
unstable => "/_matrix/client/unstable/im.nheko.summary/rooms/{room_id_or_alias}/summary",
1.15 => "/_matrix/client/v1/room_summary/{room_id_or_alias}",
}
}
#[request(error = crate::Error)]
pub struct Request {
#[ruma_api(path)]
pub room_id_or_alias: OwnedRoomOrAliasId,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
#[ruma_api(query)]
pub via: Vec<OwnedServerName>,
}
impl Request {
pub fn new(room_id_or_alias: OwnedRoomOrAliasId, via: Vec<OwnedServerName>) -> Self {
Self { room_id_or_alias, via }
}
}
#[derive(Debug, Clone)]
#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
pub struct Response {
pub summary: RoomSummary,
pub membership: Option<MembershipState>,
}
impl Response {
pub fn new(summary: RoomSummary) -> Self {
Self { summary, membership: None }
}
}
impl From<RoomSummary> for Response {
fn from(value: RoomSummary) -> Self {
Self::new(value)
}
}
#[cfg(feature = "server")]
impl ruma_common::api::OutgoingResponse for Response {
fn try_into_http_response<T: Default + bytes::BufMut>(
self,
) -> Result<http::Response<T>, ruma_common::api::error::IntoHttpError> {
#[derive(serde::Serialize)]
struct ResponseSerHelper {
#[serde(flatten)]
summary: RoomSummary,
#[serde(skip_serializing_if = "Option::is_none")]
membership: Option<MembershipState>,
}
let body = ResponseSerHelper { summary: self.summary, membership: self.membership };
http::Response::builder()
.header(http::header::CONTENT_TYPE, ruma_common::http_headers::APPLICATION_JSON)
.body(ruma_common::serde::json_to_buf(&body)?)
.map_err(Into::into)
}
}
#[cfg(feature = "client")]
impl ruma_common::api::IncomingResponse for Response {
type EndpointError = crate::Error;
fn try_from_http_response<T: AsRef<[u8]>>(
response: http::Response<T>,
) -> Result<Self, ruma_common::api::error::FromHttpResponseError<Self::EndpointError>>
{
use ruma_common::{api::EndpointError, serde::from_raw_json_value};
#[derive(serde::Deserialize)]
struct ResponseDeHelper {
membership: Option<MembershipState>,
}
if response.status().as_u16() >= 400 {
return Err(ruma_common::api::error::FromHttpResponseError::Server(
Self::EndpointError::from_http_response(response),
));
}
let raw_json = serde_json::from_slice::<Box<serde_json::value::RawValue>>(
response.body().as_ref(),
)?;
let summary = from_raw_json_value::<RoomSummary, serde_json::Error>(&raw_json)?;
let membership =
from_raw_json_value::<ResponseDeHelper, serde_json::Error>(&raw_json)?.membership;
Ok(Self { summary, membership })
}
}
}
#[cfg(all(test, feature = "client"))]
mod tests {
use ruma_common::api::IncomingResponse;
use ruma_events::room::member::MembershipState;
use serde_json::{json, to_vec as to_json_vec};
use super::v1::Response;
#[test]
fn deserialize_response() {
let body = json!({
"room_id": "!room:localhost",
"num_joined_members": 5,
"world_readable": false,
"guest_can_join": false,
"join_rule": "restricted",
"allowed_room_ids": ["!otherroom:localhost"],
"membership": "invite",
});
let response = http::Response::new(to_json_vec(&body).unwrap());
let response = Response::try_from_http_response(response).unwrap();
assert_eq!(response.summary.room_id, "!room:localhost");
assert_eq!(response.membership, Some(MembershipState::Invite));
}
}