//! [`TerminalSessions`] — the active-terminal registry (application service). //! //! Maps a [`SessionId`] to the live [`PtyHandle`] and the [`TerminalSession`] //! snapshot. Thread-safe (behind a [`Mutex`]); a single instance is shared //! (as `Arc`) by all terminal use cases via the composition root. See the module //! docs in `terminal/mod.rs` for the rationale of keeping this in the //! application layer rather than the domain or the adapter. use std::collections::HashMap; use std::sync::Mutex; use domain::ports::PtyHandle; use domain::{SessionId, TerminalSession}; /// A registered, live terminal: its PTY handle plus the domain snapshot. #[derive(Debug, Clone)] struct Entry { handle: PtyHandle, session: TerminalSession, } /// In-memory registry of active terminal sessions. #[derive(Default)] pub struct TerminalSessions { entries: Mutex>, } impl TerminalSessions { /// Creates an empty registry. #[must_use] pub fn new() -> Self { Self { entries: Mutex::new(HashMap::new()), } } /// Inserts a freshly-opened session. pub fn insert(&self, handle: PtyHandle, session: TerminalSession) { if let Ok(mut map) = self.entries.lock() { map.insert(session.id, Entry { handle, session }); } } /// Returns the [`PtyHandle`] for a session, if registered. #[must_use] pub fn handle(&self, id: &SessionId) -> Option { self.entries .lock() .ok() .and_then(|m| m.get(id).map(|e| e.handle.clone())) } /// Returns the [`TerminalSession`] snapshot for a session, if registered. #[must_use] pub fn session(&self, id: &SessionId) -> Option { self.entries .lock() .ok() .and_then(|m| m.get(id).map(|e| e.session.clone())) } /// Removes a session from the registry, returning its handle if present. pub fn remove(&self, id: &SessionId) -> Option { self.entries .lock() .ok() .and_then(|mut m| m.remove(id).map(|e| e.handle)) } /// Number of currently-registered sessions. #[must_use] pub fn len(&self) -> usize { self.entries.lock().map(|m| m.len()).unwrap_or(0) } /// Whether the registry is empty. #[must_use] pub fn is_empty(&self) -> bool { self.len() == 0 } }