pub struct Evaluator<Ref, Value> { /* private fields */ }Expand description
A generic evaluator that evaluates modules of type Value.
This evaluator can be used to decouple the way modules are read from the way they are evaluated. It follows design paradigms of the “sans-io” pattern.
This evaluator does not do anything on its own, it needs external code to “drive” it. Something like an “event loop”.
let mut evaluator = Evaluator::new();
evaluator.import("module 1");
while let Some(this) = evaluator.next() {
println!("evaluating {this}...");
// Read the value of the module here from the filesystem, network,
// environment, etc.
let value: i32 = unimplemented!();
// Resolve what other modules this module wants to import. This is also
// specific to how you read a module. For example, it could be the
// top-level "imports" array of the JSON file.
let imports = unimplemented!();
evaluator.eval(this, imports, value).unwrap();
}
let value = evaluator.finish().unwrap();
println!("final value: {value}");This pattern allows you to implement whatever kind of module logic you want inside the loop without modifying the evaluator.
Implementations§
Source§impl<Ref, Value> Evaluator<Ref, Value>
impl<Ref, Value> Evaluator<Ref, Value>
Sourcepub fn import<I>(&mut self, imports: I)
pub fn import<I>(&mut self, imports: I)
Specify additional imports to be evaluated.
This function is usually only used to provide the first module.
Source§impl<Ref, Value> Evaluator<Ref, Value>where
Ref: Display,
impl<Ref, Value> Evaluator<Ref, Value>where
Ref: Display,
Sourcepub fn trace(&self, this: Ref) -> Trace
pub fn trace(&self, this: Ref) -> Trace
Build the module trace for this module.
This function can be used to attach a module trace to module::Error
on any user-thrown errors during the evaluation loop.
§Example
use module::Error;
let mut evaluator = Evaluator::new();
evaluator.import("module 1");
while let Some(this) = evaluator.next() {
// ...
if this == "module 2" {
return Err(Error::custom("module 2 is not allowed to be evaluated"))
.with_trace(|| evaluator.trace(this));
}
// ...
evaluator.eval(this, imports, value)?;
}
let value = evaluator.finish().unwrap();
Ok(value)Source§impl<Ref, Value> Evaluator<Ref, Value>
impl<Ref, Value> Evaluator<Ref, Value>
Sourcepub fn eval(
&mut self,
this: Ref,
imports: Imports<Ref>,
value: Value,
) -> Result<()>
pub fn eval( &mut self, this: Ref, imports: Imports<Ref>, value: Value, ) -> Result<()>
Evaluate the module this.
imports: any modulesthisimportsvalue: the value of thethismodule
Returns the result of the Merge operation on value. The returned
error has the appropriate trace attached.
See: Evaluator::trace.