mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-11 00:40:00 +08:00
(goctl): support nested struct (#4211)
This commit is contained in:
@@ -57,6 +57,8 @@ var (
|
||||
importTwiceApi string
|
||||
//go:embed testdata/another_import_api.api
|
||||
anotherImportApi string
|
||||
//go:embed testdata/example.api
|
||||
exampleApi string
|
||||
)
|
||||
|
||||
func TestParser(t *testing.T) {
|
||||
@@ -316,15 +318,32 @@ func TestCamelStyle(t *testing.T) {
|
||||
validateWithCamel(t, filename, "GoZero")
|
||||
}
|
||||
|
||||
func TestExampleGen(t *testing.T) {
|
||||
env.Set(t, env.GoctlExperimental, env.ExperimentalOn)
|
||||
filename := "greet.api"
|
||||
err := os.WriteFile(filename, []byte(exampleApi), os.ModePerm)
|
||||
assert.Nil(t, err)
|
||||
t.Cleanup(func() {
|
||||
_ = os.Remove(filename)
|
||||
})
|
||||
|
||||
spec, err := parser.Parse(filename)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, len(spec.Types), 10)
|
||||
|
||||
validate(t, filename)
|
||||
}
|
||||
|
||||
func validate(t *testing.T, api string) {
|
||||
validateWithCamel(t, api, "gozero")
|
||||
}
|
||||
|
||||
func validateWithCamel(t *testing.T, api, camel string) {
|
||||
dir := "workspace"
|
||||
defer func() {
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
t.Cleanup(func() {
|
||||
_ = os.RemoveAll(dir)
|
||||
})
|
||||
|
||||
err := pathx.MkdirIfNotExist(dir)
|
||||
assert.Nil(t, err)
|
||||
err = initMod(dir)
|
||||
|
||||
@@ -74,8 +74,21 @@ func writeType(writer io.Writer, tp spec.Type) error {
|
||||
return fmt.Errorf("unspport struct type: %s", tp.Name())
|
||||
}
|
||||
|
||||
fmt.Fprintf(writer, "type %s struct {\n", util.Title(tp.Name()))
|
||||
for _, member := range structType.Members {
|
||||
_, err := fmt.Fprintf(writer, "type %s struct {\n", util.Title(tp.Name()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeMember(writer, structType.Members); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(writer, "}")
|
||||
return err
|
||||
}
|
||||
|
||||
func writeMember(writer io.Writer, members []spec.Member) error {
|
||||
for _, member := range members {
|
||||
if member.IsInline {
|
||||
if _, err := fmt.Fprintf(writer, "%s\n", strings.Title(member.Type.Name())); err != nil {
|
||||
return err
|
||||
@@ -88,6 +101,5 @@ func writeType(writer io.Writer, tp spec.Type) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(writer, "}")
|
||||
return nil
|
||||
}
|
||||
|
||||
99
tools/goctl/api/gogen/testdata/example.api
vendored
Normal file
99
tools/goctl/api/gogen/testdata/example.api
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
syntax = "v1"
|
||||
|
||||
info(
|
||||
title: "demo title"
|
||||
desc: "demo desc"
|
||||
author: "keson.an"
|
||||
date: "2024-06-25"
|
||||
version: "v1"
|
||||
)
|
||||
|
||||
// empty structure
|
||||
type Foo {
|
||||
}
|
||||
|
||||
// type lit
|
||||
type Bar {
|
||||
Foo int `json:"foo"`
|
||||
Bar bool `json:"bar"`
|
||||
Baz []string `json:"baz"`
|
||||
Qux map[string]string `json:"qux"`
|
||||
}
|
||||
|
||||
type Baz {
|
||||
Foo `json:"foo"`
|
||||
// array type
|
||||
Arr [2]int `json:"arr"`
|
||||
// nested type
|
||||
Bar {
|
||||
Foo string `json:"foo"`
|
||||
Bar bool `json:"bar"`
|
||||
Baz {
|
||||
Foo string `json:"foo"`
|
||||
Bar bool `json:"bar"`
|
||||
}
|
||||
Qux {
|
||||
Foo string `json:"foo"`
|
||||
Bar bool `json:"bar"`
|
||||
} `json:"qux"`
|
||||
} `json:"bar"`
|
||||
}
|
||||
|
||||
|
||||
type UpdateReq {
|
||||
Arg1 string `json:"arg1"`
|
||||
}
|
||||
|
||||
type ListItem {
|
||||
Value1 string `json:"value1"`
|
||||
}
|
||||
|
||||
type LoginReq {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type LoginResp {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type FormExampleReq {
|
||||
Name string `form:"name"`
|
||||
}
|
||||
|
||||
type PathExampleReq {
|
||||
ID string `path:"id"`
|
||||
}
|
||||
|
||||
type PathExampleResp {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
@server(
|
||||
jwt: Auth
|
||||
prefix: /v1
|
||||
group: g1
|
||||
timeout: 3s
|
||||
middleware: AuthInterceptor
|
||||
maxBytes: 1048576
|
||||
)
|
||||
service Foo {
|
||||
@handler ping
|
||||
get /ping
|
||||
|
||||
@handler update
|
||||
post /update (UpdateReq)
|
||||
|
||||
@handler list
|
||||
get /list returns ([]ListItem)
|
||||
|
||||
@handler login
|
||||
post /login (LoginReq) returns (LoginResp)
|
||||
|
||||
@handler formExample
|
||||
post /form/example (FormExampleReq)
|
||||
|
||||
@handler pathExample
|
||||
get /path/example/:id (PathExampleReq) returns (PathExampleResp)
|
||||
}
|
||||
|
||||
@@ -59,16 +59,59 @@ func genFile(c fileGenConfig) error {
|
||||
|
||||
func writeProperty(writer io.Writer, name, tag, comment string, tp spec.Type, indent int) error {
|
||||
util.WriteIndent(writer, indent)
|
||||
var err error
|
||||
var (
|
||||
err error
|
||||
isNestedStruct bool
|
||||
)
|
||||
structType, ok := tp.(spec.DefineStruct)
|
||||
if ok && structType.IsNestedStruct() {
|
||||
isNestedStruct = true
|
||||
}
|
||||
if len(comment) > 0 {
|
||||
comment = strings.TrimPrefix(comment, "//")
|
||||
comment = "//" + comment
|
||||
_, err = fmt.Fprintf(writer, "%s %s %s %s\n", strings.Title(name), tp.Name(), tag, comment)
|
||||
} else {
|
||||
_, err = fmt.Fprintf(writer, "%s %s %s\n", strings.Title(name), tp.Name(), tag)
|
||||
}
|
||||
|
||||
return err
|
||||
if isNestedStruct {
|
||||
_, err = fmt.Fprintf(writer, "%s struct {\n", strings.Title(name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeMember(writer, structType.Members); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := fmt.Fprintf(writer, "} %s", tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(comment) > 0 {
|
||||
_, err = fmt.Fprintf(writer, " %s", comment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = fmt.Fprint(writer, "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if len(comment) > 0 {
|
||||
_, err = fmt.Fprintf(writer, "%s %s %s %s\n", strings.Title(name), tp.Name(), tag, comment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
_, err = fmt.Fprintf(writer, "%s %s %s\n", strings.Title(name), tp.Name(), tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getAuths(api *spec.ApiSpec) []string {
|
||||
|
||||
Reference in New Issue
Block a user