Implement func rendering

This commit is contained in:
Thilo Karraß 2020-10-14 11:43:12 +02:00
parent 261d4fb295
commit 5d074b181a
3 changed files with 97 additions and 9 deletions

View File

@ -10,7 +10,30 @@ func (e Encoder) Api(server openapi.Server) string {
tBuf := bytes.Buffer{}
tBuf.WriteString(fmt.Sprintf("package %v\n\n", e.Package))
tBuf.WriteString(e.GeneratedHeader())
tBuf.WriteString("import (\n \"fmt\"\n \"reflect\"\n \"strings\"\n)\n\n")
tBuf.WriteString(Comment(server.Description, 0))
tBuf.WriteString(fmt.Sprintf("const %v_OPENAPI_BASE string = \"%v\"", strings.ToUpper(e.Package), server.Url))
tBuf.WriteString(fmt.Sprintf("const %v_OPENAPI_BASE string = \"%v\"\n\n", strings.ToUpper(e.Package), server.Url))
// replace func:
tBuf.WriteString("func replacePathParam(path *string, param string, value interface{}) {\n")
tBuf.WriteString(" *path = strings.ReplaceAll(*path, \"{\" + param + \"}\", fmt.Sprintf(\"%v\", value))\n")
tBuf.WriteString("}\n\n")
tBuf.WriteString(`// Join anything into a string
func joinIfArray(v interface{}) string {
tBuf := &strings.Builder{}
switch reflect.TypeOf(v).Kind() {
case reflect.Slice, reflect.Array:
s := reflect.ValueOf(v)
for i:=0;i<s.Len();i++ {
if i > 0 {
tBuf.WriteString(",")
}
tBuf.WriteString(fmt.Sprintf("%v", s.Index(i)))
}
default:
tBuf.WriteString(fmt.Sprintf("%v", v))
}
return tBuf.String()
}
`)
return tBuf.String()
}

View File

@ -24,7 +24,7 @@ func (s simpleparamslice) Less(i, j int) bool {
switch s {
case "path":
return 0
case "head":
case "header":
return 1
case "query":
return 2
@ -116,7 +116,7 @@ func (e Encoder) Funcs(tag string, operations []*openapi.Operation) string {
tResponses = append(tResponses, &simpleparam{
Name: k,
Type: v.Schema.TypeOrReference(),
In: "head",
In: "header",
})
}
if len(tResponseType.Content) > 0 {
@ -174,11 +174,76 @@ func (e Encoder) Funcs(tag string, operations []*openapi.Operation) string {
tBuf.WriteString(fmt.Sprintf("func (p %v) %v(%v) %v {\n", tFuncPrefix, NormalizeName(op.OperationId), tParamStr, tResponseStr))
// add header parameters
// insert path parameters
// add query parameters
// post/put params ("body")
tBuf.WriteString(fmt.Sprintf(" // [%v]%v operation here \n", op.Method(), op.Path().Name))
// assemble request
// insert path parameters
tBuf.WriteString(fmt.Sprintf(" tPath := p.base+\"%v\"\n", op.Path().Name))
for _, p := range tParams {
if p.In == "path" {
tBuf.WriteString(fmt.Sprintf(" replacePathParam(&tPath, \"%v\", %v)\n", p.Name, NormalizeName(p.Name)))
}
}
// post/put params ("body")
tBuf.WriteString(" var tBuf *bytes.Buffer = nil\n")
if op.RequestBody != nil {
tBuf.WriteString(" var tData []byte = nil\n")
tBuf.WriteString(" tData, err = json.Marshal(data)\n")
tBuf.WriteString(" if err != nil {\n")
tBuf.WriteString(" return\n")
tBuf.WriteString(" }\n")
tBuf.WriteString(" tBuf = bytes.NewBuffer(tData)\n")
}
tBuf.WriteString(fmt.Sprintf(" req, _ := http.NewRequest(\"%v\", tPath, tBuf)\n", op.Method()))
// add header parameters
for _, p := range tParams {
if p.In == "header" {
tBuf.WriteString(fmt.Sprintf(" req.Header.Add(\"%v\", \"%v\")\n", p.Name, NormalizeName(p.Name)))
}
}
// add query parameters
tQBuf := &strings.Builder{}
tQBufHasData := false
tQBuf.WriteString(" q := req.URL.Query()\n")
for _, p := range tParams {
if p.In == "query" {
tQBuf.WriteString(fmt.Sprintf(" q.Add(\"%v\", joinIfArray(%v))\n", p.Name, NormalizeName(p.Name)))
tQBufHasData = true
}
}
tQBuf.WriteString(" req.URL.RawQuery = q.Encode()\n\n")
if tQBufHasData {
tBuf.WriteString(tQBuf.String())
}
tBuf.WriteString(" resp, err := p.client.Do(req)\n")
tBuf.WriteString(" if err != nil {\n return\n }\n")
tBuf.WriteString(" defer resp.Body.Close()\n")
tBuf.WriteString(" if resp.StatusCode / 100 != 2 {\n err = errors.New(resp.Status)\n return\n }\n")
// parse response
for _, r := range tResponses {
if r.In == "header" {
tBuf.WriteString(fmt.Sprintf(" %v = resp.Header.Get(\"%v\")\n", NormalizeName(r.Name), r.Name))
}
}
for _, r := range tResponses {
if r.In == "body" {
tType := r.Type
if strings.HasPrefix(tType, "*") {
tType = "&" + strings.TrimPrefix(tType, "*")
}
tBuf.WriteString(" tResponseData, err := ioutil.ReadAll(resp.Body)\n")
tBuf.WriteString(" if err != nil {\n")
tBuf.WriteString(" return\n")
tBuf.WriteString(" }\n")
tBuf.WriteString(fmt.Sprintf(" ret = %v{}\n", tType))
tBuf.WriteString(" err = json.Unmarshal(tResponseData, ret)\n")
break // there can be only one
}
}
tBuf.WriteString(fmt.Sprintf(" return\n}\n\n"))
}
@ -190,7 +255,7 @@ func (e Encoder) Funcs(tag string, operations []*openapi.Operation) string {
func (e Encoder) tagType(tag string) string {
tNorm := NormalizeName(tag)
tBuf := bytes.Buffer{}
tBuf.WriteString("import \"net/http\"\n\n")
tBuf.WriteString("import (\n \"bytes\"\n \"encoding/json\"\n \"errors\"\n \"io/ioutil\"\n \"net/http\"\n)\n")
tBuf.WriteString(Comment(e.getTagDescription(tag), 0))
tBuf.WriteString(fmt.Sprintf("type p%v struct {\n", tNorm))
tBuf.WriteString(" client *http.Client\n")

View File

@ -202,7 +202,7 @@ func (o Operation) Path() *PathItem {
}
func (o Operation) Method() string {
return o.method
return strings.ToUpper(o.method)
}
type RequestBodyObject struct {