tuwunel_api/client/membership/
forget.rs1use axum::extract::State;
2use futures::{TryFutureExt, pin_mut};
3use ruma::{api::client::membership::forget_room, events::room::member::MembershipState};
4use tuwunel_core::{
5 Err, Result, is_matching,
6 utils::{FutureBoolExt, TryFutureExtExt},
7};
8
9use crate::Ruma;
10
11pub(crate) async fn forget_room_route(
22 State(services): State<crate::State>,
23 body: Ruma<forget_room::v3::Request>,
24) -> Result<forget_room::v3::Response> {
25 let user_id = body.sender_user();
26 let room_id = &body.room_id;
27
28 let joined = services.state_cache.is_joined(user_id, room_id);
29 let knocked = services.state_cache.is_knocked(user_id, room_id);
30 let invited = services.state_cache.is_invited(user_id, room_id);
31
32 pin_mut!(joined, knocked, invited);
33 if joined.or(knocked).or(invited).await {
34 return Err!(Request(Unknown("You must leave the room before forgetting it")));
35 }
36
37 let left = services.state_cache.is_left(user_id, room_id);
38 let left_or_banned = services
39 .state_accessor
40 .get_member(room_id, user_id)
41 .map_ok(|member| member.membership)
42 .map_ok_or(false, is_matching!(MembershipState::Leave | MembershipState::Ban));
43
44 pin_mut!(left, left_or_banned);
45 if left.or(left_or_banned).await {
46 services.state_cache.forget(room_id, user_id);
47 }
48
49 Ok(forget_room::v3::Response::new())
50}