feat: Evaluate JSON Pointers in Policy Expressions #418
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Relates to #371
Description
This PR replaces the previous preprocessor-based implementation of JSON Pointers with one that natively runs in the Policy Expression
Executor
.It replaces the
context
parameter onrun()
andparse_and_eval()
with a new field on theEnv
struct. Now, calling code must pass the JSON context while creating theEnv
.It also fixes a bug that the previous version had but which was hidden by the intermediate step of serializing to text: numbers in the JSON that could be represented as integers were being forced to
f64
. This is a problem for Policy Expressions, which distinguishes between Ints and Floats and does not currently have any casting or conversion between them. Since the previous version went through Rust's native printing off64
, and that printing code will display a float without a decimal point if it is exactly equal to an integer, the bug did not manifest.This version goes directly from the
Expr
returned byjson_to_policy_expr()
to theExecutor
, so it includes a fix to returnPrimitive::Int
values where appropriate.Feedback requested
Env
struct contain the JSONcontext
data? I considered an approach where thecontext
value is passed around separately from theEnv
, but it would get messy quickly due to all the operators needing to pass it around. It seems mostly natural to me to put in theEnv
, except that the context is effectively a global variable. It doesn't interact with the lexical scoping (should it?), so this PR currently just clones the JSON when a childEnv
is created.Env
struct own or borrow the context? This version has an owned copy for simplicity. The only issue I see with borrowing it is needing to add another lifetime parameter toEnv
, which is manageable.Env
should own a copy ofcontext
: shouldEnv::child()
pass a reference instead of a clone? I considered usingRc<Box<Value>>
to keep one shared version of the context, but I wasn't sure if it was worth the trouble.context
parameter toExecutor::std()
? Should theExecutor
be built or used in a different way?