232 lines
4.3 KiB
Go
232 lines
4.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...))
|
|
}
|
|
|
|
ResImplType := func(v *APIParamType) string {
|
|
ret := ""
|
|
if !v.IsArray || v.Ispointer {
|
|
ret = ret + "&"
|
|
}
|
|
ret += v.Typename + "{}"
|
|
return ret
|
|
}
|
|
|
|
WNL("package %s", api.Namespace)
|
|
WNL(`import (
|
|
"context"
|
|
"encoding/json"
|
|
"strings"
|
|
"net/http"
|
|
"errors"
|
|
"reflect"
|
|
"strconv"
|
|
)`)
|
|
|
|
for k := range api.UsedImportsFunctions {
|
|
WNL(`import "%s"`, k)
|
|
}
|
|
|
|
WNL(`func handleTag(s string, r *http.Request) string {
|
|
parts := strings.Split(s, ":")
|
|
where := "Q"
|
|
key := ""
|
|
if len(parts) == 1 {
|
|
key = parts[0]
|
|
} else {
|
|
where = parts[0]
|
|
key = parts[1]
|
|
}
|
|
|
|
switch where {
|
|
case "Q":
|
|
return r.URL.Query().Get(key)
|
|
case "H":
|
|
return r.Header.Get(key)
|
|
case "P":
|
|
switch key {
|
|
case "*":
|
|
return r.URL.Path
|
|
case "last":
|
|
pps := strings.Split(r.URL.Path, "/")
|
|
return pps[len(pps)-1]
|
|
case "len":
|
|
pps := strings.Split(r.URL.Path, "/")
|
|
return strconv.Itoa(len(pps))
|
|
default:
|
|
pps := strings.Split(r.URL.Path, "/")
|
|
n, _ := strconv.Atoi(key)
|
|
if n < len(pps) {
|
|
return pps[n]
|
|
}
|
|
return ""
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func convert(s string, tpname string) interface{} {
|
|
switch tpname {
|
|
case "string":
|
|
return s
|
|
|
|
case "int":
|
|
v, _ := strconv.Atoi(s)
|
|
return v
|
|
case "int8":
|
|
v, _ := strconv.Atoi(s)
|
|
return int8(v)
|
|
case "int16":
|
|
v, _ := strconv.Atoi(s)
|
|
return int16(v)
|
|
case "int32":
|
|
v, _ := strconv.Atoi(s)
|
|
return int32(v)
|
|
case "int64":
|
|
v, _ := strconv.Atoi(s)
|
|
return int64(v)
|
|
case "uint":
|
|
v, _ := strconv.Atoi(s)
|
|
return uint(v)
|
|
case "float32":
|
|
v, _ := strconv.Atoi(s)
|
|
return float32(v)
|
|
case "float64":
|
|
v, _ := strconv.Atoi(s)
|
|
return float64(v)
|
|
case "bool":
|
|
return s == "true" || s == "1" || s == "Y"
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Map(r *http.Request, in interface{}) error {
|
|
|
|
tp := reflect.TypeOf(in)
|
|
vl := reflect.ValueOf(in)
|
|
if tp.Kind() == reflect.Ptr {
|
|
tp = tp.Elem()
|
|
vl = vl.Elem()
|
|
}
|
|
if tp.Kind() != reflect.Struct {
|
|
return errors.New("Type is not struct")
|
|
}
|
|
|
|
for i := 0; i < tp.NumField(); i++ {
|
|
k, ok := tp.Field(i).Tag.Lookup("in")
|
|
if ok {
|
|
str := handleTag(k, r)
|
|
v := convert(str, tp.Field(i).Type.Name())
|
|
strv := reflect.ValueOf(v)
|
|
vl.Field(i).Set(strv)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
`)
|
|
|
|
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]]
|
|
}
|
|
`)
|
|
|
|
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)
|
|
|
|
WNL(" req := %s", ResImplType(v.ReqType))
|
|
|
|
WNL(` err:=Map(r,req)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), 500)
|
|
return
|
|
}`)
|
|
|
|
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
|
|
}
|
|
}`)
|
|
|
|
}
|
|
|
|
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
|
|
}`)
|
|
|
|
return os.WriteFile(f, buf.Bytes(), 0600)
|
|
}
|