use crate::capability::{CAP_STORAGE, STORAGE_DELETE, STORAGE_GET, STORAGE_KEYS, STORAGE_SET};
use crate::error::StdlibError;
use crate::module::StdlibModule;
use crate::value::Value;
pub struct StorageModule;
impl StorageModule {
pub fn new() -> Self {
Self
}
}
impl Default for StorageModule {
fn default() -> Self {
Self::new()
}
}
impl StdlibModule for StorageModule {
fn name(&self) -> &'static str {
"storage"
}
fn has_function(&self, function: &str) -> bool {
matches!(function, "get" | "set" | "delete" | "keys")
}
fn call(&self, function: &str, args: Vec<Value>) -> Result<Value, StdlibError> {
match function {
"get" => self.get(args),
"set" => self.set(args),
"delete" => self.delete(args),
"keys" => self.keys(args),
_ => Err(StdlibError::unknown_function("storage", function)),
}
}
}
impl StorageModule {
fn get(&self, args: Vec<Value>) -> Result<Value, StdlibError> {
if args.len() != 1 {
return Err(StdlibError::wrong_args("storage.get", 1, args.len()));
}
validate_string("storage.get", &args[0], 1)?;
Err(StdlibError::capability_call(
"storage",
"get",
CAP_STORAGE,
STORAGE_GET,
args,
))
}
fn set(&self, args: Vec<Value>) -> Result<Value, StdlibError> {
if args.len() != 2 {
return Err(StdlibError::wrong_args("storage.set", 2, args.len()));
}
validate_string("storage.set", &args[0], 1)?;
validate_string("storage.set", &args[1], 2)?;
Err(StdlibError::capability_call(
"storage",
"set",
CAP_STORAGE,
STORAGE_SET,
args,
))
}
fn delete(&self, args: Vec<Value>) -> Result<Value, StdlibError> {
if args.len() != 1 {
return Err(StdlibError::wrong_args("storage.delete", 1, args.len()));
}
validate_string("storage.delete", &args[0], 1)?;
Err(StdlibError::capability_call(
"storage",
"delete",
CAP_STORAGE,
STORAGE_DELETE,
args,
))
}
fn keys(&self, args: Vec<Value>) -> Result<Value, StdlibError> {
if !args.is_empty() {
return Err(StdlibError::wrong_args("storage.keys", 0, args.len()));
}
Err(StdlibError::capability_call(
"storage",
"keys",
CAP_STORAGE,
STORAGE_KEYS,
args,
))
}
}
fn validate_string(func: &str, val: &Value, pos: usize) -> Result<(), StdlibError> {
match val {
Value::String(_) => Ok(()),
_ => Err(StdlibError::type_mismatch(
func,
pos,
"string",
val.type_name(),
)),
}
}