Skip to main content

Module function

Module function 

Source
Expand description

Functions that can be used during the evaluation of an Expression.

An Engine holds all of the functions that can be executed by an Expression. Engine::default() intializes all of the functions from the standard.

If, however, you need to add new functions or change how existing functions work, that is also possible.

§Defining new functions

Definining a new function involves creating a struct that implements Function and then adding it to an engine.

use std::borrow::Cow;
use serde_json::{json, Value};
use rets_expression::{Engine, Expression, EvaluateContext};
use rets_expression::function::{Function, FunctionError, FunctionContext};

/// A function that takes the square root of a value.
struct Sqrt;

impl<T> Function<T> for Sqrt {
    fn evaluate<'json>(
        &self,
        _context: FunctionContext<'_, T>,
        input: Vec<Cow<'json, Value>>,
    ) -> Result<Cow<'json, Value>, FunctionError> {
        if input.len() != 1 {
            return Err(FunctionError::UnexpectedNumberOfArguments);
        }

        let Some(value) = input.get(0).and_then(|value| value.as_f64()) else {
            return Err(FunctionError::InvalidType);
        };

        let sqrt = value.sqrt();

        Ok(Cow::Owned(json!(sqrt)))
    }
}

// Add the function to the engine
let mut engine = Engine::default();
engine.set_function("SQRT", Box::new(Sqrt));

// Parse an expression that uses the function
let expression = "SQRT(9.0)".parse::<Expression>().unwrap();

// And execute it
let value = json!({});
let context = EvaluateContext::new(&engine, &value);
let result = expression.apply(context).unwrap();

assert_eq!(result.into_owned(), json!(3.0));

§Defining new functions that use state

In some cases, you may need to store state between expression evaluations, or provide state between function calls.

For these cases, EvaluateContext::new_with_state can be used to seed the EvaluateContext with state, and FunctionContext::state/FunctionContext::state_mut can be used to access state from within a function.

use std::borrow::Cow;
use serde_json::{json, Value};
use rets_expression::{Engine, Expression, EvaluateContext};
use rets_expression::function::{Function, FunctionError, FunctionContext};

/// The engine state used for the `TODAY` function call.
struct MyState {
    today: String,
}

/// A new implementation of the `TODAY` function.
struct OverriddenToday;

impl Function<MyState> for OverriddenToday {
    fn evaluate<'json>(
        &self,
        context: FunctionContext<'_, MyState>,
        input: Vec<Cow<'json, Value>>,
    ) -> Result<Cow<'json, Value>, FunctionError> {
        let state = context.state();
        let today = state.today.clone();

        Ok(Cow::Owned(json!(today)))
    }
}

// Add the function to the engine
let mut engine = Engine::default();
engine.set_function("TODAY", Box::new(OverriddenToday));

// Parse an expression that uses the function
let expression = ".TODAY.".parse::<Expression>().unwrap();

let value = json!({});

// And execute it
let state = MyState { today: String::from("2023-04-21") };
let context = EvaluateContext::new_with_state(&engine, &value, state);
let result = expression.apply(context).unwrap();

assert_eq!(result.into_owned(), json!("2023-04-21"));

// And execute it with different state
let state = MyState { today: String::from("2023-07-31") };
let context = EvaluateContext::new_with_state(&engine, &value, state);
let result = expression.apply(context).unwrap();

assert_eq!(result.into_owned(), json!("2023-07-31"));

Structs§

BoolFunction
Default implementation for the standard BOOL function
CharFunction
Default implementation for the standard CHAR function
CharfFunction
Default implementation for the standard CHARF function
DateFunction
Default implementation for the standard DATE function
DayFunction
Default implementation for the standard DAY function
DifferenceFunction
Default implementation for the standard DIFFERENCE function
FloatFunction
Default implementation for the standard FLOAT function
FunctionContext
The context that a function is run in
IntFunction
Default implementation for the standard INT function
IntersectionFunction
Default implementation for the standard INTERSECTION function
LengthFunction
Default implementation for the standard LENGTH function
ListFunction
Default implementation for the standard LIST function
LowerFunction
Default implementation for the standard LOWER function
MatchFunction
Default implementation for the standard MATCH function
MonthFunction
Default implementation for the standard MONTH function
NowFunction
Default implementation for the standard NOW function
SetFunction
Default implementation for the standard SET function
StrlenFunction
Default implementation for the standard STRLEN function
SubstrFunction
Default implementation for the standard SUBSTR function
TimeFunction
Default implementation for the standard TIME function
TodayFunction
Default implementation for the standard TODAY function
TypeofFunction
Default implementation for the standard TYPEOF function
UnionFunction
Default implementation for the standard UNION function
UpperFunction
Default implementation for the standard UPPER function
WeekdayFunction
Default implementation for the standard WEEKDAY function
YearFunction
Default implementation for the standard YEAR function

Enums§

FunctionError
An error that can be thrown by a function

Traits§

Function
The trait that defines the evaluation of a function