use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::wire::ClientPresence;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify))]
#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
pub struct PresenceTracker {
clients: HashMap<String, ClientPresence>,
}
impl PresenceTracker {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn upsert(&mut self, presence: ClientPresence) {
self.clients.insert(presence.client_id.clone(), presence);
}
pub fn remove(&mut self, client_id: &str) -> Option<ClientPresence> {
self.clients.remove(client_id)
}
#[must_use]
pub fn get(&self, client_id: &str) -> Option<&ClientPresence> {
self.clients.get(client_id)
}
#[must_use]
pub fn get_mut(&mut self, client_id: &str) -> Option<&mut ClientPresence> {
self.clients.get_mut(client_id)
}
#[must_use]
pub fn contains(&self, client_id: &str) -> bool {
self.clients.contains_key(client_id)
}
pub fn client_ids(&self) -> impl Iterator<Item = &str> {
self.clients.keys().map(String::as_str)
}
pub fn all(&self) -> impl Iterator<Item = &ClientPresence> {
self.clients.values()
}
#[must_use]
pub fn len(&self) -> usize {
self.clients.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.clients.is_empty()
}
pub fn clients_in_buffer(&self, buffer_id: u64) -> impl Iterator<Item = &ClientPresence> {
self.clients
.values()
.filter(move |p| p.active_buffer == Some(buffer_id))
}
pub fn active_clients(&self) -> impl Iterator<Item = &ClientPresence> {
self.clients.values().filter(|p| p.is_active)
}
pub fn broadcasters(&self) -> impl Iterator<Item = &ClientPresence> {
self.clients
.values()
.filter(|p| p.sync_mode.is_broadcasting())
}
pub fn clear(&mut self) {
self.clients.clear();
}
}
#[cfg(test)]
#[path = "presence_tests.rs"]
mod tests;