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