Skip to main content

arminius_lib_roomservice_client/
roomserver_connection.rs

1// SPDX-FileCopyrightText: 2025 BWI GmbH
2//
3// SPDX-License-Identifier: Apache-2.0
4
5//! wrapper around `Client` to add roomserver-specific
6//! functionality
7use arminius_lib_component::ServerState;
8use arminius_lib_nats::{NatsClient, NatsError, SharedNatsClient};
9use axum::extract::FromRequestParts;
10use ruma::OwnedRoomId;
11
12use crate::{requests::APICall, roomserver_command_subject::RoomserverCommand};
13
14/// Wrapper around [`SharedNatsClient`] for roomserver-specific requests
15#[derive(Debug, Clone)]
16pub struct RoomServerConnection {
17	/// The NATS connection
18	nats: SharedNatsClient,
19}
20
21impl RoomServerConnection {
22	/// Create a new RoomServerConnection
23	#[must_use]
24	pub fn new(nats: &SharedNatsClient) -> Self {
25		Self { nats: nats.clone() }
26	}
27
28	/// Makes a request to the room server, and get the response
29	pub async fn make_roomserver_request<T: APICall>(
30		&self,
31		room_id: Option<OwnedRoomId>,
32		request: T::Request,
33	) -> Result<Result<T::Response, T::Error>, NatsError> {
34		let subject = RoomserverCommand { room_id, command: T::ENDPOINT.to_owned() };
35		let subscriber = self.nats.make_nats_request(subject, request).await?;
36		NatsClient::await_nats_response(subscriber).await
37	}
38
39	/// Makes a request to the room server, but do not await a response
40	pub async fn make_roomserver_request_ignoring_response<T: APICall>(
41		&self,
42		room_id: Option<OwnedRoomId>,
43		request: T::Request,
44	) -> Result<(), NatsError> {
45		let subject = RoomserverCommand { room_id, command: T::ENDPOINT.to_owned() };
46		self.nats.make_nats_request(subject, request).await?;
47		Ok(())
48	}
49}
50
51impl<S> FromRequestParts<S> for RoomServerConnection
52where
53	S: Send + Sync,
54	ServerState: axum::extract::FromRef<S>,
55{
56	type Rejection = ();
57
58	fn from_request_parts(
59		_: &mut axum::http::request::Parts,
60		state: &S,
61	) -> impl Future<Output = Result<Self, Self::Rejection>> + Send {
62		let server_state = <ServerState as axum::extract::FromRef<S>>::from_ref(state);
63		let room_server = RoomServerConnection::new(&server_state.nats_connection);
64		async move { Ok(room_server) }
65	}
66}