use std::sync::Arc;
use crate::{Bridge, CompiledModule, ExecutionResult, Observation, Result, SandboxConfig};
pub struct PersistentSandbox {
module: Arc<CompiledModule>,
bridge: Arc<dyn Bridge>,
config: SandboxConfig,
loaded_scripts: Vec<String>,
}
impl PersistentSandbox {
pub fn new(
module: &CompiledModule,
bridge: Arc<dyn Bridge>,
config: &SandboxConfig,
) -> Result<Self> {
let serialized = module.serialize()?;
let module = CompiledModule::load_cached(&serialized)?;
Ok(Self {
module: Arc::new(module),
bridge,
config: config.clone(),
loaded_scripts: Vec::new(),
})
}
pub fn load(&mut self, scripts: &[String]) -> Result<()> {
self.loaded_scripts = scripts.to_vec();
let _ = self.execute(&[])?;
Ok(())
}
#[must_use]
pub fn eval_only(&mut self, script: &str) -> Vec<Observation> {
self.execute(&[script.to_string()])
.map(|result| result.observations)
.unwrap_or_default()
}
pub fn store_fuel(&self) -> Result<u64> {
Ok(self.config.max_fuel)
}
pub fn set_store_fuel(&mut self, fuel: u64) {
self.config.max_fuel = fuel;
}
fn execute(&self, extra_scripts: &[String]) -> Result<ExecutionResult> {
let mut scripts = self.loaded_scripts.clone();
scripts.extend(extra_scripts.iter().cloned());
self.module
.execute(&scripts, Arc::clone(&self.bridge), &self.config)
}
}