diff --git a/tools/goctl/api/spec/example_test.go b/tools/goctl/api/spec/example_test.go new file mode 100644 index 00000000..eaa1651d --- /dev/null +++ b/tools/goctl/api/spec/example_test.go @@ -0,0 +1,15 @@ +package spec_test + +import ( + "fmt" + "github.com/zeromicro/go-zero/tools/goctl/api/spec" +) + +func ExampleMember_GetEnumOptions() { + member := spec.Member{ + Tag: `json:"foo,options=foo|bar|options|123"`, + } + fmt.Println(member.GetEnumOptions()) + // Output: + // [foo bar options 123] +} diff --git a/tools/goctl/api/spec/fn.go b/tools/goctl/api/spec/fn.go index 8821b3a7..d208a8c2 100644 --- a/tools/goctl/api/spec/fn.go +++ b/tools/goctl/api/spec/fn.go @@ -154,6 +154,27 @@ func (m Member) IsTagMember(tagKey string) bool { return false } +// GetEnumOptions return a slice contains all enumeration options +func (m Member) GetEnumOptions() []string { + if !m.IsBodyMember() { + return nil + } + + tags := m.Tags() + for _, tag := range tags { + if tag.Key == bodyTagKey { + options := tag.Options + for _, option := range options { + if strings.Index(option, "options=") == 0 { + option = strings.TrimPrefix(option, "options=") + return strings.Split(option, "|") + } + } + } + } + return nil +} + // GetBodyMembers returns all json fields func (t DefineStruct) GetBodyMembers() []Member { var result []Member diff --git a/tools/goctl/api/tsgen/util.go b/tools/goctl/api/tsgen/util.go index 27c230d9..5d211717 100644 --- a/tools/goctl/api/tsgen/util.go +++ b/tools/goctl/api/tsgen/util.go @@ -19,7 +19,7 @@ const ( func writeProperty(writer io.Writer, member spec.Member, indent int) error { writeIndent(writer, indent) - ty, err := goTypeToTs(member.Type, false) + ty, err := genTsType(member) if err != nil { return err } @@ -52,6 +52,19 @@ func writeIndent(writer io.Writer, indent int) { } } +func genTsType(m spec.Member) (ty string, err error) { + ty, err = goTypeToTs(m.Type, false) + if enums := m.GetEnumOptions(); enums != nil { + if ty == "string" { + for i := range enums { + enums[i] = "'" + enums[i] + "'" + } + } + ty = strings.Join(enums, " | ") + } + return +} + func goTypeToTs(tp spec.Type, fromPacket bool) (string, error) { switch v := tp.(type) { case spec.DefineStruct: diff --git a/tools/goctl/api/tsgen/util_test.go b/tools/goctl/api/tsgen/util_test.go new file mode 100644 index 00000000..de11800b --- /dev/null +++ b/tools/goctl/api/tsgen/util_test.go @@ -0,0 +1,38 @@ +package tsgen + +import ( + "github.com/stretchr/testify/assert" + "github.com/zeromicro/go-zero/tools/goctl/api/spec" + "testing" +) + +func TestGenTsType(t *testing.T) { + member := spec.Member{ + Name: "foo", + Type: spec.PrimitiveType{RawName: "string"}, + Tag: `json:"foo,options=foo|bar|options|123"`, + Comment: "", + Docs: nil, + IsInline: false, + } + ty, err := genTsType(member) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, `'foo' | 'bar' | 'options' | '123'`, ty) + + member.IsInline = true + ty, err = genTsType(member) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, `'foo' | 'bar' | 'options' | '123'`, ty) + + member.Type = spec.PrimitiveType{RawName: "int"} + member.Tag = `json:"foo,options=1|3|4|123"` + ty, err = genTsType(member) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, `1 | 3 | 4 | 123`, ty) +}