use chio_kernel::Guard;
use crate::abi::WasmGuardAbi;
use crate::config::WasmGuardConfig;
use crate::error::WasmGuardError;
use super::guard::WasmGuard;
pub struct WasmGuardRuntime {
guards: Vec<WasmGuard>,
}
impl WasmGuardRuntime {
pub fn new() -> Self {
Self { guards: Vec::new() }
}
pub fn add_guard(&mut self, guard: WasmGuard) {
self.guards.push(guard);
}
pub fn load_guard<F>(
&mut self,
config: &WasmGuardConfig,
factory: F,
) -> Result<(), WasmGuardError>
where
F: FnOnce(&[u8], u64) -> Result<Box<dyn WasmGuardAbi>, WasmGuardError>,
{
let wasm_bytes = std::fs::read(&config.path).map_err(|e| WasmGuardError::ModuleLoad {
path: config.path.clone(),
reason: e.to_string(),
})?;
if wasm_bytes.len() > config.max_module_size {
return Err(WasmGuardError::ModuleTooLarge {
size: wasm_bytes.len(),
limit: config.max_module_size,
});
}
let backend = factory(&wasm_bytes, config.fuel_limit)?;
self.guards.push(WasmGuard::new(
config.name.clone(),
backend,
config.advisory,
None, ));
Ok(())
}
#[must_use]
pub fn guard_count(&self) -> usize {
self.guards.len()
}
pub fn guards(&self) -> impl Iterator<Item = &WasmGuard> {
self.guards.iter()
}
pub fn into_guards(self) -> Vec<Box<dyn Guard>> {
self.guards
.into_iter()
.map(|g| Box::new(g) as Box<dyn Guard>)
.collect()
}
}
impl Default for WasmGuardRuntime {
fn default() -> Self {
Self::new()
}
}