//! Room identity and lifecycle. use crate::ids::RoomId; use crate::retention::Retention; /// Whether a room accepts reads and writes right now. /// /// The host maps its own state onto this. Multithreaded: an active community /// with chat enabled is [`RoomState::Open`]; `Frozen` and `Archived` communities /// are [`RoomState::ReadOnly`], matching how threads already behave; a community /// with `chat_policy = off` is [`RoomState::Closed`]. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RoomState { /// Reads and writes, subject to per-user authz. Open, /// Reads only. The room and its backlog stay visible; nobody can send. ReadOnly, /// The room does not exist as far as the outside is concerned. Callers should /// render a 404, not a disabled input: a closed room has no route, no hub /// entry, and no UI affordance. Closed, } impl RoomState { pub fn allows_reads(&self) -> bool { matches!(self, Self::Open | Self::ReadOnly) } pub fn allows_writes(&self) -> bool { matches!(self, Self::Open) } } /// A resolved room. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Room { pub id: RoomId, pub state: RoomState, pub retention: Retention, } #[cfg(test)] mod tests { use super::*; #[test] fn closed_rooms_allow_nothing() { assert!(!RoomState::Closed.allows_reads()); assert!(!RoomState::Closed.allows_writes()); } #[test] fn read_only_rooms_read_but_do_not_write() { assert!(RoomState::ReadOnly.allows_reads()); assert!(!RoomState::ReadOnly.allows_writes()); } #[test] fn open_rooms_allow_both() { assert!(RoomState::Open.allows_reads()); assert!(RoomState::Open.allows_writes()); } }