Skip to main content

ass_editor/sessions/
access.rs

1//! Document-access, statistics, and maintenance operations.
2//!
3//! Implements read/write access to a session's [`EditorDocument`], session
4//! statistics reporting, stale-session cleanup, shared-arena resets, and
5//! shared extension-registry management for [`EditorSessionManager`].
6
7use super::config::SessionStats;
8use super::manager::EditorSessionManager;
9use crate::core::{EditorDocument, EditorError, Result};
10
11#[cfg(feature = "plugins")]
12use std::sync::Arc;
13
14#[cfg(not(feature = "std"))]
15use alloc::{string::ToString, vec, vec::Vec};
16
17impl EditorSessionManager {
18    /// Execute a function with a read-only reference to a session's document
19    pub fn with_document<F, R>(&self, session_id: &str, f: F) -> Result<R>
20    where
21        F: FnOnce(&EditorDocument) -> Result<R>,
22    {
23        self.with_inner(|inner| {
24            inner
25                .sessions
26                .get(session_id)
27                .ok_or_else(|| EditorError::DocumentNotFound {
28                    id: session_id.to_string(),
29                })
30                .and_then(|session| f(&session.document))
31        })
32    }
33
34    /// Execute a closure with mutable access to a session's document
35    pub fn with_document_mut<F, R>(&mut self, session_id: &str, f: F) -> Result<R>
36    where
37        F: FnOnce(&mut EditorDocument) -> Result<R>,
38    {
39        self.with_inner_mut(|inner| {
40            let session = inner.sessions.get_mut(session_id).ok_or_else(|| {
41                EditorError::DocumentNotFound {
42                    id: session_id.to_string(),
43                }
44            })?;
45
46            let result = f(&mut session.document)?;
47            session.increment_operations();
48
49            Ok(result)
50        })
51    }
52
53    /// Get session statistics
54    pub fn stats(&self) -> SessionStats {
55        self.with_inner(|inner| inner.stats.clone())
56    }
57
58    /// Perform cleanup of stale sessions
59    #[cfg(feature = "std")]
60    pub fn cleanup_stale_sessions(&mut self, max_age: std::time::Duration) -> Result<usize> {
61        // Get list of stale sessions
62        let sessions_to_remove = self.with_inner(|inner| {
63            if !inner.config.auto_cleanup {
64                return vec![];
65            }
66
67            inner
68                .sessions
69                .iter()
70                .filter(|(_, session)| session.is_stale(max_age))
71                .map(|(id, _)| id.clone())
72                .collect::<Vec<_>>()
73        });
74
75        // Remove stale sessions
76        let mut removed_count = 0;
77        for session_id in sessions_to_remove {
78            if self.remove_session(&session_id).is_ok() {
79                removed_count += 1;
80            }
81        }
82
83        Ok(removed_count)
84    }
85
86    /// Reset shared arena to reclaim memory
87    #[cfg(feature = "arena")]
88    pub fn reset_shared_arena(&mut self) {
89        self.with_inner_mut(|inner| {
90            inner.shared_arena.reset();
91            inner.stats.arena_resets += 1;
92            inner.ops_since_arena_reset = 0;
93        });
94    }
95
96    /// Set shared extension registry
97    #[cfg(feature = "plugins")]
98    pub fn set_extension_registry(&mut self, registry: Arc<ass_core::plugin::ExtensionRegistry>) {
99        self.with_inner_mut(|inner| {
100            inner.extension_registry = Some(registry);
101        });
102    }
103
104    /// Get shared extension registry
105    #[cfg(feature = "plugins")]
106    #[must_use]
107    pub fn extension_registry(&self) -> Option<Arc<ass_core::plugin::ExtensionRegistry>> {
108        self.with_inner(|inner| inner.extension_registry.clone())
109    }
110}