cue: move Decode to separate file
This prepares for a complete rewrite.
Change-Id: I13126a97c5899d3492b296fc0bd9082d32f923f0
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9521
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/decode.go b/cue/decode.go
new file mode 100644
index 0000000..c27bd02
--- /dev/null
+++ b/cue/decode.go
@@ -0,0 +1,30 @@
+// Copyright 2021 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cue
+
+import (
+ "encoding/json"
+)
+
+// Decode initializes x with Value v. If x is a struct, it will validate the
+// constraints specified in the field tags.
+func (v Value) Decode(x interface{}) error {
+ // TODO: optimize
+ b, err := v.MarshalJSON()
+ if err != nil {
+ return err
+ }
+ return json.Unmarshal(b, x)
+}
diff --git a/cue/decode_test.go b/cue/decode_test.go
new file mode 100644
index 0000000..f3d43ea
--- /dev/null
+++ b/cue/decode_test.go
@@ -0,0 +1,96 @@
+// Copyright 2021 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cue
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestDecode(t *testing.T) {
+ type fields struct {
+ A int `json:"A"`
+ B int `json:"B"`
+ C int `json:"C"`
+ }
+ intList := func(ints ...int) *[]int {
+ ints = append([]int{}, ints...)
+ return &ints
+ }
+ testCases := []struct {
+ value string
+ dst interface{}
+ want interface{}
+ err string
+ }{{
+ value: `_|_`,
+ err: "explicit error (_|_ literal) in source",
+ }, {
+ value: `"str"`,
+ dst: new(string),
+ want: "str",
+ }, {
+ value: `"str"`,
+ dst: new(int),
+ err: "cannot unmarshal string into Go value of type int",
+ }, {
+ value: `{}`,
+ dst: &fields{},
+ want: fields{},
+ }, {
+ value: `{a:1,b:2,c:3}`,
+ dst: &fields{},
+ want: fields{A: 1, B: 2, C: 3},
+ }, {
+ value: `{for k, v in y if v > 1 {"\(k)": v} }
+ y: {a:1,b:2,c:3}`,
+ dst: &fields{},
+ want: fields{B: 2, C: 3},
+ }, {
+ value: `{a:1,b:2,c:int}`,
+ dst: new(fields),
+ err: "cannot convert incomplete value",
+ }, {
+ value: `[]`,
+ dst: intList(),
+ want: *intList(),
+ }, {
+ value: `[1,2,3]`,
+ dst: intList(),
+ want: *intList(1, 2, 3),
+ }, {
+ value: `[for x in #y if x > 1 { x }]
+ #y: [1,2,3]`,
+ dst: intList(),
+ want: *intList(2, 3),
+ }, {
+ value: `[int]`,
+ err: "cannot convert incomplete value",
+ }}
+ for _, tc := range testCases {
+ t.Run(tc.value, func(t *testing.T) {
+ err := getInstance(t, tc.value).Value().Decode(tc.dst)
+ checkFatal(t, err, tc.err, "init")
+
+ got := reflect.ValueOf(tc.dst).Elem().Interface()
+ if !cmp.Equal(got, tc.want) {
+ t.Error(cmp.Diff(got, tc.want))
+ t.Errorf("\n%#v\n%#v", got, tc.want)
+ }
+ })
+ }
+}
diff --git a/cue/types.go b/cue/types.go
index 009a179..f2b2b09 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -1016,22 +1016,6 @@
}
}
-// Decode initializes x with Value v. If x is a struct, it will validate the
-// constraints specified in the field tags.
-func (v Value) Decode(x interface{}) error {
- // TODO: optimize
- b, err := v.MarshalJSON()
- if err != nil {
- return err
- }
- return json.Unmarshal(b, x)
-}
-
-// // EncodeJSON generates JSON for the given value.
-// func (v Value) EncodeJSON(w io.Writer, v Value) error {
-// return nil
-// }
-
// Doc returns all documentation comments associated with the field from which
// the current value originates.
func (v Value) Doc() []*ast.CommentGroup {
diff --git a/cue/types_test.go b/cue/types_test.go
index d5d613a..1768baa 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -1976,80 +1976,6 @@
}
}
-func TestDecode(t *testing.T) {
- type fields struct {
- A int `json:"A"`
- B int `json:"B"`
- C int `json:"C"`
- }
- intList := func(ints ...int) *[]int {
- ints = append([]int{}, ints...)
- return &ints
- }
- testCases := []struct {
- value string
- dst interface{}
- want interface{}
- err string
- }{{
- value: `_|_`,
- err: "explicit error (_|_ literal) in source",
- }, {
- value: `"str"`,
- dst: new(string),
- want: "str",
- }, {
- value: `"str"`,
- dst: new(int),
- err: "cannot unmarshal string into Go value of type int",
- }, {
- value: `{}`,
- dst: &fields{},
- want: fields{},
- }, {
- value: `{a:1,b:2,c:3}`,
- dst: &fields{},
- want: fields{A: 1, B: 2, C: 3},
- }, {
- value: `{for k, v in y if v > 1 {"\(k)": v} }
- y: {a:1,b:2,c:3}`,
- dst: &fields{},
- want: fields{B: 2, C: 3},
- }, {
- value: `{a:1,b:2,c:int}`,
- dst: new(fields),
- err: "cannot convert incomplete value",
- }, {
- value: `[]`,
- dst: intList(),
- want: *intList(),
- }, {
- value: `[1,2,3]`,
- dst: intList(),
- want: *intList(1, 2, 3),
- }, {
- value: `[for x in #y if x > 1 { x }]
- #y: [1,2,3]`,
- dst: intList(),
- want: *intList(2, 3),
- }, {
- value: `[int]`,
- err: "cannot convert incomplete value",
- }}
- for _, tc := range testCases {
- t.Run(tc.value, func(t *testing.T) {
- err := getInstance(t, tc.value).Value().Decode(tc.dst)
- checkFatal(t, err, tc.err, "init")
-
- got := reflect.ValueOf(tc.dst).Elem().Interface()
- if !cmp.Equal(got, tc.want) {
- t.Error(cmp.Diff(got, tc.want))
- t.Errorf("\n%#v\n%#v", got, tc.want)
- }
- })
- }
-}
-
// TODO: options: disallow cycles.
func TestValidate(t *testing.T) {
testCases := []struct {