1
0
Fork 0
mirror of https://gitlab.com/famedly/conduit.git synced 2025-08-16 18:01:35 +00:00
conduit/src/api/client_server/space.rs

57 lines
1.8 KiB
Rust
Raw Normal View History

use std::str::FromStr;
use crate::{service::rooms::spaces::PagnationToken, services, Error, Result, Ruma};
use ruma::{
api::client::{error::ErrorKind, space::get_hierarchy},
UInt,
};
2023-07-02 16:06:54 +02:00
/// # `GET /_matrix/client/v1/rooms/{room_id}/hierarchy``
///
/// Paginates over the space tree in a depth-first manner to locate child rooms of a given space.
pub async fn get_hierarchy_route(
body: Ruma<get_hierarchy::v1::Request>,
) -> Result<get_hierarchy::v1::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let limit = body
.limit
.unwrap_or(UInt::from(10_u32))
.min(UInt::from(100_u32));
let max_depth = body
.max_depth
.unwrap_or(UInt::from(3_u32))
.min(UInt::from(10_u32));
let key = body
2023-07-02 16:06:54 +02:00
.from
.as_ref()
.and_then(|s| PagnationToken::from_str(s).ok());
2023-07-02 16:06:54 +02:00
// Should prevent unexpected behaviour in (bad) clients
if let Some(token) = &key {
if token.suggested_only != body.suggested_only || token.max_depth != max_depth {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"suggested_only and max_depth cannot change on paginated requests",
));
}
}
2023-07-02 16:06:54 +02:00
services()
.rooms
.spaces
.get_client_hierarchy(
2023-07-02 16:06:54 +02:00
sender_user,
&body.room_id,
usize::try_from(limit)
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Limit is too great"))?,
key.map_or(vec![], |token| token.short_room_ids),
usize::try_from(max_depth).map_err(|_| {
Error::BadRequest(ErrorKind::InvalidParam, "Max depth is too great")
})?,
2023-07-02 16:06:54 +02:00
body.suggested_only,
)
.await
}