Added Arg::is
Allows for manually defining basic generic function reflection
This commit is contained in:
parent
14cc62c9c7
commit
85482b393a
@ -183,6 +183,14 @@ impl<'a> Arg<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the argument is of type `T`.
|
||||
pub fn is<T: TypePath>(&self) -> bool {
|
||||
self.value
|
||||
.try_as_reflect()
|
||||
.map(<dyn Reflect>::is::<T>)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an argument that can be passed to a [`DynamicFunction`] or [`DynamicFunctionMut`].
|
||||
|
||||
@ -328,7 +328,7 @@ impl<'env> IntoFunctionMut<'env, ()> for DynamicFunction<'env> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::func::IntoReturn;
|
||||
use crate::func::{FunctionInfo, IntoReturn};
|
||||
|
||||
#[test]
|
||||
fn should_overwrite_function_name() {
|
||||
@ -434,4 +434,46 @@ mod tests {
|
||||
let value = factorial.call(args).unwrap().unwrap_owned();
|
||||
assert_eq!(value.try_take::<i32>().unwrap(), 120);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_allow_creating_manual_generic_dynamic_function() {
|
||||
let func = DynamicFunction::new(
|
||||
|mut args| {
|
||||
let a = args.take_arg()?;
|
||||
let b = args.take_arg()?;
|
||||
|
||||
if a.is::<i32>() {
|
||||
let a = a.take::<i32>()?;
|
||||
let b = b.take::<i32>()?;
|
||||
Ok((a + b).into_return())
|
||||
} else {
|
||||
let a = a.take::<f32>()?;
|
||||
let b = b.take::<f32>()?;
|
||||
Ok((a + b).into_return())
|
||||
}
|
||||
},
|
||||
vec![
|
||||
FunctionInfo::named("add::<i32>")
|
||||
.with_arg::<i32>("a")
|
||||
.with_arg::<i32>("b")
|
||||
.with_return::<i32>(),
|
||||
FunctionInfo::named("add::<f32>")
|
||||
.with_arg::<f32>("a")
|
||||
.with_arg::<f32>("b")
|
||||
.with_return::<f32>(),
|
||||
],
|
||||
);
|
||||
|
||||
assert!(func.name().is_none());
|
||||
let func = func.with_name("add");
|
||||
assert_eq!(func.name().unwrap(), "add");
|
||||
|
||||
let args = ArgList::default().push_owned(25_i32).push_owned(75_i32);
|
||||
let result = func.call(args).unwrap().unwrap_owned();
|
||||
assert_eq!(result.try_take::<i32>().unwrap(), 100);
|
||||
|
||||
let args = ArgList::default().push_owned(25.0_f32).push_owned(75.0_f32);
|
||||
let result = func.call(args).unwrap().unwrap_owned();
|
||||
assert_eq!(result.try_take::<f32>().unwrap(), 100.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,6 +276,7 @@ impl<'env> IntoFunctionMut<'env, ()> for DynamicFunctionMut<'env> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::func::{FunctionInfo, IntoReturn};
|
||||
|
||||
#[test]
|
||||
fn should_overwrite_function_name() {
|
||||
@ -323,4 +324,40 @@ mod tests {
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_allow_creating_manual_generic_dynamic_function_mut() {
|
||||
let mut total = 0_i32;
|
||||
let func = DynamicFunctionMut::new(
|
||||
|mut args| {
|
||||
let value = args.take_arg()?;
|
||||
|
||||
if value.is::<i32>() {
|
||||
let value = value.take::<i32>()?;
|
||||
total += value;
|
||||
} else {
|
||||
let value = value.take::<i16>()?;
|
||||
total += value as i32;
|
||||
}
|
||||
|
||||
Ok(().into_return())
|
||||
},
|
||||
vec![
|
||||
FunctionInfo::named("add::<i32>").with_arg::<i32>("value"),
|
||||
FunctionInfo::named("add::<i16>").with_arg::<i16>("value"),
|
||||
],
|
||||
);
|
||||
|
||||
assert!(func.name().is_none());
|
||||
let mut func = func.with_name("add");
|
||||
assert_eq!(func.name().unwrap(), "add");
|
||||
|
||||
let args = ArgList::default().push_owned(25_i32);
|
||||
func.call(args).unwrap();
|
||||
let args = ArgList::default().push_owned(75_i16);
|
||||
func.call(args).unwrap();
|
||||
|
||||
drop(func);
|
||||
assert_eq!(total, 100);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user