From 67f38778dbfbf97ab2268e7519b3947987525f66 Mon Sep 17 00:00:00 2001 From: alovn Date: Sun, 8 May 2022 08:01:52 +0800 Subject: [PATCH] feat: response replace field --- examples/docs/apis-greeter.md | 28 +++++++++++----- examples/docs/apis-hello.md | 4 +-- examples/docs/apis-ungrouped.md | 2 +- examples/main.go | 8 ++--- gen/template/group_apis.tpl | 5 ++- operation.go | 59 +++++++++++++++++++++++++-------- parser.go | 4 +++ spec.go | 11 ++++-- 8 files changed, 87 insertions(+), 34 deletions(-) diff --git a/examples/docs/apis-greeter.md b/examples/docs/apis-greeter.md index 44cf369..477ee36 100644 --- a/examples/docs/apis-greeter.md +++ b/examples/docs/apis-greeter.md @@ -9,18 +9,31 @@ greeter分组说明 ```text GET /greeter ``` +**Response**: - -Response: ```json // 输出对象 dd -// HTTP StatusCode: 200 +// StatusCode: 200 // object main { "code": 0, // int, 返回状态码 "msg": "返回消息", // string, 返回文本消息 - "data": nil // any, 返回的具体数据 + "data": { + "my_title": "example" // string, 标题 + } +} +``` + +```json + +// 出错了 +// StatusCode: 500 +// object main +{ + "data": null, // any, 返回的具体数据 + "code": 10010, // int, 返回状态码 + "msg": "异常" // string, 返回文本消息 } ``` @@ -30,16 +43,15 @@ Response: ```text GET /greeter2 ``` +**Response**: - -Response: ```json // 输出对象 dd -// HTTP StatusCode: 200 +// StatusCode: 200 // object main { - "my_title": "" + "my_title": "example" // string, 标题 } ``` diff --git a/examples/docs/apis-hello.md b/examples/docs/apis-hello.md index 4a45baf..984683f 100644 --- a/examples/docs/apis-hello.md +++ b/examples/docs/apis-hello.md @@ -9,7 +9,7 @@ ```text GET /hello ``` - +**Response**: ### 测试hello2 @@ -17,5 +17,5 @@ GET /hello ```text GET /hello2 ``` - +**Response**: diff --git a/examples/docs/apis-ungrouped.md b/examples/docs/apis-ungrouped.md index 74b1395..0e71e9a 100644 --- a/examples/docs/apis-ungrouped.md +++ b/examples/docs/apis-ungrouped.md @@ -9,5 +9,5 @@ Ungrouped apis ```text GET /other ``` - +**Response**: diff --git a/examples/main.go b/examples/main.go index 8822480..6238fc5 100644 --- a/examples/main.go +++ b/examples/main.go @@ -23,8 +23,8 @@ type Response struct { Msg string `json:"msg,omitempty" example:"返回消息"` //返回文本消息 Data interface{} `json:"data,omitempty"` //返回的具体数据 } -type TestData struct { - MyTitle string `json:"my_title,omitempty"` +type TestData struct { //测试数据 + MyTitle string `json:"my_title,omitempty"` //标题 } type Request struct { @@ -39,8 +39,8 @@ type Request struct { //@group greeter //@accept json //@request Request -//@response1 200 Response{data=TestData} 输出对象 dd -//@response 200 Response 输出对象 dd +//@response 200 Response{data=TestData} 输出对象 dd +//@response 500 Response{code=10010,msg="异常"} 出错了 func greet() { var msg = "Hello World!" fmt.Println(msg) diff --git a/gen/template/group_apis.tpl b/gen/template/group_apis.tpl index 758d7e5..ed9203c 100644 --- a/gen/template/group_apis.tpl +++ b/gen/template/group_apis.tpl @@ -11,13 +11,12 @@ author: {{$v.Author}} ```text {{$v.HTTPMethod}} {{$v.Api}} ``` - +**Response**: {{range $res := $v.Responses}} -Response: ```json {{if $res.Description}} // {{$res.Description}}{{end}} -// HTTP StatusCode: {{$res.StatusCode}} +// StatusCode: {{$res.StatusCode}} {{$res.Examples}} ``` {{end}} diff --git a/operation.go b/operation.go index 29f9191..d1caf5d 100644 --- a/operation.go +++ b/operation.go @@ -10,7 +10,8 @@ import ( var ( // 200 Response{data=Data} examples - responsePattern = regexp.MustCompile(`^(\d+)\s+([\w\-.\\{}=,\[\]]+)\s+(.*)?`) + // responsePattern = regexp.MustCompile(`^(\d+)\s+([\w\-.\\{}=,\[\]]+)\s+(.*)?`) + responsePattern = regexp.MustCompile(`^(\d+)\s+([\w\-.\\{}=,\"\[\]]+|[\w.]+{.*?})\s+(.*)?`) // responsePattern = regexp.MustCompile(`^([\w,]+)\s+([\w{}]+)\s+([\w\-.\\{}=,\[\]]+)[^"]*(.*)?`) // ResponseType{data1=Type1,data2=Type2}. @@ -114,10 +115,13 @@ func (operation *Operation) ParseRouterComment(commentLine string) error { // ParseResponseComment parses comment for given `response` comment string. func (operation *Operation) ParseResponseComment(commentLine string, astFile *ast.File) error { + operation.parser.clearStructStack() + fmt.Println(commentLine) matches := responsePattern.FindStringSubmatch(commentLine) for i, m := range matches { fmt.Println(i, m) } + fmt.Println(commentLine, len(matches)) if len(matches) != 4 { return nil } @@ -172,30 +176,41 @@ func (operation *Operation) parseCombinedObject(refType string, astFile *ast.Fil } fmt.Println("parseCombinedObject matches:", matches) - schema, err := operation.parseObject(matches[1], astFile) + schemaA, err := operation.parseObject(matches[1], astFile) if err != nil { return nil, err } - fmt.Printf("parseCombinedObject schema=%+v\n", schema) - - fields, props := parseFields(matches[2]), map[string]TypeSchema{} + fmt.Printf("parseCombinedObject schema=%+v\n", schemaA) + fields := parseFields(matches[2]) + // props := map[string]TypeSchema{} for _, field := range fields { keyVal := strings.SplitN(field, "=", 2) if len(keyVal) == 2 { - schema, err := operation.parseObject(keyVal[1], astFile) - if err != nil { - return nil, err + // fmt.Println("keyVal", keyVal[0], keyVal[1]) //data TestData + // if is number or string wrap, replace it + if isReplaceValue(keyVal[1]) { + if p, ok := schemaA.Properties[keyVal[0]]; ok { + p.Example = keyVal[1] + } + } else { + schema, err := operation.parseObject(keyVal[1], astFile) + if err != nil { + return nil, err + } + schemaA.Properties[keyVal[0]] = schema //data=xx + // props[keyVal[0]] = *schema } - props[keyVal[0]] = *schema } } - fmt.Printf("props: %+v\n", props) - if len(props) == 0 { - return schema, nil - } - return schema, nil + // fmt.Printf("props: %+v\n", props) + // if len(props) == 0 { + // return schema, nil + // } + fmt.Printf("parseCombinedObject2 schema=%+v\n", schemaA) + fmt.Println(schemaA.Properties["data"]) + return schemaA, nil // return spec.ComposedSchema(*schema, spec.Schema{ // SchemaProps: spec.SchemaProps{ @@ -205,6 +220,22 @@ func (operation *Operation) parseCombinedObject(refType string, astFile *ast.Fil // }), nil } +func isReplaceValue(val string) bool { + if (strings.HasPrefix(val, "\"") && strings.HasSuffix(val, "\"")) || (strings.HasPrefix(val, "'") && strings.HasSuffix(val, "'")) { + return true + } + _, err := strconv.ParseInt(val, 10, 64) + if err == nil { + return true + } + _, err = strconv.ParseFloat(val, 64) + if err == nil { + return true + } + _, err = strconv.ParseBool(val) + return err == nil +} + func parseFields(s string) []string { nestLevel := 0 return strings.FieldsFunc(s, func(char rune) bool { diff --git a/parser.go b/parser.go index b21c98d..a0d60f4 100644 --- a/parser.go +++ b/parser.go @@ -392,6 +392,10 @@ func (parser *Parser) isInStructStack(typeSpecDef *TypeSpecDef) bool { return false } +func (parser *Parser) clearStructStack() { + parser.structStack = parser.structStack[:0] +} + // ParseDefinition parses given type spec that corresponds to the type under // given name and package func (parser *Parser) ParseDefinition(typeSpecDef *TypeSpecDef) (*TypeSchema, error) { diff --git a/spec.go b/spec.go index a51a503..9d786c5 100644 --- a/spec.go +++ b/spec.go @@ -159,11 +159,11 @@ func getExampleValue(typeName string, field *ast.Field) string { case "rune": return fmt.Sprintf("'%c'", exampleRune(example)) case "string": - return fmt.Sprintf("\"%s\"", example) + return fmt.Sprintf("\"%s\"", exampleString(example)) case "bool": return fmt.Sprintf("%t", exampleBool(example)) case "any": - return "nil" + return "null" } return example @@ -199,6 +199,13 @@ func exampleBool(example string) bool { return val } +func exampleString(example string) string { + if example == "" { + return "example" + } + return example +} + //getFieldName format json/xml func getFieldName(name string, field *ast.Field, format string) string { if field != nil {