pub struct FnWrapper<T, F, const CTX: bool = false> { /* private fields */ }
Expand description

Wrapper of a function containing information about its arguments.

Using FnWrapper allows to define native functions with minimum boilerplate and with increased type safety. FnWrappers can be constructed explicitly or indirectly via Environment::insert_wrapped_fn(), Value::wrapped_fn(), or wrap().

Arguments of a wrapped function must implement TryFromValue trait for the applicable grammar, and the output type must implement IntoEvalResult. If you need CallContext (e.g., to call functions provided as an argument), it should be specified as a first argument.

Examples

Basic function

use arithmetic_eval::{fns, Environment, ExecutableModule, Value};

let max = fns::wrap(|x: f32, y: f32| if x > y { x } else { y });

let program = "max(1, 3) == 3 && max(-1, -3) == -1";
let program = Untyped::<F32Grammar>::parse_statements(program)?;
let module = ExecutableModule::new("test_max", &program)?;

let mut env = Environment::new();
env.insert_native_fn("max", max);
assert_eq!(module.with_env(&env)?.run()?, Value::Bool(true));

Fallible function with complex args

fn zip_arrays(xs: Vec<f32>, ys: Vec<f32>) -> Result<Vec<(f32, f32)>, String> {
    if xs.len() == ys.len() {
        Ok(xs.into_iter().zip(ys).map(|(x, y)| (x, y)).collect())
    } else {
        Err("Arrays must have the same size".to_owned())
    }
}

let program = "zip((1, 2, 3), (4, 5, 6)) == ((1, 4), (2, 5), (3, 6))";
let program = Untyped::<F32Grammar>::parse_statements(program)?;
let module = ExecutableModule::new("test_zip", &program)?;

let mut env = Environment::new();
env.insert_wrapped_fn("zip", zip_arrays);
assert_eq!(module.with_env(&env)?.run()?, Value::Bool(true));

Using CallContext to call functions

fn map_array(
    context: &mut CallContext<'_, f32>,
    array: Vec<Value<f32>>,
    map_fn: Function<f32>,
) -> Result<Vec<Value<f32>>, Error> {
    array
        .into_iter()
        .map(|value| {
            let arg = context.apply_call_location(value);
            map_fn.evaluate(vec![arg], context)
        })
        .collect()
}

let program = "map((1, 2, 3), |x| x + 3) == (4, 5, 6)";
let module = Untyped::<F32Grammar>::parse_statements(program)?;
let module = ExecutableModule::new("test", &module)?;

let mut env = Environment::new();
env.insert_wrapped_fn("map", map_array);
assert_eq!(module.with_env(&env)?.run()?, Value::Bool(true));

Implementations§

source§

impl<T, F, const CTX: bool> FnWrapper<T, F, CTX>

source

pub const fn new(function: F) -> Self

Creates a new wrapper.

Note that the created wrapper is not guaranteed to be usable as NativeFn. For this to be the case, function needs to be a function or an Fn closure, and the T type argument needs to be a tuple with the function return type and the argument types (in this order).

Trait Implementations§

source§

impl<T, F: Clone, const CTX: bool> Clone for FnWrapper<T, F, CTX>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T, F, const CTX: bool> Debug for FnWrapper<T, F, CTX>where F: Debug,

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<Num, F, Ret> NativeFn<Num> for FnWrapper<(Ret,), F, false>where F: Fn() -> Ret, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret> NativeFn<Num> for FnWrapper<(Ret,), F, true>where F: Fn(&mut CallContext<'_, Num>) -> Ret, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T> NativeFn<Num> for FnWrapper<(Ret, T), F, false>where F: Fn(T) -> Ret, T: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T> NativeFn<Num> for FnWrapper<(Ret, T), F, true>where F: Fn(&mut CallContext<'_, Num>, T) -> Ret, T: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U> NativeFn<Num> for FnWrapper<(Ret, T, U), F, false>where F: Fn(T, U) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U> NativeFn<Num> for FnWrapper<(Ret, T, U), F, true>where F: Fn(&mut CallContext<'_, Num>, T, U) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V> NativeFn<Num> for FnWrapper<(Ret, T, U, V), F, false>where F: Fn(T, U, V) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V> NativeFn<Num> for FnWrapper<(Ret, T, U, V), F, true>where F: Fn(&mut CallContext<'_, Num>, T, U, V) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W), F, false>where F: Fn(T, U, V, W) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W), F, true>where F: Fn(&mut CallContext<'_, Num>, T, U, V, W) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X), F, false>where F: Fn(T, U, V, W, X) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X), F, true>where F: Fn(&mut CallContext<'_, Num>, T, U, V, W, X) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X, Y> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X, Y), F, false>where F: Fn(T, U, V, W, X, Y) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Y: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X, Y> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X, Y), F, true>where F: Fn(&mut CallContext<'_, Num>, T, U, V, W, X, Y) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Y: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X, Y, Z> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X, Y, Z), F, false>where F: Fn(T, U, V, W, X, Y, Z) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Y: TryFromValue<Num>, Z: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X, Y, Z> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X, Y, Z), F, true>where F: Fn(&mut CallContext<'_, Num>, T, U, V, W, X, Y, Z) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Y: TryFromValue<Num>, Z: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X, Y, Z, A> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X, Y, Z, A), F, false>where F: Fn(T, U, V, W, X, Y, Z, A) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Y: TryFromValue<Num>, Z: TryFromValue<Num>, A: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X, Y, Z, A> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X, Y, Z, A), F, true>where F: Fn(&mut CallContext<'_, Num>, T, U, V, W, X, Y, Z, A) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Y: TryFromValue<Num>, Z: TryFromValue<Num>, A: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X, Y, Z, A, B> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X, Y, Z, A, B), F, false>where F: Fn(T, U, V, W, X, Y, Z, A, B) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Y: TryFromValue<Num>, Z: TryFromValue<Num>, A: TryFromValue<Num>, B: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X, Y, Z, A, B> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X, Y, Z, A, B), F, true>where F: Fn(&mut CallContext<'_, Num>, T, U, V, W, X, Y, Z, A, B) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Y: TryFromValue<Num>, Z: TryFromValue<Num>, A: TryFromValue<Num>, B: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X, Y, Z, A, B, C> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X, Y, Z, A, B, C), F, false>where F: Fn(T, U, V, W, X, Y, Z, A, B, C) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Y: TryFromValue<Num>, Z: TryFromValue<Num>, A: TryFromValue<Num>, B: TryFromValue<Num>, C: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<Num, F, Ret, T, U, V, W, X, Y, Z, A, B, C> NativeFn<Num> for FnWrapper<(Ret, T, U, V, W, X, Y, Z, A, B, C), F, true>where F: Fn(&mut CallContext<'_, Num>, T, U, V, W, X, Y, Z, A, B, C) -> Ret, T: TryFromValue<Num>, U: TryFromValue<Num>, V: TryFromValue<Num>, W: TryFromValue<Num>, X: TryFromValue<Num>, Y: TryFromValue<Num>, Z: TryFromValue<Num>, A: TryFromValue<Num>, B: TryFromValue<Num>, C: TryFromValue<Num>, Ret: IntoEvalResult<Num>,

source§

fn evaluate( &self, args: Vec<SpannedValue<Num>>, context: &mut CallContext<'_, Num> ) -> EvalResult<Num>

Executes the function on the specified arguments.
source§

impl<T, F: Copy, const CTX: bool> Copy for FnWrapper<T, F, CTX>

Auto Trait Implementations§

§

impl<T, F, const CTX: bool> RefUnwindSafe for FnWrapper<T, F, CTX>where F: RefUnwindSafe, T: RefUnwindSafe,

§

impl<T, F, const CTX: bool> Send for FnWrapper<T, F, CTX>where F: Send, T: Send,

§

impl<T, F, const CTX: bool> Sync for FnWrapper<T, F, CTX>where F: Sync, T: Sync,

§

impl<T, F, const CTX: bool> Unpin for FnWrapper<T, F, CTX>where F: Unpin, T: Unpin,

§

impl<T, F, const CTX: bool> UnwindSafe for FnWrapper<T, F, CTX>where F: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.