cmd/cue/cmd: allow decoding JSON Schema and OpenAPI
Also added a test to ensure that format simplification
is not triggered inadventendly with this change.
Issue #56
Change-Id: Ie925de45a1cfe95f05f922dd04c47d0a8b42dd6c
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5252
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/internal/encoding/encoding.go b/internal/encoding/encoding.go
index f6187e8..83de8a3 100644
--- a/internal/encoding/encoding.go
+++ b/internal/encoding/encoding.go
@@ -22,6 +22,7 @@
"fmt"
"io"
"io/ioutil"
+ "net/url"
"os"
"strings"
@@ -33,6 +34,8 @@
"cuelang.org/go/cue/parser"
"cuelang.org/go/cue/token"
"cuelang.org/go/encoding/json"
+ "cuelang.org/go/encoding/jsonschema"
+ "cuelang.org/go/encoding/openapi"
"cuelang.org/go/encoding/protobuf"
"cuelang.org/go/internal/filetypes"
"cuelang.org/go/internal/third_party/yaml"
@@ -171,6 +174,39 @@
return i
}
+ switch f.Interpretation {
+ case "":
+ case build.OpenAPI:
+ i.interpret = func(i *cue.Instance) (file *ast.File, id string, err error) {
+ cfg := &openapi.Config{PkgName: cfg.PkgName}
+ file, err = simplify(openapi.Extract(i, cfg))
+ return file, "", err
+ }
+ case build.JSONSchema:
+ i.interpret = func(i *cue.Instance) (file *ast.File, id string, err error) {
+ id = f.Tags["id"]
+ if id == "" {
+ id, _ = i.Lookup("$id").String()
+ }
+ if id != "" {
+ u, err := url.Parse(id)
+ if err != nil {
+ return nil, "", errors.Wrapf(err, token.NoPos, "invalid id")
+ }
+ u.Scheme = ""
+ id = strings.TrimPrefix(u.String(), "//")
+ }
+ cfg := &jsonschema.Config{
+ ID: id,
+ PkgName: cfg.PkgName,
+ }
+ file, err = simplify(jsonschema.Extract(i, cfg))
+ return file, id, err
+ }
+ default:
+ i.err = fmt.Errorf("unsupported interpretation %q", f.Interpretation)
+ }
+
path := f.Filename
switch f.Encoding {
case build.CUE:
@@ -341,3 +377,19 @@
}
return ok
}
+
+// simplify reformats a File. To be used as a wrapper for Extract functions.
+//
+// It currently does so by formatting the file using fmt.Format and then
+// reparsing it. This is not ideal, but the package format does not provide a
+// way to do so differently.
+func simplify(f *ast.File, err error) (*ast.File, error) {
+ if err != nil {
+ return nil, err
+ }
+ b, err := format.Node(f, format.Simplify())
+ if err != nil {
+ return nil, err
+ }
+ return parser.ParseFile(f.Filename, b, parser.ParseComments)
+}