tuwunel_api_federation/
state.rs1use axum::extract::State;
2use futures::{StreamExt, future::join};
3use ruma::api::federation::event::get_room_state;
4use tuwunel_core::{
5 Result,
6 utils::stream::{BroadbandExt, IterStream},
7};
8
9use super::utils::{auth_chain_pdu, state_at_event, state_pdu, walk_state_auth_chain};
10use crate::Ruma;
11
12pub(crate) async fn get_room_state_route(
16 State(services): State<crate::State>,
17 body: Ruma<get_room_state::v1::Request>,
18) -> Result<get_room_state::v1::Response> {
19 let (room_version, state_ids) =
20 state_at_event(&services, body.origin(), &body.room_id, &body.event_id).await?;
21
22 let auth_chain = walk_state_auth_chain(
23 &services,
24 &body.room_id,
25 &room_version,
26 &state_ids,
27 &body.event_id,
28 )
29 .broad_filter_map(async |id| auth_chain_pdu(&services, &id, &room_version).await)
30 .collect();
31
32 let pdus = state_ids
33 .iter()
34 .stream()
35 .broad_filter_map(|id| state_pdu(&services, id, &room_version))
36 .collect();
37
38 let (auth_chain, pdus) = join(auth_chain, pdus).await;
39
40 Ok(get_room_state::v1::Response { auth_chain, pdus })
41}