use crate::val::{ByteQue, Store};
use std::collections::HashMap;
pub type Result<T> = std::result::Result<T, String>;
impl<T> Store for Result<T>
where
T: Store,
{
#[inline]
fn store(&self, q: &mut ByteQue) {
match self {
Ok(t) => {
false.store(q);
t.store(q);
}
Err(e) => {
true.store(q);
e.store(q);
}
}
}
#[inline]
fn restore(q: &mut ByteQue) -> Self {
if bool::restore(q) {
return Err(Store::restore(q));
}
Ok(Store::restore(q))
}
}
pub struct Fun {
fun: HashMap<String, fn(&mut ByteQue) -> ByteQue>,
}
impl Fun {
pub fn new() -> Self {
Fun {
fun: HashMap::new(),
}
}
pub fn regist(&mut self, name: &str, f: fn(&mut ByteQue) -> ByteQue) {
self.fun.insert(String::from(name), f);
}
pub fn invoke(&self, q: &mut ByteQue) -> ByteQue {
let name = String::restore(q);
match self.fun.get(&name) {
Some(f) => f(q),
None => {
let mut r = ByteQue::new();
true.store(&mut r);
format!("{} function not found", name).store(&mut r);
r
}
}
}
}
#[macro_export]
macro_rules! fun {
($name:expr $(,$arg:expr)*) => {{
let mut q = $crate::ByteQue::new();
String::from($name).store(&mut q);
$($arg.store(&mut q);)*
q
}};
($name:expr, $($arg:expr,)*) => {
$crate::fun!($name $(,$arg)*)
}
}