Files
buzz/crates/buzz-core/src/presence.rs
Will Pfleger d99ad131f1 refactor: rename sprout backend to buzz (#958)
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <wpfleger@block.xyz>
Signed-off-by: Will Pfleger <wpfleger@squareup.com>
Signed-off-by: Will Pfleger <wpfleger96@gmail.com>
Co-authored-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub1fgdl5qqnh3k3f2xkqrvt7cujalhm623x4s7fdjdj5yrtp5fzjl9qrjpucw <4a1bfa0013bc6d14a8d600d8bf6392efefbd2a26ac3c96c9b2a106b0d12297ca@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: npub16v54tttfqacx9ycvc3k0ut0npj564ahcuajzy6qjvh57ntmsf4uq4806j2 <d32955ad69077062930cc46cfe2df30ca9aaf6f8e76422681265e9e9af704d78@sprout-oss.stage.blox.sqprod.co>
Co-authored-by: Will Pfleger <wpfleger96@gmail.com>
2026-06-10 19:29:51 -04:00

74 lines
2.2 KiB
Rust

//! Presence status types shared across REST, MCP, and WebSocket surfaces.
use serde::{Deserialize, Serialize};
/// Allowed presence statuses for the REST/MCP surface.
///
/// The WebSocket path (kind:20001) accepts arbitrary status strings for
/// forward-compatibility; this enum is the curated set for structured APIs.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum PresenceStatus {
/// User is actively online.
Online,
/// User is away / idle.
Away,
/// User is offline; clears the presence entry.
Offline,
}
impl PresenceStatus {
/// Returns the lowercase string representation stored in Redis.
pub fn as_str(&self) -> &'static str {
match self {
Self::Online => "online",
Self::Away => "away",
Self::Offline => "offline",
}
}
}
impl std::fmt::Display for PresenceStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serde_roundtrip() {
let online: PresenceStatus = serde_json::from_str(r#""online""#).unwrap();
assert_eq!(online, PresenceStatus::Online);
assert_eq!(serde_json::to_string(&online).unwrap(), r#""online""#);
let away: PresenceStatus = serde_json::from_str(r#""away""#).unwrap();
assert_eq!(away, PresenceStatus::Away);
let offline: PresenceStatus = serde_json::from_str(r#""offline""#).unwrap();
assert_eq!(offline, PresenceStatus::Offline);
}
#[test]
fn serde_rejects_unknown_variant() {
let result: Result<PresenceStatus, _> = serde_json::from_str(r#""invisible""#);
assert!(result.is_err());
}
#[test]
fn as_str_matches_serde() {
assert_eq!(PresenceStatus::Online.as_str(), "online");
assert_eq!(PresenceStatus::Away.as_str(), "away");
assert_eq!(PresenceStatus::Offline.as_str(), "offline");
}
#[test]
fn display_matches_as_str() {
assert_eq!(format!("{}", PresenceStatus::Online), "online");
assert_eq!(format!("{}", PresenceStatus::Away), "away");
assert_eq!(format!("{}", PresenceStatus::Offline), "offline");
}
}