Skip to main content

leviath_scripting/
sandbox.rs

1//! Sandbox configuration for Rhai scripts.
2
3/// Configuration for the Rhai sandbox.
4#[derive(Debug, Clone)]
5pub struct SandboxConfig {
6    /// Maximum number of operations before script is terminated
7    pub max_operations: usize,
8
9    /// Maximum string size in characters
10    pub max_string_size: usize,
11
12    /// Maximum array size
13    pub max_array_size: usize,
14
15    /// Maximum map size
16    pub max_map_size: usize,
17}
18
19impl Default for SandboxConfig {
20    fn default() -> Self {
21        Self {
22            max_operations: 100_000,
23            max_string_size: 1_000_000,
24            max_array_size: 10_000,
25            max_map_size: 10_000,
26        }
27    }
28}
29
30impl SandboxConfig {
31    /// Create a new sandbox configuration with custom limits.
32    pub fn new() -> Self {
33        Self::default()
34    }
35
36    /// Set the maximum number of operations.
37    pub fn with_max_operations(mut self, max: usize) -> Self {
38        self.max_operations = max;
39        self
40    }
41
42    /// Set the maximum string size.
43    pub fn with_max_string_size(mut self, max: usize) -> Self {
44        self.max_string_size = max;
45        self
46    }
47
48    /// Set the maximum array size.
49    pub fn with_max_array_size(mut self, max: usize) -> Self {
50        self.max_array_size = max;
51        self
52    }
53
54    /// Set the maximum map size.
55    pub fn with_max_map_size(mut self, max: usize) -> Self {
56        self.max_map_size = max;
57        self
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn default_has_expected_values() {
67        let cfg = SandboxConfig::default();
68        assert_eq!(cfg.max_operations, 100_000);
69        assert_eq!(cfg.max_string_size, 1_000_000);
70        assert_eq!(cfg.max_array_size, 10_000);
71        assert_eq!(cfg.max_map_size, 10_000);
72    }
73
74    #[test]
75    fn new_same_as_default() {
76        let new = SandboxConfig::new();
77        let def = SandboxConfig::default();
78        assert_eq!(new.max_operations, def.max_operations);
79        assert_eq!(new.max_string_size, def.max_string_size);
80        assert_eq!(new.max_array_size, def.max_array_size);
81        assert_eq!(new.max_map_size, def.max_map_size);
82    }
83
84    #[test]
85    fn with_max_operations() {
86        let cfg = SandboxConfig::new().with_max_operations(500);
87        assert_eq!(cfg.max_operations, 500);
88        // other fields remain default
89        assert_eq!(cfg.max_string_size, 1_000_000);
90    }
91
92    #[test]
93    fn with_max_string_size() {
94        let cfg = SandboxConfig::new().with_max_string_size(2048);
95        assert_eq!(cfg.max_string_size, 2048);
96        assert_eq!(cfg.max_operations, 100_000);
97    }
98
99    #[test]
100    fn with_max_array_size() {
101        let cfg = SandboxConfig::new().with_max_array_size(50);
102        assert_eq!(cfg.max_array_size, 50);
103        assert_eq!(cfg.max_map_size, 10_000);
104    }
105
106    #[test]
107    fn with_max_map_size() {
108        let cfg = SandboxConfig::new().with_max_map_size(99);
109        assert_eq!(cfg.max_map_size, 99);
110        assert_eq!(cfg.max_array_size, 10_000);
111    }
112
113    #[test]
114    fn chaining_multiple_builders() {
115        let cfg = SandboxConfig::new()
116            .with_max_operations(1)
117            .with_max_string_size(2)
118            .with_max_array_size(3)
119            .with_max_map_size(4);
120        assert_eq!(cfg.max_operations, 1);
121        assert_eq!(cfg.max_string_size, 2);
122        assert_eq!(cfg.max_array_size, 3);
123        assert_eq!(cfg.max_map_size, 4);
124    }
125
126    #[test]
127    fn clone_preserves_values() {
128        let cfg = SandboxConfig::new().with_max_operations(42);
129        let cloned = cfg.clone();
130        assert_eq!(cloned.max_operations, 42);
131    }
132
133    #[test]
134    fn debug_impl_exists() {
135        let cfg = SandboxConfig::new();
136        let debug = format!("{cfg:?}");
137        assert!(debug.contains("SandboxConfig"));
138        assert!(debug.contains("100000"));
139    }
140}