Skip to content

Commit

Permalink
playground: implement format function
Browse files Browse the repository at this point in the history
This is ahead of a change that adds the ability to format a tab in the
playground (see cue-lang/cuelang.org#482 for details).

For now we only need to support CUE as a format option. But we
nonetheless support JSON and this is verified by some simple tests.

Signed-off-by: Paul Jolly <[email protected]>
Change-Id: I85aa17fd38ad43c59dea041ef5d7cfea01e3def7
Dispatch-Trailer: {"type":"trybot","CL":1205298,"patchset":4,"ref":"refs/changes/98/1205298/4","targetBranch":"master"}
  • Loading branch information
myitcv authored and cueckoo committed Dec 6, 2024
1 parent 8621a0c commit 49ee059
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 6 deletions.
64 changes: 58 additions & 6 deletions playground/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import (
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/format"
"cuelang.org/go/cue/load"
"cuelang.org/go/cue/parser"
"cuelang.org/go/cue/token"
"cuelang.org/go/pkg/encoding/json"
"github.com/cue-lang/cuelang.org/playground/internal/cuelang_org_go_internal/encoding"
"github.com/cue-lang/cuelang.org/playground/internal/cuelang_org_go_internal/filetypes"
)
Expand All @@ -36,6 +38,7 @@ const (
functionExport function = "export"
functionEval function = "eval"
functionDef function = "def"
functionFmt function = "fmt"
)

type input string
Expand All @@ -57,7 +60,7 @@ const (
func handleCUECompile(in input, fn function, out output, inputVal string) (string, error) {
// TODO implement more functions
switch fn {
case functionExport, functionEval, functionDef:
case functionExport, functionEval, functionDef, functionFmt:
default:
return "", fmt.Errorf("function %q is not implemented", fn)
}
Expand All @@ -67,6 +70,29 @@ func handleCUECompile(in input, fn function, out output, inputVal string) (strin
default:
return "", fmt.Errorf("unknown input type: %v", in)
}

switch out {
case outputCUE, outputJSON, outputYaml:
default:
return "", fmt.Errorf("unknown ouput type: %v", out)
}

if fn == functionFmt {
// For Fmt, we require in and out to be the same.
if in != input(out) {
return "", fmt.Errorf("fmt input output mismatch: input = %q, output = %q", in, out)
}

// Error in case we are trying to format something we can't
switch in {
case inputCUE, inputJSON:
default:
return "", fmt.Errorf("don't (yet) know how to format %q", in)
}

return formatInput(in, inputVal), nil
}

loadCfg := &load.Config{
Stdin: strings.NewReader(inputVal),
Dir: "/",
Expand All @@ -89,11 +115,6 @@ func handleCUECompile(in input, fn function, out output, inputVal string) (strin
if err := v.Err(); err != nil {
return "", fmt.Errorf("failed to build: %w", err)
}
switch out {
case outputCUE, outputJSON, outputYaml:
default:
return "", fmt.Errorf("unknown ouput type: %v", out)
}
cueOpts := []cue.Option{
cue.Docs(true),
cue.Attributes(true),
Expand Down Expand Up @@ -126,6 +147,9 @@ func handleCUECompile(in input, fn function, out output, inputVal string) (strin

// TODO(mvdan): Note that formatOpts appear to do nothing at all.
// For instance, the tests indent JSON with four spaces instead of two.
//
// TODO(myitcv): make the sharing of format options consistent with
// formatInput.
var formatOpts []format.Option
switch out {
case outputCUE:
Expand Down Expand Up @@ -159,3 +183,31 @@ func getSyntax(v cue.Value, opts []cue.Option) *ast.File {
panic("unreachable")
}
}

// formatInput attempts to format s according to the filetype in. On success it
// returns the formatted result, otherwise it returns s. formatInput panics on
// an unsupported in filetype.
func formatInput(in input, s string) string {
switch in {
case inputCUE:
// TODO(myitcv): make the sharing of format options consistent with
// handleCUECompile.
n, err := parser.ParseFile("cue:-", s, parser.ParseComments)
if err != nil {
return s
}
b, err := format.Node(n, format.TabIndent(true))
if err != nil {
return s
}
return string(b)
case inputJSON:
res, err := json.Indent([]byte(s), "", " ")
if err != nil {
return s
}
return res
default:
panic(fmt.Errorf("don't know how to format %q", in))
}
}
36 changes: 36 additions & 0 deletions playground/impl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,42 @@ var testTable = []struct {
"x: {\n\tx2: \"foo\"\n}\ny: x.missing\n",
"",
},

// Simple format checks; no errors
{
inputCUE, functionFmt, outputCUE,
" package foo\n",
"package foo\n",
"",
},
{
inputJSON, functionFmt, outputJSON,

// Preserve double-declaration; this is format-only, not evaluation
"{\n\"x\": 5,\n\"x\": 5\n}\n",
"{\n \"x\": 5,\n \"x\": 5\n}\n",
"",
},

// Error format checks
{
inputCUE, functionFmt, outputCUE,
" {\n",
" {\n",
"",
},
{
inputJSON, functionFmt, outputJSON,
"{\nx: 5\n}\n",
"{\nx: 5\n}\n",
"",
},
{
inputYaml, functionFmt, outputYaml,
"x: 5\n",
"",
"don't (yet) know how to format \"yaml\"",
},
}

func TestHandleCUECompile(t *testing.T) {
Expand Down

0 comments on commit 49ee059

Please sign in to comment.