Skip to main content

spreadsheet_mcp/recalc/
mod.rs

1#[cfg(feature = "recalc")]
2mod backend;
3#[cfg(feature = "recalc")]
4mod executor;
5#[cfg(feature = "recalc-libreoffice")]
6mod fire_and_forget;
7#[cfg(feature = "recalc-formualizer")]
8mod formualizer_backend;
9#[cfg(feature = "recalc")]
10pub mod macro_uri;
11#[cfg(feature = "recalc-libreoffice")]
12mod pooled;
13#[cfg(feature = "recalc-libreoffice")]
14mod screenshot;
15
16#[cfg(feature = "recalc-libreoffice")]
17pub use backend::LibreOfficeBackend;
18#[cfg(feature = "recalc")]
19pub use backend::RecalcBackend;
20#[cfg(feature = "recalc-libreoffice")]
21pub use executor::RecalcExecutor;
22#[cfg(feature = "recalc")]
23pub use executor::RecalcResult;
24#[cfg(feature = "recalc-libreoffice")]
25pub use fire_and_forget::FireAndForgetExecutor;
26#[cfg(feature = "recalc-formualizer")]
27pub use formualizer_backend::FormualizerBackend;
28#[cfg(feature = "recalc-libreoffice")]
29pub use screenshot::{ScreenshotExecutor, ScreenshotResult};
30
31use std::path::PathBuf;
32#[cfg(feature = "recalc")]
33use std::sync::Arc;
34#[cfg(feature = "recalc")]
35use tokio::sync::Semaphore;
36
37#[cfg(feature = "recalc")]
38#[derive(Clone)]
39pub struct GlobalRecalcLock(pub Arc<Semaphore>);
40
41#[cfg(feature = "recalc")]
42impl GlobalRecalcLock {
43    pub fn new(permits: usize) -> Self {
44        Self(Arc::new(Semaphore::new(permits)))
45    }
46}
47
48#[cfg(feature = "recalc")]
49#[derive(Clone)]
50pub struct GlobalScreenshotLock(pub Arc<Semaphore>);
51
52#[cfg(feature = "recalc")]
53impl GlobalScreenshotLock {
54    pub fn new() -> Self {
55        Self(Arc::new(Semaphore::new(1)))
56    }
57}
58
59#[cfg(feature = "recalc")]
60impl Default for GlobalScreenshotLock {
61    fn default() -> Self {
62        Self::new()
63    }
64}
65
66#[derive(Debug, Clone, Copy, Default)]
67pub enum ExecutorStrategy {
68    #[default]
69    FireAndForget,
70    Pooled,
71}
72
73#[derive(Debug, Clone)]
74pub struct RecalcConfig {
75    pub soffice_path: Option<PathBuf>,
76    pub timeout_ms: Option<u64>,
77    pub strategy: ExecutorStrategy,
78}
79
80impl Default for RecalcConfig {
81    fn default() -> Self {
82        Self {
83            soffice_path: None,
84            timeout_ms: Some(30_000),
85            strategy: ExecutorStrategy::FireAndForget,
86        }
87    }
88}
89
90#[cfg(feature = "recalc-libreoffice")]
91pub fn create_executor(config: &RecalcConfig) -> Arc<dyn RecalcExecutor> {
92    match config.strategy {
93        ExecutorStrategy::FireAndForget => Arc::new(FireAndForgetExecutor::new(config)),
94        ExecutorStrategy::Pooled => {
95            tracing::warn!("Pooled executor not yet implemented, falling back to fire-and-forget");
96            Arc::new(FireAndForgetExecutor::new(config))
97        }
98    }
99}