Document macros.
This commit is contained in:
parent
928f044553
commit
180c4dee08
@ -11,11 +11,15 @@ use crate::engine::Array;
|
|||||||
use crate::stdlib::{string::String, vec, vec::Vec};
|
use crate::stdlib::{string::String, vec, vec::Vec};
|
||||||
|
|
||||||
/// Trait that represent arguments to a function call.
|
/// Trait that represent arguments to a function call.
|
||||||
|
/// Any data type that can be converted into a `Vec` of `Dynamic` values can be used
|
||||||
|
/// as arguments to a function call.
|
||||||
pub trait FuncArgs {
|
pub trait FuncArgs {
|
||||||
/// Convert to a `Vec` of `Dynamic` arguments.
|
/// Convert to a `Vec` of `Dynamic` arguments.
|
||||||
fn into_vec(self) -> Vec<Dynamic>;
|
fn into_vec(self) -> Vec<Dynamic>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Macro to implement `FuncArgs` for a single standard type that can be converted
|
||||||
|
/// into `Dynamic`.
|
||||||
macro_rules! impl_std_args {
|
macro_rules! impl_std_args {
|
||||||
($($p:ty),*) => {
|
($($p:ty),*) => {
|
||||||
$(
|
$(
|
||||||
@ -43,6 +47,8 @@ impl_std_args!(INT);
|
|||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
impl_std_args!(f32, f64);
|
impl_std_args!(f32, f64);
|
||||||
|
|
||||||
|
/// Macro to implement `FuncArgs` for tuples of standard types (each can be
|
||||||
|
/// converted into `Dynamic`).
|
||||||
macro_rules! impl_args {
|
macro_rules! impl_args {
|
||||||
($($p:ident),*) => {
|
($($p:ident),*) => {
|
||||||
impl<$($p: Any + Clone),*> FuncArgs for ($($p,)*)
|
impl<$($p: Any + Clone),*> FuncArgs for ($($p,)*)
|
||||||
|
@ -80,7 +80,8 @@ pub trait RegisterResultFn<FN, ARGS, RET> {
|
|||||||
/// // Normal function
|
/// // Normal function
|
||||||
/// fn div(x: i64, y: i64) -> Result<i64, EvalAltResult> {
|
/// fn div(x: i64, y: i64) -> Result<i64, EvalAltResult> {
|
||||||
/// if y == 0 {
|
/// if y == 0 {
|
||||||
/// Err("division by zero!".into()) // '.into()' automatically converts to 'EvalAltResult::ErrorRuntime'
|
/// // '.into()' automatically converts to 'EvalAltResult::ErrorRuntime'
|
||||||
|
/// Err("division by zero!".into())
|
||||||
/// } else {
|
/// } else {
|
||||||
/// Ok(x / y)
|
/// Ok(x / y)
|
||||||
/// }
|
/// }
|
||||||
@ -97,14 +98,28 @@ pub trait RegisterResultFn<FN, ARGS, RET> {
|
|||||||
fn register_result_fn(&mut self, name: &str, f: FN);
|
fn register_result_fn(&mut self, name: &str, f: FN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These types are used to build a unique _marker_ tuple type for each combination
|
||||||
|
// of function parameter types in order to make each trait implementation unique.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// `RegisterFn<FN, (Mut<A>, B, Ref<C>), R>`
|
||||||
|
//
|
||||||
|
// will have the function prototype constraint to:
|
||||||
|
//
|
||||||
|
// `FN: (&mut A, B, &C) -> R`
|
||||||
|
//
|
||||||
|
// These types are not actually used anywhere.
|
||||||
pub struct Ref<A>(A);
|
pub struct Ref<A>(A);
|
||||||
pub struct Mut<A>(A);
|
pub struct Mut<A>(A);
|
||||||
|
|
||||||
|
/// Identity dereferencing function.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity<T>(data: T) -> T {
|
fn identity<T>(data: T) -> T {
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This macro counts the number of arguments via recursion.
|
||||||
macro_rules! count_args {
|
macro_rules! count_args {
|
||||||
() => { 0_usize };
|
() => { 0_usize };
|
||||||
( $head:ident $($tail:ident)* ) => { 1_usize + count_args!($($tail)*) };
|
( $head:ident $($tail:ident)* ) => { 1_usize + count_args!($($tail)*) };
|
||||||
@ -115,6 +130,10 @@ macro_rules! def_register {
|
|||||||
def_register!(imp);
|
def_register!(imp);
|
||||||
};
|
};
|
||||||
(imp $($par:ident => $mark:ty => $param:ty => $clone:expr),*) => {
|
(imp $($par:ident => $mark:ty => $param:ty => $clone:expr),*) => {
|
||||||
|
// ^ function parameter generic type name
|
||||||
|
// ^ function parameter marker type (A, Ref<A> or Mut<A>)
|
||||||
|
// ^ function parameter actual type
|
||||||
|
// ^ dereferencing function
|
||||||
impl<
|
impl<
|
||||||
$($par: Any + Clone,)*
|
$($par: Any + Clone,)*
|
||||||
FN: Fn($($param),*) -> RET + 'static,
|
FN: Fn($($param),*) -> RET + 'static,
|
||||||
@ -220,6 +239,8 @@ macro_rules! def_register {
|
|||||||
def_register!(imp $p0 => $p0 => $p0 => Clone::clone $(, $p => $p => $p => Clone::clone)*);
|
def_register!(imp $p0 => $p0 => $p0 => Clone::clone $(, $p => $p => $p => Clone::clone)*);
|
||||||
def_register!(imp $p0 => Ref<$p0> => &$p0 => identity $(, $p => $p => $p => Clone::clone)*);
|
def_register!(imp $p0 => Ref<$p0> => &$p0 => identity $(, $p => $p => $p => Clone::clone)*);
|
||||||
def_register!(imp $p0 => Mut<$p0> => &mut $p0 => identity $(, $p => $p => $p => Clone::clone)*);
|
def_register!(imp $p0 => Mut<$p0> => &mut $p0 => identity $(, $p => $p => $p => Clone::clone)*);
|
||||||
|
// handle the first parameter ^ first parameter passed through
|
||||||
|
// others passed by value (cloned) ^
|
||||||
|
|
||||||
def_register!($($p),*);
|
def_register!($($p),*);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user