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_structureconstructors — 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]}:
| Setting | Result |
|---|---|
ThrowError (default) | Err(Thrown { type: "NaN" }) |
IgnoreValue | 3 (skips "text") |
CoerceToZero | 3 ("text" → 0) |
ReturnNull | null |
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]}:
| Setting | Result |
|---|---|
ReturnSaturated (default) | f64::MAX (sign of dividend) |
ThrowError | Err(Thrown { type: "NaN" }) |
ReturnNull | null |
ReturnInfinity | Infinity (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::Customnow takesArc<dyn Fn(&OwnedDataValue) -> bool + Send + Sync>(the canonical owned value type). v4 used&serde_json::Value.
Truthiness comparison:
| Value | JavaScript | Python | StrictBoolean |
|---|---|---|---|
true | truthy | truthy | truthy |
false | falsy | falsy | falsy |
1 | truthy | truthy | falsy |
0 | falsy | falsy | falsy |
"" | falsy | falsy | falsy |
"0" | truthy | truthy | falsy |
[] | falsy | falsy | falsy |
[0] | truthy | truthy | falsy |
null | falsy | falsy | falsy |
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"
}