mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-19 04:26:39 +00:00
Feat: support nullable option (#5736)
Signed-off-by: iyear <ljyngup@gmail.com>
This commit is contained in:
@@ -93,11 +93,16 @@ func (g *Generator) convert(typ gotypes.Type) (cueast.Expr, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cueast.BinaryExpr{
|
||||
X: cueast.NewNull(),
|
||||
Op: cuetoken.OR,
|
||||
Y: expr,
|
||||
}, nil
|
||||
|
||||
// generate null enum for pointer type
|
||||
if g.opts.nullable {
|
||||
return &cueast.BinaryExpr{
|
||||
X: cueast.NewNull(),
|
||||
Op: cuetoken.OR,
|
||||
Y: expr,
|
||||
}, nil
|
||||
}
|
||||
return expr, nil
|
||||
case *gotypes.Slice:
|
||||
if t.Elem().String() == "byte" {
|
||||
return ident("bytes", false), nil
|
||||
|
||||
@@ -63,3 +63,16 @@ func TestConvertInvalid(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertNullable(t *testing.T) {
|
||||
g, err := NewGenerator("testdata/nullable.go")
|
||||
assert.NoError(t, err)
|
||||
|
||||
got := &bytes.Buffer{}
|
||||
assert.NoError(t, g.Generate(got, WithNullable()))
|
||||
|
||||
want, err := os.ReadFile("testdata/nullable.cue")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, got.String(), string(want))
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package cuegen
|
||||
|
||||
type options struct {
|
||||
anyTypes map[string]struct{}
|
||||
nullable bool
|
||||
}
|
||||
|
||||
var defaultOptions = &options{
|
||||
@@ -25,6 +26,7 @@ var defaultOptions = &options{
|
||||
"map[string]interface{}": {}, "map[string]any": {},
|
||||
"interface{}": {}, "any": {},
|
||||
},
|
||||
nullable: false,
|
||||
}
|
||||
|
||||
// Option is a function that configures generation options
|
||||
@@ -42,3 +44,10 @@ func WithAnyTypes(types ...string) Option {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithNullable will generate null enum for pointer type
|
||||
func WithNullable() Option {
|
||||
return func(opts *options) {
|
||||
opts.nullable = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,10 +47,29 @@ func TestWithAnyTypes(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
opts := options{map[string]struct{}{}}
|
||||
opts := options{anyTypes: map[string]struct{}{}}
|
||||
for _, opt := range tt.opts {
|
||||
opt(&opts)
|
||||
}
|
||||
assert.Equal(t, opts.anyTypes, tt.extra, tt.name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithNullable(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
opts []Option
|
||||
want bool
|
||||
}{
|
||||
{name: "default", opts: nil, want: false},
|
||||
{name: "true", opts: []Option{WithNullable()}, want: true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
opts := options{nullable: false}
|
||||
for _, opt := range tt.opts {
|
||||
opt(&opts)
|
||||
}
|
||||
assert.Equal(t, opts.nullable, tt.want, tt.name)
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package testdata
|
||||
|
||||
Nullable: {
|
||||
field1?: null | string
|
||||
field2?: null | int
|
||||
field3?: null | bool
|
||||
Field4: null | {
|
||||
field1: null | string
|
||||
field2: null | int
|
||||
field3: null | bool
|
||||
}
|
||||
field5?: null | [...string]
|
||||
field6?: null | [...int]
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright 2023 The KubeVela 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 testdata
|
||||
|
||||
type Nullable struct {
|
||||
Field1 *string `json:"field1,omitempty"`
|
||||
Field2 *int `json:"field2,omitempty"`
|
||||
Field3 *bool `json:"field3,omitempty"`
|
||||
Field4 *struct {
|
||||
Field1 *string `json:"field1"`
|
||||
Field2 *int `json:"field2"`
|
||||
Field3 *bool `json:"field3"`
|
||||
}
|
||||
Field5 *[]string `json:"field5,omitempty"`
|
||||
Field6 *[]int `json:"field6,omitempty"`
|
||||
}
|
||||
Vendored
+2
-2
@@ -52,7 +52,7 @@ AnonymousField: SmallStruct: {
|
||||
field1: string
|
||||
field2: string
|
||||
}
|
||||
ReferenceField: field1: null | {
|
||||
ReferenceField: field1: {
|
||||
field1: string
|
||||
field2: string
|
||||
}
|
||||
@@ -61,7 +61,7 @@ StructField: {
|
||||
field1: string
|
||||
field2: string
|
||||
}
|
||||
field2: null | {
|
||||
field2: {
|
||||
field1: string
|
||||
field2: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user