Skip to main content

shape_runtime/engine/
builder.rs

1//! Builder pattern for creating Shape engine with configuration
2
3use super::ShapeEngine;
4use crate::DataFrame;
5use shape_ast::error::Result;
6
7/// Builder pattern for creating an engine with configuration
8pub struct ShapeEngineBuilder {
9    data: Option<DataFrame>,
10    async_provider: Option<crate::data::SharedAsyncProvider>,
11    enable_debug: bool,
12    max_execution_time: Option<std::time::Duration>,
13    memory_limit: Option<usize>,
14}
15
16impl ShapeEngineBuilder {
17    pub fn new() -> Self {
18        Self {
19            data: None,
20            async_provider: None,
21            enable_debug: false,
22            max_execution_time: None,
23            memory_limit: None,
24        }
25    }
26
27    pub fn with_data(mut self, data: DataFrame) -> Self {
28        self.data = Some(data);
29        self
30    }
31
32    /// Set async data provider (Phase 6)
33    ///
34    /// When using an async provider, the engine will prefetch data before execution.
35    /// This enables concurrent data loading and live data streaming.
36    pub fn with_async_provider(mut self, provider: crate::data::SharedAsyncProvider) -> Self {
37        self.async_provider = Some(provider);
38        self
39    }
40
41    pub fn enable_debug(mut self, enable: bool) -> Self {
42        self.enable_debug = enable;
43        self
44    }
45
46    pub fn max_execution_time(mut self, duration: std::time::Duration) -> Self {
47        self.max_execution_time = Some(duration);
48        self
49    }
50
51    pub fn memory_limit(mut self, bytes: usize) -> Self {
52        self.memory_limit = Some(bytes);
53        self
54    }
55
56    pub fn build(self) -> Result<ShapeEngine> {
57        let mut engine = if let Some(provider) = self.async_provider {
58            // Phase 6: Use async provider
59            ShapeEngine::with_async_provider(provider)?
60        } else if let Some(data) = self.data {
61            // Legacy: Use initial data
62            ShapeEngine::with_data(data)?
63        } else {
64            // Default: No data
65            ShapeEngine::new()?
66        };
67
68        // Apply configuration
69        if self.enable_debug {
70            engine.runtime.set_debug_mode(true);
71        }
72
73        // Apply execution time and memory limits
74        if let Some(max_time) = self.max_execution_time {
75            engine.runtime.set_execution_timeout(max_time);
76        }
77        if let Some(mem_limit) = self.memory_limit {
78            engine.runtime.set_memory_limit(mem_limit);
79        }
80
81        // Load stdlib by default
82        engine.load_stdlib()?;
83
84        Ok(engine)
85    }
86}
87
88impl Default for ShapeEngineBuilder {
89    fn default() -> Self {
90        Self::new()
91    }
92}