68 lines
2.5 KiB
Rust
68 lines
2.5 KiB
Rust
use super::{Env, FromValue, NativeFunction, Value};
|
|
|
|
macro_rules! impl_function {
|
|
( $($ty:ident),* $(,)? ) => {
|
|
#[allow(non_snake_case, unused_variables, unused_mut, unused_assignments)]
|
|
impl<F,R,$($ty,)*> NativeFunction<($($ty,)*)> for F
|
|
where
|
|
F: Fn($(&$ty,)*) -> R,
|
|
R: Into<Value>,
|
|
$($ty: FromValue,)*
|
|
{
|
|
fn native_execute(&self, _: &Env, args: &[Value]) -> Result<Value, String> {
|
|
let mut args = args.iter();
|
|
let total_count = {
|
|
let mut count = 0;
|
|
$(
|
|
let _: Option<$ty> = None;
|
|
count += 1;
|
|
)*
|
|
count
|
|
};
|
|
let mut count = 0;
|
|
$(
|
|
let arg = args.next()
|
|
.ok_or_else(|| format!("method expected {} parameters, but parameter {} was missing", total_count, count))?;
|
|
let $ty = $ty::from_value(arg)
|
|
.ok_or_else(|| format!("Parameter {} was not of type {}, it was {}", count, std::any::type_name::<$ty>(), arg.value_kind()))?;
|
|
count += 1;
|
|
)*
|
|
Ok(self($($ty,)*).into())
|
|
}
|
|
}
|
|
|
|
|
|
#[allow(non_snake_case, unused_variables, unused_mut, unused_assignments)]
|
|
impl<F,R,$($ty,)*> NativeFunction<((), $($ty,)*)> for F
|
|
where
|
|
F: Fn(&Env, $(&$ty,)*) -> R,
|
|
R: Into<Value>,
|
|
$($ty: FromValue,)*
|
|
{
|
|
fn native_execute(&self, env: &Env, args: &[Value]) -> Result<Value, String> {
|
|
let mut args = args.iter();
|
|
let total_count = {
|
|
let mut count = 0;
|
|
$(
|
|
let _: Option<$ty> = None;
|
|
count += 1;
|
|
)*
|
|
count
|
|
};
|
|
let mut count = 0;
|
|
$(
|
|
let arg = args.next()
|
|
.ok_or_else(|| format!("method expected {} parameters, but parameter {} was missing", total_count, count))?;
|
|
let $ty = $ty::from_value(arg)
|
|
.ok_or_else(|| format!("Parameter {} was not of type {}, it was {}", count, std::any::type_name::<$ty>(), arg.value_kind()))?;
|
|
count += 1;
|
|
)*
|
|
Ok(self(env, $($ty,)*).into())
|
|
}
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
crate::macros::for_each_tuple!(impl_function);
|