apigen/lib/processGoServerOutput.go

124 lines
2.3 KiB
Go

package lib
import (
"bytes"
_ "embed"
"fmt"
"os"
)
func processGoServerOutput(f string) error {
buf := &bytes.Buffer{}
W := func(s string, p ...interface{}) {
buf.WriteString(fmt.Sprintf(s, p...))
}
WNL := func(s string, p ...interface{}) {
buf.WriteString(fmt.Sprintf(s+"\n", p...))
}
WNL("package %s", api.Namespace)
WNL(`import (
"context"
"encoding/json"
"strings"
"net/http"
)`)
for k := range api.UsedImportsFunctions {
W(`import "%s"`, k)
}
WNL(`type API struct {
Mux *http.ServeMux
Perms map[string]string
}
func (a *API) GetPerm(r *http.Request) string {
return a.Perms[r.Method+"_"+strings.Split(r.RequestURI, "?")[0]]
}
`)
WNL(`func Init() *API{
mux := &http.ServeMux{}
ret := &API{
Mux: mux,
Perms: make(map[string]string),
}`)
for _, v := range api.Methods {
if v.Perm != "" {
WNL(` ret.Perms["%s_%s"]="%s"`, v.Verb, v.Path, v.Perm)
}
}
for _, v := range api.SortedPaths {
WNL(` mux.HandleFunc("%s",func(w http.ResponseWriter, r *http.Request) {
switch r.Method {`, v.Path)
for _, v1 := range v.SortedVerbs {
WNL(` case "%s":`, v1.Method.Verb)
if v1.Method.Raw {
WNL(` %s(w,r)`, v1.Method.Name)
} else {
WNL(` h_%s(w,r)`, v1.Method.Name)
}
WNL(` default:
http.Error(w,"Method not allowed",500)`)
}
WNL(` }`)
WNL(` })
return ret
}`)
}
for _, v := range api.Methods {
WNL(`func h_%s(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
ctx = context.WithValue(r.Context(), "REQ", r)
ctx = context.WithValue(ctx, "RES", w)`, v.Name)
W(" var req ")
if v.ReqType.IsArray {
W("[]")
}
if v.ReqType.Ispointer {
W("*")
}
WNL(v.ReqType.Typename)
WNL(` if r.Method!=http.MethodGet && r.Method!=http.MethodHead {`)
if v.ReqType.Ispointer || v.ReqType.IsArray {
WNL(" err := json.NewDecoder(r.Body).Decode(req)")
} else {
WNL(" err := json.NewDecoder(r.Body).Decode(&req)")
}
WNL(` if err != nil {
http.Error(w, err.Error(), 500)
return
}
}`)
WNL(` res, err := %s(ctx,req)`, v.Name)
WNL(` if err != nil {
http.Error(w, err.Error(), 500)
return
}
w.Header().Add("Content-Type","Application/json")
err=json.NewEncoder(w).Encode(res)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
}`)
}
return os.WriteFile(f, buf.Bytes(), 0600)
}