Function evaluate

Source
pub fn evaluate<'s, 'e, 'r, R>(
    source: &'s str,
    args: impl IntoIterator<Item = i32>,
    environment: impl IntoIterator<Item = (&'e str, i32)>,
    rng: &'r mut R,
) -> Result<Evaluation, EvaluationError<'s>>
where R: Rng + ?Sized, 'e: 's,
Expand description

Evaluate the dice expression using the given arguments, environment, and pseudo-random number generator (pRNG). Missing external variables default to zero during evaluation, but all parameters must be bound. Optimize the function using the standard optimizer.

This is a one-shot convenience function that compiles and evaluates the dice expression in a single step. If you need to evaluate the same dice expression multiple times, consider compiling the function once and reusing it with the Evaluator type.

§Parameters

  • source: The source code to compile and evaluate.
  • args: The arguments to the function.
  • environment: The environment in which to evaluate the function, as a vector of external variable bindings. The bindings are pairs of variable names and values. Missing bindings default to zero.
  • rng: The pseudo-random number generator to use for range and dice rolls.

§Returns

The result of the evaluation.

§Errors

  • CompilationFailed if the function could not be compiled.
  • BadArity if the number of arguments provided disagrees with the number of formal parameters in the function signature.
  • UnrecognizedExternal if an external variable is not recognized.

§Examples

Roll one standard six-sided die:

use xdy::evaluate;
use rand::rng;

let result = evaluate("1D6", vec![], vec![], &mut rng()).unwrap();
assert!(1 <= result.result && result.result <= 6);
assert!(result.records.len() == 1);
assert!(result.records[0].results.len() == 1);
assert!(1 <= result.records[0].results[0] && result.records[0].results[0] <= 6);

Roll a variable number of dice, using an argument named x to supply the number of dice to roll:

use xdy::evaluate;
use rand::rng;

let result =
    evaluate("x: {x}D6", vec![3], vec![], &mut rng()).unwrap();
assert!(3 <= result.result && result.result <= 18);
assert!(result.records.len() == 1);
assert!(result.records[0].results.len() == 3);
assert!(1 <= result.records[0].results[0] && result.records[0].results[0] <= 6);
assert!(1 <= result.records[0].results[1] && result.records[0].results[1] <= 6);
assert!(1 <= result.records[0].results[2] && result.records[0].results[2] <= 6);

Roll a variable number of dice, using an external variable named x to supply the number of dice to roll:

use xdy::evaluate;
use rand::rng;

let result =
    evaluate("{x}D6", vec![], vec![("x", 3)], &mut rng()).unwrap();
assert!(3 <= result.result && result.result <= 18);
assert!(result.records.len() == 1);
assert!(result.records[0].results.len() == 3);
assert!(1 <= result.records[0].results[0] && result.records[0].results[0] <= 6);
assert!(1 <= result.records[0].results[1] && result.records[0].results[1] <= 6);
assert!(1 <= result.records[0].results[2] && result.records[0].results[2] <= 6);

Evaluate an arithmetic expression involving different types of dice:

use xdy::evaluate;
use rand::rng;

let result = evaluate("1D6 + 2D8 - 1D10", vec![], vec![], &mut rng()).unwrap();
assert!(-7 <= result.result && result.result <= 21);
assert!(result.records.len() == 3);
assert!(result.records[0].results.len() == 1);
assert!(result.records[1].results.len() == 2);
assert!(result.records[2].results.len() == 1);
assert!(1 <= result.records[0].results[0] && result.records[0].results[0] <= 6);
assert!(1 <= result.records[1].results[0] && result.records[1].results[0] <= 8);
assert!(1 <= result.records[1].results[1] && result.records[1].results[1] <= 8);
assert!(1 <= result.records[2].results[0] && result.records[2].results[0] <= 10);