//! Per-script overrides for the Rhai sandbox limits. //! //! All fields are optional: `None` means "use the executor's platform //! default for this knob". Stored as JSONB in the `scripts.sandbox` //! column so adding new knobs in the future is a code-only change. //! //! Values are clamped against the admin-set ceiling at write time //! (in `manager-core`). The executor trusts what's stored: it merges //! defaults + overrides per call and applies the result. use serde::{Deserialize, Serialize}; #[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] #[serde(deny_unknown_fields)] pub struct ScriptSandbox { #[serde(skip_serializing_if = "Option::is_none")] pub max_operations: Option, #[serde(skip_serializing_if = "Option::is_none")] pub max_string_size: Option, #[serde(skip_serializing_if = "Option::is_none")] pub max_array_size: Option, #[serde(skip_serializing_if = "Option::is_none")] pub max_map_size: Option, #[serde(skip_serializing_if = "Option::is_none")] pub max_call_levels: Option, #[serde(skip_serializing_if = "Option::is_none")] pub max_expr_depth: Option, } impl ScriptSandbox { #[must_use] pub const fn empty() -> Self { Self { max_operations: None, max_string_size: None, max_array_size: None, max_map_size: None, max_call_levels: None, max_expr_depth: None, } } /// Returns true if every field is `None` (no overrides). #[must_use] pub const fn is_empty(&self) -> bool { self.max_operations.is_none() && self.max_string_size.is_none() && self.max_array_size.is_none() && self.max_map_size.is_none() && self.max_call_levels.is_none() && self.max_expr_depth.is_none() } }