Skip to content

Commit 3347302

Browse files
committed
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 <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent f60c88a commit 3347302

File tree

4 files changed

+126
-90
lines changed

4 files changed

+126
-90
lines changed

cue/decode.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2021 CUE Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cue
16+
17+
import (
18+
"encoding/json"
19+
)
20+
21+
// Decode initializes x with Value v. If x is a struct, it will validate the
22+
// constraints specified in the field tags.
23+
func (v Value) Decode(x interface{}) error {
24+
// TODO: optimize
25+
b, err := v.MarshalJSON()
26+
if err != nil {
27+
return err
28+
}
29+
return json.Unmarshal(b, x)
30+
}

cue/decode_test.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright 2021 CUE Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package cue
16+
17+
import (
18+
"reflect"
19+
"testing"
20+
21+
"github.com/google/go-cmp/cmp"
22+
)
23+
24+
func TestDecode(t *testing.T) {
25+
type fields struct {
26+
A int `json:"A"`
27+
B int `json:"B"`
28+
C int `json:"C"`
29+
}
30+
intList := func(ints ...int) *[]int {
31+
ints = append([]int{}, ints...)
32+
return &ints
33+
}
34+
testCases := []struct {
35+
value string
36+
dst interface{}
37+
want interface{}
38+
err string
39+
}{{
40+
value: `_|_`,
41+
err: "explicit error (_|_ literal) in source",
42+
}, {
43+
value: `"str"`,
44+
dst: new(string),
45+
want: "str",
46+
}, {
47+
value: `"str"`,
48+
dst: new(int),
49+
err: "cannot unmarshal string into Go value of type int",
50+
}, {
51+
value: `{}`,
52+
dst: &fields{},
53+
want: fields{},
54+
}, {
55+
value: `{a:1,b:2,c:3}`,
56+
dst: &fields{},
57+
want: fields{A: 1, B: 2, C: 3},
58+
}, {
59+
value: `{for k, v in y if v > 1 {"\(k)": v} }
60+
y: {a:1,b:2,c:3}`,
61+
dst: &fields{},
62+
want: fields{B: 2, C: 3},
63+
}, {
64+
value: `{a:1,b:2,c:int}`,
65+
dst: new(fields),
66+
err: "cannot convert incomplete value",
67+
}, {
68+
value: `[]`,
69+
dst: intList(),
70+
want: *intList(),
71+
}, {
72+
value: `[1,2,3]`,
73+
dst: intList(),
74+
want: *intList(1, 2, 3),
75+
}, {
76+
value: `[for x in #y if x > 1 { x }]
77+
#y: [1,2,3]`,
78+
dst: intList(),
79+
want: *intList(2, 3),
80+
}, {
81+
value: `[int]`,
82+
err: "cannot convert incomplete value",
83+
}}
84+
for _, tc := range testCases {
85+
t.Run(tc.value, func(t *testing.T) {
86+
err := getInstance(t, tc.value).Value().Decode(tc.dst)
87+
checkFatal(t, err, tc.err, "init")
88+
89+
got := reflect.ValueOf(tc.dst).Elem().Interface()
90+
if !cmp.Equal(got, tc.want) {
91+
t.Error(cmp.Diff(got, tc.want))
92+
t.Errorf("\n%#v\n%#v", got, tc.want)
93+
}
94+
})
95+
}
96+
}

cue/types.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,22 +1016,6 @@ outer:
10161016
}
10171017
}
10181018

1019-
// Decode initializes x with Value v. If x is a struct, it will validate the
1020-
// constraints specified in the field tags.
1021-
func (v Value) Decode(x interface{}) error {
1022-
// TODO: optimize
1023-
b, err := v.MarshalJSON()
1024-
if err != nil {
1025-
return err
1026-
}
1027-
return json.Unmarshal(b, x)
1028-
}
1029-
1030-
// // EncodeJSON generates JSON for the given value.
1031-
// func (v Value) EncodeJSON(w io.Writer, v Value) error {
1032-
// return nil
1033-
// }
1034-
10351019
// Doc returns all documentation comments associated with the field from which
10361020
// the current value originates.
10371021
func (v Value) Doc() []*ast.CommentGroup {

cue/types_test.go

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,80 +1976,6 @@ func TestEquals(t *testing.T) {
19761976
}
19771977
}
19781978

1979-
func TestDecode(t *testing.T) {
1980-
type fields struct {
1981-
A int `json:"A"`
1982-
B int `json:"B"`
1983-
C int `json:"C"`
1984-
}
1985-
intList := func(ints ...int) *[]int {
1986-
ints = append([]int{}, ints...)
1987-
return &ints
1988-
}
1989-
testCases := []struct {
1990-
value string
1991-
dst interface{}
1992-
want interface{}
1993-
err string
1994-
}{{
1995-
value: `_|_`,
1996-
err: "explicit error (_|_ literal) in source",
1997-
}, {
1998-
value: `"str"`,
1999-
dst: new(string),
2000-
want: "str",
2001-
}, {
2002-
value: `"str"`,
2003-
dst: new(int),
2004-
err: "cannot unmarshal string into Go value of type int",
2005-
}, {
2006-
value: `{}`,
2007-
dst: &fields{},
2008-
want: fields{},
2009-
}, {
2010-
value: `{a:1,b:2,c:3}`,
2011-
dst: &fields{},
2012-
want: fields{A: 1, B: 2, C: 3},
2013-
}, {
2014-
value: `{for k, v in y if v > 1 {"\(k)": v} }
2015-
y: {a:1,b:2,c:3}`,
2016-
dst: &fields{},
2017-
want: fields{B: 2, C: 3},
2018-
}, {
2019-
value: `{a:1,b:2,c:int}`,
2020-
dst: new(fields),
2021-
err: "cannot convert incomplete value",
2022-
}, {
2023-
value: `[]`,
2024-
dst: intList(),
2025-
want: *intList(),
2026-
}, {
2027-
value: `[1,2,3]`,
2028-
dst: intList(),
2029-
want: *intList(1, 2, 3),
2030-
}, {
2031-
value: `[for x in #y if x > 1 { x }]
2032-
#y: [1,2,3]`,
2033-
dst: intList(),
2034-
want: *intList(2, 3),
2035-
}, {
2036-
value: `[int]`,
2037-
err: "cannot convert incomplete value",
2038-
}}
2039-
for _, tc := range testCases {
2040-
t.Run(tc.value, func(t *testing.T) {
2041-
err := getInstance(t, tc.value).Value().Decode(tc.dst)
2042-
checkFatal(t, err, tc.err, "init")
2043-
2044-
got := reflect.ValueOf(tc.dst).Elem().Interface()
2045-
if !cmp.Equal(got, tc.want) {
2046-
t.Error(cmp.Diff(got, tc.want))
2047-
t.Errorf("\n%#v\n%#v", got, tc.want)
2048-
}
2049-
})
2050-
}
2051-
}
2052-
20531979
// TODO: options: disallow cycles.
20541980
func TestValidate(t *testing.T) {
20551981
testCases := []struct {

0 commit comments

Comments
 (0)