Skip to content

Commit 2b56c50

Browse files
committed
pkg/encoding/toml: add new builtin package for encoding/toml
With just Marshal and Unmarshal for now; validation APIs will follow, as their semantics don't seem consistent between json and yaml. Leave a TODO to come back to the validation APIs as well. We add some txtar tests as well, driven by pkg/internal/builtintest. Fixes #3344. Signed-off-by: Daniel Martí <[email protected]> Change-Id: I5cd4c01ab39daa4a208afcd8c3303f5f8d4ef512 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1201474 TryBot-Result: CUEcueckoo <[email protected]> Reviewed-by: Roger Peppe <[email protected]>
1 parent 9583e29 commit 2b56c50

File tree

5 files changed

+276
-0
lines changed

5 files changed

+276
-0
lines changed

pkg/encoding/toml/manual.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2024 The 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 toml
16+
17+
import (
18+
"bytes"
19+
"strings"
20+
21+
"cuelang.org/go/cue"
22+
"cuelang.org/go/cue/ast"
23+
"cuelang.org/go/encoding/toml"
24+
)
25+
26+
// Marshal returns the TOML encoding of v.
27+
func Marshal(v cue.Value) (string, error) {
28+
if err := v.Validate(cue.Concrete(true)); err != nil {
29+
return "", err
30+
}
31+
var b strings.Builder
32+
if err := toml.NewEncoder(&b).Encode(v); err != nil {
33+
return "", err
34+
}
35+
return b.String(), nil
36+
}
37+
38+
// Unmarshal parses the TOML to a CUE expression.
39+
func Unmarshal(data []byte) (ast.Expr, error) {
40+
return toml.NewDecoder("", bytes.NewReader(data)).Decode()
41+
}
42+
43+
// TODO(mvdan): add Validate too, but which semantics? encoding/json and encoding/yaml do not seem to agree.

pkg/encoding/toml/pkg.go

+42
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
-- in.cue --
2+
import "encoding/toml"
3+
4+
marshal: {
5+
_input: {
6+
rootKey: r1: "foo"
7+
rootKeys: {
8+
r1: "foo"
9+
r2: "bar"
10+
r3: "baz"
11+
}
12+
rootKeysDots: {
13+
a1: "foo"
14+
b1: b2: "bar"
15+
c1: c2: c3: "baz"
16+
}
17+
subtables: {
18+
tables: [
19+
{table1: "foo"},
20+
{table2: "bar"},
21+
{subtable: {sub1: "baz"}}
22+
]
23+
}
24+
complexKeys: "123-456": " foo bar ": "value"
25+
defaults: key: string | *"default"
26+
27+
failIncomplete: key: string | "nondefault"
28+
failRequired: key!: "foo"
29+
}
30+
for name, value in _input {
31+
output: (name): toml.Marshal(value)
32+
}
33+
}
34+
35+
unmarshal: {
36+
_input: {
37+
rootKeysDots: """
38+
a1 = "A"
39+
b1.b2 = "B"
40+
c1.c2.c3 = "C"
41+
"""
42+
subtables: """
43+
[[tables]]
44+
table1 = 'foo'
45+
[[tables]]
46+
table2 = 'bar'
47+
[[tables]]
48+
[tables.subtable]
49+
sub1 = 'baz'
50+
"""
51+
complexKeys: """
52+
[123-456]
53+
' foo bar ' = 'value'
54+
"""
55+
defaultEmpty: string | *""
56+
57+
failIncomplete: string | ""
58+
failBadSyntax: """
59+
= "no key name"
60+
"""
61+
failDuplicate: """
62+
foo = "same key"
63+
foo = "same key"
64+
"""
65+
}
66+
for name, value in _input {
67+
output: (name): toml.Unmarshal(value)
68+
}
69+
}
70+
71+
-- out/toml --
72+
Errors:
73+
unmarshal.output.failBadSyntax: error in call to encoding/toml.Unmarshal: invalid character at start of key: =:
74+
./in.cue:66:19
75+
1:1
76+
unmarshal.output.failDuplicate: error in call to encoding/toml.Unmarshal: duplicate key: foo:
77+
./in.cue:66:19
78+
2:1
79+
80+
Result:
81+
import "encoding/toml"
82+
83+
marshal: {
84+
output: {
85+
rootKey: """
86+
r1 = 'foo'
87+
88+
"""
89+
rootKeys: """
90+
r1 = 'foo'
91+
r2 = 'bar'
92+
r3 = 'baz'
93+
94+
"""
95+
rootKeysDots: """
96+
a1 = 'foo'
97+
98+
[b1]
99+
b2 = 'bar'
100+
101+
[c1]
102+
[c1.c2]
103+
c3 = 'baz'
104+
105+
"""
106+
subtables: """
107+
[[tables]]
108+
table1 = 'foo'
109+
110+
[[tables]]
111+
table2 = 'bar'
112+
113+
[[tables]]
114+
[tables.subtable]
115+
sub1 = 'baz'
116+
117+
"""
118+
complexKeys: """
119+
[123-456]
120+
' foo bar ' = 'value'
121+
122+
"""
123+
defaults: """
124+
key = 'default'
125+
126+
"""
127+
failIncomplete: toml.Marshal(value)
128+
failRequired: toml.Marshal(value)
129+
}
130+
}
131+
unmarshal: {
132+
output: {
133+
rootKeysDots: {
134+
a1: "A"
135+
b1: {
136+
b2: "B"
137+
}
138+
c1: {
139+
c2: {
140+
c3: "C"
141+
}
142+
}
143+
}
144+
subtables: {
145+
tables: [{
146+
table1: "foo"
147+
}, {
148+
table2: "bar"
149+
}, {
150+
subtable: {
151+
sub1: "baz"
152+
}
153+
}]
154+
}
155+
complexKeys: {
156+
"123-456": {
157+
" foo bar ": "value"
158+
}
159+
}
160+
defaultEmpty: {}
161+
failIncomplete: toml.Unmarshal(value)
162+
failBadSyntax: _|_ // unmarshal.output.failBadSyntax: error in call to encoding/toml.Unmarshal: invalid character at start of key: =
163+
failDuplicate: _|_ // unmarshal.output.failDuplicate: error in call to encoding/toml.Unmarshal: duplicate key: foo
164+
}
165+
}

pkg/encoding/toml/toml_test.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2024 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 toml_test
16+
17+
import (
18+
"testing"
19+
20+
"cuelang.org/go/pkg/internal/builtintest"
21+
)
22+
23+
func TestBuiltin(t *testing.T) {
24+
builtintest.Run("toml", t)
25+
}

pkg/register.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)