this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

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í <mvdan@mvdan.cc>
Change-Id: I5cd4c01ab39daa4a208afcd8c3303f5f8d4ef512
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1201474
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>

+276
+43
pkg/encoding/toml/manual.go
··· 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.
+42
pkg/encoding/toml/pkg.go
··· 1 + // Code generated by cuelang.org/go/pkg/gen. DO NOT EDIT. 2 + 3 + package toml 4 + 5 + import ( 6 + "cuelang.org/go/internal/core/adt" 7 + "cuelang.org/go/internal/pkg" 8 + ) 9 + 10 + func init() { 11 + pkg.Register("encoding/toml", p) 12 + } 13 + 14 + var _ = adt.TopKind // in case the adt package isn't used 15 + 16 + var p = &pkg.Package{ 17 + Native: []*pkg.Builtin{{ 18 + Name: "Marshal", 19 + Params: []pkg.Param{ 20 + {Kind: adt.TopKind}, 21 + }, 22 + Result: adt.StringKind, 23 + Func: func(c *pkg.CallCtxt) { 24 + v := c.Value(0) 25 + if c.Do() { 26 + c.Ret, c.Err = Marshal(v) 27 + } 28 + }, 29 + }, { 30 + Name: "Unmarshal", 31 + Params: []pkg.Param{ 32 + {Kind: adt.BytesKind | adt.StringKind}, 33 + }, 34 + Result: adt.TopKind, 35 + Func: func(c *pkg.CallCtxt) { 36 + data := c.Bytes(0) 37 + if c.Do() { 38 + c.Ret, c.Err = Unmarshal(data) 39 + } 40 + }, 41 + }}, 42 + }
+165
pkg/encoding/toml/testdata/marshal.txtar
··· 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 + }
+25
pkg/encoding/toml/toml_test.go
··· 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 + }
+1
pkg/register.go
··· 13 13 _ "cuelang.org/go/pkg/encoding/csv" 14 14 _ "cuelang.org/go/pkg/encoding/hex" 15 15 _ "cuelang.org/go/pkg/encoding/json" 16 + _ "cuelang.org/go/pkg/encoding/toml" 16 17 _ "cuelang.org/go/pkg/encoding/yaml" 17 18 _ "cuelang.org/go/pkg/html" 18 19 _ "cuelang.org/go/pkg/list"