use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify))]
#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
pub enum SyncMode {
#[default]
Independent,
Broadcast,
Follow {
target: String,
},
Accept,
}
impl SyncMode {
#[must_use]
pub fn follow(target: impl Into<String>) -> Self {
Self::Follow {
target: target.into(),
}
}
#[must_use]
pub const fn is_broadcasting(&self) -> bool {
matches!(self, Self::Broadcast)
}
#[must_use]
pub const fn is_receiving(&self) -> bool {
matches!(self, Self::Follow { .. } | Self::Accept)
}
#[must_use]
pub const fn is_independent(&self) -> bool {
matches!(self, Self::Independent)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify))]
#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
pub struct ClientPresence {
pub client_id: String,
pub name: Option<String>,
pub sync_mode: SyncMode,
pub active_buffer: Option<u64>,
pub cursor: Option<(u32, u32)>,
pub is_active: bool,
}
impl ClientPresence {
#[must_use]
pub fn new(client_id: impl Into<String>) -> Self {
Self {
client_id: client_id.into(),
name: None,
sync_mode: SyncMode::Independent,
active_buffer: None,
cursor: None,
is_active: true,
}
}
#[must_use]
pub fn with_name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
#[must_use]
pub fn with_sync_mode(mut self, mode: SyncMode) -> Self {
self.sync_mode = mode;
self
}
#[must_use]
pub const fn with_position(mut self, buffer_id: u64, line: u32, col: u32) -> Self {
self.active_buffer = Some(buffer_id);
self.cursor = Some((line, col));
self
}
#[must_use]
pub fn display_name(&self) -> &str {
self.name.as_deref().unwrap_or(&self.client_id)
}
}
#[cfg(test)]
#[path = "presence_tests.rs"]
mod tests;