cue-lang / docs-and-content

A place to discuss, plan, and track documentation on cuelang.org
5 stars 1 forks source link

docs/howto: Validating and transforming Go data with CUE(?) #121

Open jpluscplusm opened 2 months ago

jpluscplusm commented 2 months ago

In https://cuelang.slack.com/archives/CLT3ULF6C/p1710191048140359, a user asked about a way to use Go to

This is very similar to the use case demonstrated in the not-yet-live https://cl-1190655-7--cue-cls.netlify.app/docs/concept/how-cue-works-with-go/#checking-go-data-with-cue-schema, but is different enough that it warrants a standalone page.

@myitcv proposed this, based on the user's constraints and an example they posted:

go mod tidy
go run .
cmp stdout stdout.golden

-- cue.mod/module.cue --
module: "mod.com"
language: {
    version: "v0.8.1"
}
-- go.mod --
module mod.example

go 1.22.1

require cuelang.org/go v0.8.1

-- main.go --
package main

import (
    "fmt"

    "cuelang.org/go/cue"
    "cuelang.org/go/cue/cuecontext"
    "cuelang.org/go/cue/load"
)

type params struct {
    Foo       string `json:"foo"`
    Bar       int    `json:"bar"`
    FirstName string `json:"firstName"`
    LastName  string ` json:"lastName"`
}

func main() {
    ctx := cuecontext.New()

    // Load CUE package from the current directory
    bps := load.Instances([]string{"."}, nil)
    v := ctx.BuildInstance(bps[0])

    p := params{
        Foo:       "foo",
        Bar:       42,
        FirstName: "CUE",
        LastName:  "Cueckoo",
    }

    // Fill in the _params field
    paramsPath := cue.MakePath(cue.Hid("_params", "mod.com:example"))
    res := v.FillPath(paramsPath, p)

    // Lookup the value of appConfig
    appConfigPath := cue.ParsePath("appConfig")
    appConfig := res.LookupPath(appConfigPath)

    fmt.Printf("%v\n", appConfig)
}
-- source.cue --
package example

_params: {
    foo:       string
    bar:       int & >0
    firstName: string
    lastName:  string
}

appConfig: {
    someConfigItem: _params.foo
    fullName:       "\(_params.firstName) \(_params.lastName)"
}
-- stdout.golden --
{
    someConfigItem: "foo"
    fullName:       "CUE Cueckoo"
}

We might want to include a failing test, either on the page or behind the scenes.