use serde::{Deserialize, Serialize};
pub const DEFAULT_FUEL_LIMIT: u64 = 10_000_000;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WasmGuardConfig {
pub name: String,
pub path: String,
#[serde(default = "default_fuel_limit")]
pub fuel_limit: u64,
#[serde(default = "default_priority")]
pub priority: u32,
#[serde(default)]
pub advisory: bool,
#[serde(default = "default_max_memory_bytes")]
pub max_memory_bytes: usize,
#[serde(default = "default_max_module_size")]
pub max_module_size: usize,
}
fn default_fuel_limit() -> u64 {
DEFAULT_FUEL_LIMIT
}
fn default_priority() -> u32 {
1000
}
fn default_max_memory_bytes() -> usize {
16 * 1024 * 1024
}
fn default_max_module_size() -> usize {
10 * 1024 * 1024
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn config_deserializes_with_defaults() {
let json = r#"{"name": "pii-guard", "path": "/etc/chio/guards/pii.wasm"}"#;
let config: WasmGuardConfig =
serde_json::from_str(json).expect("deserialize config with defaults");
assert_eq!(config.name, "pii-guard");
assert_eq!(config.fuel_limit, DEFAULT_FUEL_LIMIT);
assert_eq!(config.priority, 1000);
assert!(!config.advisory);
}
#[test]
fn config_deserializes_with_overrides() {
let json = r#"{
"name": "custom",
"path": "/opt/guard.wasm",
"fuel_limit": 5000000,
"priority": 50,
"advisory": true
}"#;
let config: WasmGuardConfig =
serde_json::from_str(json).expect("deserialize config with overrides");
assert_eq!(config.fuel_limit, 5_000_000);
assert_eq!(config.priority, 50);
assert!(config.advisory);
}
#[test]
fn config_round_trips_through_json() {
let original = WasmGuardConfig {
name: "test".to_string(),
path: "/tmp/test.wasm".to_string(),
fuel_limit: 1_000_000,
priority: 100,
advisory: false,
max_memory_bytes: 8 * 1024 * 1024,
max_module_size: 5 * 1024 * 1024,
};
let json = serde_json::to_string(&original).expect("serialize");
let recovered: WasmGuardConfig = serde_json::from_str(&json).expect("deserialize");
assert_eq!(recovered.name, original.name);
assert_eq!(recovered.fuel_limit, original.fuel_limit);
assert_eq!(recovered.max_memory_bytes, original.max_memory_bytes);
assert_eq!(recovered.max_module_size, original.max_module_size);
}
#[test]
fn config_missing_name_fails() {
let json = r#"{"path": "/etc/chio/guards/test.wasm"}"#;
let result: Result<WasmGuardConfig, _> = serde_json::from_str(json);
assert!(result.is_err());
}
#[test]
fn config_missing_path_fails() {
let json = r#"{"name": "test"}"#;
let result: Result<WasmGuardConfig, _> = serde_json::from_str(json);
assert!(result.is_err());
}
#[test]
fn config_all_fields_explicit() {
let json = r#"{
"name": "pii-guard",
"path": "/etc/chio/guards/pii.wasm",
"fuel_limit": 2000000,
"priority": 50,
"advisory": true
}"#;
let config: WasmGuardConfig = serde_json::from_str(json).expect("deserialize all fields");
assert_eq!(config.name, "pii-guard");
assert_eq!(config.fuel_limit, 2_000_000);
assert_eq!(config.priority, 50);
assert!(config.advisory);
}
#[test]
fn config_zero_fuel_limit_allowed() {
let json = r#"{"name": "test", "path": "/test.wasm", "fuel_limit": 0}"#;
let config: WasmGuardConfig = serde_json::from_str(json).expect("deserialize");
assert_eq!(config.fuel_limit, 0);
}
#[test]
fn config_max_priority_allowed() {
let json = r#"{"name": "test", "path": "/test.wasm", "priority": 4294967295}"#;
let config: WasmGuardConfig = serde_json::from_str(json).expect("deserialize");
assert_eq!(config.priority, u32::MAX);
}
#[test]
fn config_deserializes_with_default_memory_and_module_limits() {
let json = r#"{"name": "pii-guard", "path": "/etc/chio/guards/pii.wasm"}"#;
let config: WasmGuardConfig =
serde_json::from_str(json).expect("deserialize config with default limits");
assert_eq!(config.max_memory_bytes, 16 * 1024 * 1024);
assert_eq!(config.max_module_size, 10 * 1024 * 1024);
}
#[test]
fn config_deserializes_with_overridden_memory_and_module_limits() {
let json = r#"{
"name": "custom",
"path": "/opt/guard.wasm",
"max_memory_bytes": 8388608,
"max_module_size": 5242880
}"#;
let config: WasmGuardConfig =
serde_json::from_str(json).expect("deserialize config with overrides");
assert_eq!(config.max_memory_bytes, 8_388_608);
assert_eq!(config.max_module_size, 5_242_880);
}
}