Skip to main content

ably_chat/
occupancy.rs

1//! The occupancy handle and occupancy read operation (ADR-0010).
2
3use std::future::{Future, IntoFuture};
4use std::pin::Pin;
5
6use reqwest::Method;
7
8use crate::client::Client;
9use crate::dispatch::{decode_json, room_path};
10use crate::error::Result;
11use crate::types::{Occupancy, RoomName};
12
13/// Occupancy operations for a room.
14///
15/// Named `OccupancyHandle` to avoid clashing with the [`Occupancy`] data type.
16/// Cheap to `Clone` (`Arc`-backed via [`Client`]) and `Send + Sync`.
17///
18/// [`Occupancy`]: crate::types::Occupancy
19#[derive(Clone, Debug)]
20pub struct OccupancyHandle {
21    pub(crate) client: Client,
22    pub(crate) room: RoomName,
23}
24
25impl OccupancyHandle {
26    pub(crate) fn new(client: Client, room: RoomName) -> Self {
27        Self { client, room }
28    }
29
30    /// Fetches the current occupancy metrics for the room.
31    ///
32    /// `GET /chat/v4/rooms/{roomName}/occupancy`. Retry-safe.
33    pub fn get(&self) -> GetOccupancy {
34        GetOccupancy {
35            client: self.client.clone(),
36            room: self.room.clone(),
37        }
38    }
39}
40
41/// Builder for [`OccupancyHandle::get`]; `.await` it to fetch [`Occupancy`].
42#[derive(Clone, Debug)]
43pub struct GetOccupancy {
44    client: Client,
45    room: RoomName,
46}
47
48impl IntoFuture for GetOccupancy {
49    type Output = Result<Occupancy>;
50    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
51
52    fn into_future(self) -> Self::IntoFuture {
53        Box::pin(async move {
54            let resp = self
55                .client
56                .inner
57                .send(
58                    Method::GET,
59                    &room_path(self.room.as_str(), "/occupancy"),
60                    &[],
61                    None,
62                    false,
63                )
64                .await?;
65            decode_json(&resp.body)
66        })
67    }
68}