diff --git a/comments.go b/src/comments.go similarity index 100% rename from comments.go rename to src/comments.go diff --git a/config.go b/src/config.go similarity index 100% rename from config.go rename to src/config.go diff --git a/main.go b/src/main.go similarity index 79% rename from main.go rename to src/main.go index 4a247a7..727f649 100644 --- a/main.go +++ b/src/main.go @@ -110,7 +110,22 @@ func addFunction(a *ast.FuncDecl) { case *ast.SelectorExpr: reqType.Typename = y.X.(*ast.Ident).Name + "." + y.Sel.Name } - + case *ast.ArrayType: + reqType.IsArray = true + switch y := x.Elt.(type) { + case *ast.Ident: + reqType.Typename = y.Name + case *ast.SelectorExpr: + reqType.Typename = y.X.(*ast.Ident).Name + "." + y.Sel.Name + case *ast.StarExpr: + reqType.Ispointer = true + switch z := y.X.(type) { + case *ast.Ident: + reqType.Typename = z.Name + case *ast.SelectorExpr: + reqType.Typename = z.X.(*ast.Ident).Name + "." + z.Sel.Name + } + } case *ast.Ident: reqType.Typename = x.Name } @@ -127,55 +142,48 @@ func addFunction(a *ast.FuncDecl) { case *ast.SelectorExpr: resType.Typename = y.X.(*ast.Ident).Name + "." + y.Sel.Name } + case *ast.ArrayType: + resType.IsArray = true + switch y := x.Elt.(type) { + case *ast.Ident: + resType.Typename = y.Name + case *ast.SelectorExpr: + resType.Typename = y.X.(*ast.Ident).Name + "." + y.Sel.Name + case *ast.StarExpr: + resType.Ispointer = true + switch z := y.X.(type) { + case *ast.Ident: + resType.Typename = z.Name + case *ast.SelectorExpr: + resType.Typename = z.X.(*ast.Ident).Name + "." + z.Sel.Name + } + } - case *ast.Ident: - resType.Typename = x.Name } + + if md["RAW"] == "true" { + reqType.Typename = md["REQ"] + resType.Typename = md["RES"] + } + + verb := md["VERB"] + if verb == "" { + verb = http.MethodPost + } + fn := APIMethod{ + Desc: a.Name.Name, + Verb: verb, + Path: md["PATH"], + Perm: md["PERM"], + ReqType: reqType, + ResType: resType, + Raw: md["RAW"] == "true", + } + api.Methods[a.Name.Name] = &fn } - if md["RAW"] == "true" { - reqType.Typename = md["REQ"] - resType.Typename = md["RES"] - } - - verb := md["VERB"] - if verb == "" { - verb = http.MethodPost - } - fn := APIMethod{ - Desc: a.Name.Name, - Verb: verb, - Path: md["PATH"], - Perm: md["PERM"], - ReqType: reqType, - ResType: resType, - Raw: md["RAW"] == "true", - } - api.Methods[a.Name.Name] = &fn } -//func processHTTPTestOutput(f string, api *API) { -// -// for k, m := range api.Methods { -// fname := path.Join(httptestdir, k+".http") -// if dc.FileExists(fname) { -// continue -// } -// b := bytes.Buffer{} -// b.WriteString(fmt.Sprintf(`%s{{BASEURL}}%s -//Content-Type: application/json -//Cookie: dc={{COOKIE}} -// -//{} -// -//### -//`, m.Verb, api.BasePath+m.Path)) -// -// err := ioutil.WriteFile(fname, b.Bytes(), 0600) -// dc.Err(err) -// } -//} - func mapHttp(api *API) { for k, v := range api.Methods { pathmap, ok := httpMapper[v.Path] diff --git a/processGoClientOutput.go b/src/processGoClientOutput.go similarity index 88% rename from processGoClientOutput.go rename to src/processGoClientOutput.go index 1a2093a..fb7a60d 100644 --- a/processGoClientOutput.go +++ b/src/processGoClientOutput.go @@ -80,15 +80,16 @@ func invoke(m string, path string, bodyo interface{}) (*json.Decoder, error) { for k, m := range api.Methods { - b.WriteString(fmt.Sprintf("func %s(req *%s) (res *%s, err error){\n", k, m.ReqType.Typename, m.ResType.Typename)) + b.WriteString(fmt.Sprintf("func %s(req %s) (res %s, err error){\n", k, APIParamTypeDecToString(m.ReqType), APIParamTypeDecToString(m.ResType))) b.WriteString(fmt.Sprintf(` dec, err := invoke("%s", "%s", req) - ret := &%s{} + ret := %s{} err = dec.Decode(ret) if err != nil{ return nil,err } return ret, err -}`, m.Verb, m.Path, m.ResType.Typename)) +}`, m.Verb, m.Path, APIParamTypeToString(m.ResType))) + b.WriteString("\n") //} } diff --git a/processGoServerOutput.go b/src/processGoServerOutput.go similarity index 94% rename from processGoServerOutput.go rename to src/processGoServerOutput.go index ead1b99..01a2cb9 100644 --- a/processGoServerOutput.go +++ b/src/processGoServerOutput.go @@ -12,15 +12,6 @@ import ( func processGoServerOutput(api *API) { - APIParamTypeToString := func(t *APIParamType) string { - ret := "" - if t.Ispointer { - ret = ret + "&" - } - ret = ret + t.Typename - return ret - } - b := bytes.Buffer{} f := config.Gofname diff --git a/processTSClientOutput.go b/src/processTSClientOutput.go similarity index 90% rename from processTSClientOutput.go rename to src/processTSClientOutput.go index e86f4b4..7d81c9f 100644 --- a/processTSClientOutput.go +++ b/src/processTSClientOutput.go @@ -9,6 +9,14 @@ import ( ) func processTSClientOutput(f string, api *API) { + + _typeName := func(m *APIParamType) string { + if m.IsArray { + return m.Typename + "[]" + } + return m.Typename + } + b := bytes.Buffer{} if f == "" { f = config.Tsfname @@ -137,15 +145,8 @@ async function InvokeOk(path: string, method: HTMLMethod, body?: any): Promise{\n", k, m.ReqType)) - // b.WriteString(fmt.Sprintf("\treturn InvokeJSON(\"%s\",\"%s\",req)\n", m.Path, m.Verb)) - // b.WriteString(fmt.Sprintf("}\n\n")) - // } - // - //} else { - b.WriteString(fmt.Sprintf("export async function %s(req:%s):Promise<%s>{\n", k, m.ReqType.Typename, m.ResType.Typename)) + + b.WriteString(fmt.Sprintf("export async function %s(req:%s):Promise<%s>{\n", k, _typeName(m.ReqType), _typeName(m.ResType))) b.WriteString(fmt.Sprintf("\treturn InvokeJSON(\"%s\",\"%s\",req)\n", m.Path, m.Verb)) b.WriteString(fmt.Sprintf("}\n\n")) //} diff --git a/types.go b/src/types.go similarity index 63% rename from types.go rename to src/types.go index 5b0b47a..97004ff 100644 --- a/types.go +++ b/src/types.go @@ -25,6 +25,7 @@ type APIType struct { type APIParamType struct { Typename string Ispointer bool + IsArray bool } type APIMethod struct { @@ -36,3 +37,37 @@ type APIMethod struct { ResType *APIParamType Raw bool `yaml:"raw"` } + +func APIParamTypeToString(t *APIParamType) string { + ret := "" + if t.IsArray { + ret = "[]" + if t.Ispointer { + ret = ret + "*" + } + ret = ret + t.Typename + return ret + } + if t.Ispointer { + ret = ret + "&" + } + ret = ret + t.Typename + return ret +} + +func APIParamTypeDecToString(t *APIParamType) string { + ret := "" + if t.IsArray { + ret = "[]" + if t.Ispointer { + ret = ret + "*" + } + ret = ret + t.Typename + return ret + } + if t.Ispointer { + ret = ret + "*" + } + ret = ret + t.Typename + return ret +} diff --git a/util.go b/src/util.go similarity index 100% rename from util.go rename to src/util.go diff --git a/test/goapi/api.go b/test/goapi/api.go index 4f2839b..54b44c3 100644 --- a/test/goapi/api.go +++ b/test/goapi/api.go @@ -27,7 +27,7 @@ func Init() API { mux.HandleFunc("/someapi", func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "POST": - h_SomeAPI(w, r) + h_SomeAPI2(w, r) default: http.Error(w, "Method not allowed", 500) } @@ -35,12 +35,12 @@ func Init() API { return ret } -func h_SomeAPI(w http.ResponseWriter, r *http.Request) { +func h_SomeAPI2(w http.ResponseWriter, r *http.Request) { ctx := r.Context() ctx = context.WithValue(r.Context(), "REQ", r) ctx = context.WithValue(ctx, "RES", w) - req := &ARequestStruct{} + req := &AStr{} if r.Method != http.MethodGet && r.Method != http.MethodHead { err := json.NewDecoder(r.Body).Decode(&req) if err != nil { @@ -49,7 +49,7 @@ func h_SomeAPI(w http.ResponseWriter, r *http.Request) { } } - res, err := SomeAPI(ctx, req) + res, err := SomeAPI2(ctx, req) if err != nil { http.Error(w, err.Error(), 500) return diff --git a/test/goapi/test.go b/test/goapi/test.go index ba16540..62b5c25 100644 --- a/test/goapi/test.go +++ b/test/goapi/test.go @@ -2,29 +2,42 @@ package goapi import ( "context" - "time" ) -/*@API*/ -type ARequestStruct struct { - A *string `json:"a"` - B int64 - C time.Time - D *string -} +// +///*@API*/ +//type ARequestStruct struct { +// A *string `json:"a"` +// B int64 +// C time.Time +// D *string +//} +// +///*@API*/ +//type AResponseStruct struct { +// A string +// B int64 +// C time.Time +// D *string +//} +// +///* +//@API +//@PATH: /someapi +//*/ +//func SomeAPI(ctx context.Context, a *ARequestStruct) (*AResponseStruct, error) { +// return nil, nil +//} /*@API*/ -type AResponseStruct struct { +type AStr struct { A string - B int64 - C time.Time - D *string } /* @API @PATH: /someapi */ -func SomeAPI(ctx context.Context, a *ARequestStruct) (*AResponseStruct, error) { +func SomeAPI2(ctx context.Context, a *AStr) ([]*AStr, error) { return nil, nil } diff --git a/test/gocli/apicli.go b/test/gocli/apicli.go index ab536fe..310211c 100644 --- a/test/gocli/apicli.go +++ b/test/gocli/apicli.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "net/http" - "time" ) var Basepath string = "" @@ -38,31 +37,13 @@ func invoke(m string, path string, bodyo interface{}) (*json.Decoder, error) { return ret, nil } -func Some() (*struct{}, error) { - dec, err := invoke("a", "/c/d", struct{}{}) - ret := &struct{}{} - dec.Decode(ret) - return ret, err - +type AStr struct { + A string `json:"a"` } -type ARequestStruct struct { - A string `json:"a"` - B int64 `json:"b"` - C time.Time `json:"c"` - D string `json:"d"` -} - -type AResponseStruct struct { - A string `json:"a"` - B int64 `json:"b"` - C time.Time `json:"c"` - D string `json:"d"` -} - -func SomeAPI(req *ARequestStruct) (res *AResponseStruct, err error) { +func SomeAPI2(req *AStr) (res []*AStr, err error) { dec, err := invoke("POST", "/someapi", req) - ret := &AResponseStruct{} + ret := []*AStr{} err = dec.Decode(ret) if err != nil { return nil, err diff --git a/test/tscli/api.ts b/test/tscli/api.ts index ec85029..f57492c 100644 --- a/test/tscli/api.ts +++ b/test/tscli/api.ts @@ -81,26 +81,16 @@ async function InvokeOk(path: string, method: HTMLMethod, body?: any): Promise{ +SomeAPI2*/ +export async function SomeAPI2(req:AStr):Promise{ return InvokeJSON("/someapi","POST",req) }