Evaluate(opts ...Option), similar to Validate and Syntax
Is your feature request related to a problem? Please describe.
I'd like to be able to process a Value with Options like Validate & Syntax, but get a Value back.
Describe the solution you'd like
Value.Evaluate(opts ...Option) Value which has the same interface as Validate & Syntax
Describe alternatives you've considered
- Using
Syntaxand then processing that withcue.Context.BuildExpr. - Custom walk with
Fields(opts), this seems like what Evaluate would be close too
It is always good to have a concrete example to which one can ground such requests.
Something like the last set of bullet points in the questions here: https://github.com/cue-lang/cue/discussions/1329
But that I may want to progressively fill and resolve references for a subset of the fields. This could be useful in something like Dagger or where a CUE Value is used by a program that interacts with the outside world.
Maybe having something like the UnifyAccept second parameter that acts like a mask for which fields to consider? (If I am understanding that param correctly)
Arriving here via https://github.com/cue-lang/cue/discussions/1329#discussioncomment-1556815, per @mpvl in https://github.com/cue-lang/cue/issues/1327#issuecomment-951831172 I think we need a more comprehensive use case to help drive the design here. Pseudo code in particular helps to visualise the solution.
I'll work on some examples, I'm assuming there is no rush on this.
I'd argue that users may find intriguing use cases if such a function did exist.
... and currently there isn't a Value function which can return a new Value after running the evaluator with a given set of Option. We have Syntax() ast.Node and Validate() err, so Evaluate() Value would fit nicely. I think one could ctx.BuildExpr(val.Syntax(myOpts...)) today to get the effect of a Value.Evaluate(myOpts...)?
I'm assuming there is no rush on this.
Correct.
@myitcv we should probably consolidate the Evaluate(...Option) discussion here (so it doesn't keep spilling over into #1326 )
package main
import (
"fmt"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
)
const input = `
a: {
i: int
j: int | *i
}
`
func main() {
c := cuecontext.New()
val := c.CompileString(input)
fmt.Println("\noriginal\n===============")
val.Walk(func(v cue.Value) bool {
fmt.Printf("\n%# v\n", v)
return true
}, nil)
val = val.FillPath(cue.ParsePath("a.i"), 42)
fmt.Println("\nfilled\n===============")
val.Walk(func(v cue.Value) bool {
fmt.Printf("\n%# v\n", v)
return true
}, nil)
//
// This would be equivalent to the lines after
//
// val.Evaluate(cue.Final(), cue.Concrete(true))
a := val.Syntax(cue.Final(), cue.Concrete(true))
val = c.BuildExpr(a.(ast.Expr))
fmt.Println("\nfinal\n===============")
val.Walk(func(v cue.Value) bool {
fmt.Printf("\n%# v\n", v)
return true
}, nil)
}
Gives
original
===============
a: {
i: int
j: int | *i
}
i: int
j: int | *i
int
int | *i
filled
===============
a: {
i: 42
j: int | *i
}
i: 42
j: int | *i
42
int | *i
final
===============
a: {
i: 42
j: 42
}
i: 42
j: 42
42
42
Tony Worm suggested that I include my use case here.
I'm dynamically combining several sources of configuration and wanted a way to be able to display the effective configuration to users. To accomplish this, I'm currently using value.Syntax(cue.Final()) which is fine as the very next thing I do is format.Node. However, my unified configurations are fairly large, and so users may reasonably wish to print only a particular path (and indeed some convenience commands in my CLI offer this). With an AST, I have two choices: 1) use LookupPath etc first, then call .Syntax or 2) Call .Syntax first, then round-trip to a Value or JSON and query that. I'm now doing (1) and it is fine, but it wasn't what I was initially expecting. It's a little bit annoying because there isn't a single codepath where I extract paths. As a result, each codepath that extracts a value path must call .Syntax(Final()) itself. My initial expectation was that I would have been able to do: final := value.Eval(Final()) or similar up front in a central place.