Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Configuration

Customize evaluation behavior with EvaluationConfig and the EngineBuilder.

Creating a Configured Engine

#![allow(unused)]
fn main() {
use datalogic_rs::{Engine, EvaluationConfig, NanHandling};

// Default configuration
let engine = Engine::new();

// Custom configuration
let config = EvaluationConfig {
    arithmetic_nan_handling: NanHandling::IgnoreValue,
    ..Default::default()
};
let engine = Engine::builder().with_config(config).build();
}

v5 dropped the inherent Engine::with_config / with_preserve_structure / with_config_and_structure constructors — use the builder. There is no compatibility shim. See the Migration Guide for the v4 → v5 mapping.

Configuration Options

EvaluationConfig is a plain struct — set fields directly with struct update syntax:

#![allow(unused)]
fn main() {
use datalogic_rs::{EvaluationConfig, NanHandling, DivisionByZeroHandling};

let config = EvaluationConfig {
    arithmetic_nan_handling: NanHandling::IgnoreValue,
    division_by_zero: DivisionByZeroHandling::ReturnNull,
    loose_equality_errors: false,
    ..Default::default()
};
}

NaN Handling

Control how non-numeric values are handled in arithmetic operations.

#![allow(unused)]
fn main() {
use datalogic_rs::{EvaluationConfig, NanHandling};

// ThrowError (default), IgnoreValue, CoerceToZero, ReturnNull
let config = EvaluationConfig {
    arithmetic_nan_handling: NanHandling::IgnoreValue,
    ..Default::default()
};
}

Behavior comparison for {"+": [1, "text", 2]}:

SettingResult
ThrowError (default)Err(Thrown { type: "NaN" })
IgnoreValue3 (skips "text")
CoerceToZero3 ("text"0)
ReturnNullnull

Division by Zero

#![allow(unused)]
fn main() {
use datalogic_rs::{EvaluationConfig, DivisionByZeroHandling};

// ReturnSaturated (default), ThrowError, ReturnNull, ReturnInfinity
let config = EvaluationConfig {
    division_by_zero: DivisionByZeroHandling::ThrowError,
    ..Default::default()
};
}

Behavior comparison for {"/": [10, 0]}:

SettingResult
ReturnSaturated (default)f64::MAX (sign of dividend)
ThrowErrorErr(Thrown { type: "NaN" })
ReturnNullnull
ReturnInfinityInfinity (sign of dividend)

Truthiness Evaluation

#![allow(unused)]
fn main() {
use std::sync::Arc;
use datalogic_rs::{EvaluationConfig, TruthyEvaluator};
use datalogic_rs::datavalue::OwnedDataValue;

// JavaScript (default), Python, StrictBoolean, Custom
let config = EvaluationConfig {
    truthy_evaluator: TruthyEvaluator::Python,
    ..Default::default()
};

// Custom truthy: receives an OwnedDataValue (no serde_json required)
let custom = Arc::new(|value: &OwnedDataValue| -> bool {
    value.as_f64().map_or(false, |n| n > 0.0)
});
let config = EvaluationConfig {
    truthy_evaluator: TruthyEvaluator::Custom(custom),
    ..Default::default()
};
}

v5 change: TruthyEvaluator::Custom now takes Arc<dyn Fn(&OwnedDataValue) -> bool + Send + Sync> (the canonical owned value type). v4 used &serde_json::Value.

Truthiness comparison:

ValueJavaScriptPythonStrictBoolean
truetruthytruthytruthy
falsefalsyfalsyfalsy
1truthytruthyfalsy
0falsyfalsyfalsy
""falsyfalsyfalsy
"0"truthytruthyfalsy
[]falsyfalsyfalsy
[0]truthytruthyfalsy
nullfalsyfalsyfalsy

Loose Equality Errors

Control whether loose equality (==) raises errors for incompatible types.

#![allow(unused)]
fn main() {
let config = EvaluationConfig {
    loose_equality_errors: true,   // default
    ..Default::default()
};
}

Numeric Coercion

#![allow(unused)]
fn main() {
use datalogic_rs::{EvaluationConfig, NumericCoercionConfig};

let config = EvaluationConfig {
    numeric_coercion: NumericCoercionConfig {
        empty_string_to_zero: false,
        null_to_zero: false,
        bool_to_number: false,
        reject_non_numeric: true,
        undefined_to_zero: false,
    },
    ..Default::default()
};
}

Configuration Presets

#![allow(unused)]
fn main() {
use datalogic_rs::{Engine, EvaluationConfig};

// Lenient arithmetic — IgnoreValue + ReturnNull divide-by-zero
let engine = Engine::builder()
    .with_config(EvaluationConfig::safe_arithmetic())
    .build();

// Strict — errors for any type mismatch and no numeric coercion
let engine = Engine::builder()
    .with_config(EvaluationConfig::strict())
    .build();
}

Combining with Templating Mode

Use both configuration and templating mode (requires feature = "templating"):

#![allow(unused)]
fn main() {
let config = EvaluationConfig {
    arithmetic_nan_handling: NanHandling::CoerceToZero,
    ..Default::default()
};

let engine = Engine::builder()
    .with_config(config)
    .with_templating(true)
    .build();
}

Configuration Examples

Lenient Data Processing

#![allow(unused)]
fn main() {
let config = EvaluationConfig {
    arithmetic_nan_handling: NanHandling::IgnoreValue,
    division_by_zero: DivisionByZeroHandling::ReturnNull,
    ..Default::default()
};

let engine = Engine::builder().with_config(config).build();

let r = engine.eval_str(
    r#"{"+": [1, "not a number", null, 2]}"#,
    r#"{}"#,
).unwrap();
// "3" (ignores non-numeric values)
}

Strict Validation

#![allow(unused)]
fn main() {
let engine = Engine::builder()
    .with_config(EvaluationConfig::strict())
    .build();

let result = engine.eval_str(r#"{"+": [1, "2"]}"#, r#"{}"#);
// Err(...) — strict mode does not coerce "2" to a number
}

Custom Business Logic Truthiness

#![allow(unused)]
fn main() {
use std::sync::Arc;
use datalogic_rs::datavalue::OwnedDataValue;

let custom_truthy = Arc::new(|value: &OwnedDataValue| -> bool {
    match value {
        OwnedDataValue::Bool(b) => *b,
        OwnedDataValue::Number(_) => value.as_f64().map_or(false, |n| n > 0.0),
        OwnedDataValue::String(s) => !s.is_empty(),
        _ => false,
    }
});

let config = EvaluationConfig {
    truthy_evaluator: TruthyEvaluator::Custom(custom_truthy),
    ..Default::default()
};

let engine = Engine::builder().with_config(config).build();
// {"if": [0,  "yes", "no"]}  ⇒ "no"
// {"if": [-5, "yes", "no"]}  ⇒ "no"
// {"if": [1,  "yes", "no"]}  ⇒ "yes"
}