OPA conformance (#71)

- Remove unnecessary memory allocations
- Add --non-strict flag
- Ensure that only empty modules (ones without rules) are initialzed prior to evaluating rules.
- Record rule as entry for each of its prefixes.
  For example, for a rule a.b.c =... in package test, record it in
  rules["data.test.a"], rules["data.test.a.b"] and rules["data.test.a.b.c"]

  This allows evaluating the correct list of rules based on expessions
  a.b.c, a.b, a, data.test.a.b.c, data.test.a.b, data.test.a

Closes #69
Closes #70

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
Anand Krishnamoorthi
2023-12-23 11:55:25 -08:00
committed by GitHub
parent ad3282caf4
commit e61b406547
11 changed files with 201 additions and 139 deletions

View File

@@ -121,10 +121,10 @@ impl Engine {
self.prepare_for_eval(enable_tracing)?;
self.interpreter.clean_internal_evaluation_state();
// Ensure that each module has an empty object
for m in &self.modules {
// Ensure that empty modules are created.
for m in self.modules.iter().filter(|m| m.policy.is_empty()) {
let path = Parser::get_path_ref_components(&m.package.refr)?;
let path: Vec<&str> = path.iter().map(|s| *s.text()).collect();
let path: Vec<&str> = path.iter().map(|s| s.text()).collect();
let vref =
Interpreter::make_or_get_value_mut(self.interpreter.get_data_mut(), &path[..])?;
if *vref == Value::Undefined {
@@ -147,6 +147,16 @@ impl Engine {
self.interpreter.set_current_module(prev_module)?;
}
// Ensure that all modules are created.
for m in &self.modules {
let path = Parser::get_path_ref_components(&m.package.refr)?;
let path: Vec<&str> = path.iter().map(|s| s.text()).collect();
let vref =
Interpreter::make_or_get_value_mut(self.interpreter.get_data_mut(), &path[..])?;
if *vref == Value::Undefined {
*vref = Value::new_object();
}
}
self.interpreter.create_rule_prefixes()?;
Ok(self.interpreter.get_data_mut().clone())
}