Open jpluscplusm opened 4 months ago
Alternative version using FillPath
:
go mod tidy
go run .
cmp stdout stdout.golden
-- go.mod --
module mod.example
go 1.22.3
require cuelang.org/go v0.9.0
-- main.go --
package main
import (
"fmt"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
)
func main() {
ctx := cuecontext.New()
v := ctx.CompileString(`
Ref!: _
x: "\(Ref.Val)/gg"
`)
v = v.FillPath(cue.MakePath(cue.Str("Ref")), map[string]string{"Val": "test"})
fmt.Printf("%v\n", v)
}
-- stdout.golden --
{
Ref: {
Val: "test"
}
x: "test/gg"
}
Slack thread: https://cuelang.slack.com/archives/CLT3ULF6C/p1716865650006559
Thread content
#### OP my expectation was that fill path would do unification .. i am starting to think that i am missing something about escaping that string but not sure. ```go package main import ( "fmt" "testing" ) func lokkupPath(value cue.Value, path string) (cue.Value, error) { var val cue.Value fieldValue := value.LookupPath(cue.ParsePath(path)) if !fieldValue.Exists() || fieldValue.Kind() == cue.BottomKind { return val, ErrInvalidReference } return fieldValue, nil } func TestFillPath(t *testing.T) { tmap := map[string]any{ "xx": "\\(Ref.Val)/xx", "yy": "\\(Ref.Val)/yy", } cctx := cuecontext.New() code := cctx.Encode(tmap) // fmt.Println(code) codeval := code.FillPath(cue.ParsePath("Ref"), struct { Val string }{ Val: "test", }) // fmt.Println(codeval) xx, err := lokkupPath(codeval, "xx") if err != nil { t.Errorf("failed") } fmt.Println("xx", xx) } // ---- output // xx "\\(Ref.Val)/xx" // PASS ``` #### Reply I think what you are actually after is CompileString. At least I hope the following example makes the distinction between cue.Context.Encode and cue.Context.CompileString clear ```txtar go mod tidy go run . cmp stdout stdout.golden -- go.mod -- module mod.example go 1.22.3 require cuelang.org/go v0.9.0 -- main.go -- package main import ( "fmt" "cuelang.org/go/cue/cuecontext" ) func main() { ctx := cuecontext.New() tmap := map[string]any{ "Ref": struct { Val string }{ Val: "test", }, } // Use cue.Context.Encode to convert a Go value to // CUE data. Note that the Go value can contain // cue.Value values. tmapValue := ctx.Encode(tmap) // Use cue.Context.CompileString to compile some CUE derived := ctx.CompileString(` Ref: _ x: "\(Ref.Val)/gg" `) // Use cue.Value.Unify to unify res := tmapValue.Unify(derived) fmt.Printf("%v\n", res) } -- stdout.golden -- { Ref: { Val: "test" } x: "test/gg" } ``` If you use cue.Context.Encode on a Go value, then the resulting cue.Value will be just data Hence your expectation of a reference ("\(Ref.Val)") resolving is not correct. But as you can see, you can use a combination of various techniques to give you a variety of cue.Value's, and "glue" them together using cue.Value.Unify