222 lines
5.5 KiB
Go
222 lines
5.5 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
type config struct {
|
|
Openapi string `json:"openapi"`
|
|
Info struct {
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
Version string `json:"version"`
|
|
} `json:"info"`
|
|
Paths map[string]map[string]struct {
|
|
Tags []string `json:"tags"`
|
|
Summary string `json:"summary"`
|
|
OperationID string `json:"operationId"`
|
|
Parameters []struct {
|
|
Name string `json:"name"`
|
|
In string `json:"in"`
|
|
Schema property `json:"schema"`
|
|
} `json:"parameters"`
|
|
RequestBody *struct {
|
|
Content struct {
|
|
ApplicationJSON struct {
|
|
Schema property `json:"schema"`
|
|
} `json:"application/json"`
|
|
} `json:"content"`
|
|
Required bool `json:"required"`
|
|
} `json:"requestBody"`
|
|
Responses struct {
|
|
Num200 struct {
|
|
Description string `json:"description"`
|
|
Content struct {
|
|
ApplicationJSON struct {
|
|
Schema property `json:"schema"`
|
|
} `json:"application/json"`
|
|
} `json:"content"`
|
|
} `json:"200"`
|
|
} `json:"responses"`
|
|
} `json:"paths"`
|
|
Components struct {
|
|
Models map[string]struct {
|
|
Type string `json:"type"`
|
|
Properties map[string]property `json:"properties"`
|
|
} `json:"schemas"`
|
|
} `json:"components"`
|
|
}
|
|
|
|
type property struct {
|
|
Type string `json:"type"`
|
|
Format string `json:"format"`
|
|
Nullable bool `json:"nullable"`
|
|
Ref string `json:"$ref"`
|
|
AllOf []struct {
|
|
Ref string `json:"$ref"`
|
|
} `json:"allOf"`
|
|
Items struct {
|
|
Ref string `json:"$ref"`
|
|
} `json:"items"`
|
|
}
|
|
|
|
func (p *property) toKt() string {
|
|
sb := strings.Builder{}
|
|
if p.Type != "" {
|
|
sb.WriteString(fmt.Sprintf("%s", toMicronautKotlinType(*p)))
|
|
}
|
|
if p.Ref != "" {
|
|
sb.WriteString(fmt.Sprintf("%s", refToName(p.Ref)))
|
|
}
|
|
if len(p.AllOf) != 0 {
|
|
sb.WriteString(fmt.Sprintf("%s", refToName(p.AllOf[0].Ref)))
|
|
}
|
|
if p.Nullable {
|
|
sb.WriteString(fmt.Sprintf("?"))
|
|
}
|
|
return sb.String()
|
|
}
|
|
|
|
func main() {
|
|
b, err := os.ReadFile("swaggers/example_1.json")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
config := &config{}
|
|
if err := json.Unmarshal(b, config); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
res := toMicronautKotlin(config)
|
|
|
|
if err := os.WriteFile("res/models.kt", []byte(res["models"]), 0600); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if err := os.WriteFile("res/client.kt", []byte(res["client"]), 0600); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func toMicronautKotlin(config *config) map[string]string {
|
|
sbModels := strings.Builder{}
|
|
sbModels.WriteString("package models\n\n")
|
|
for modelName, model := range config.Components.Models {
|
|
sbModels.WriteString(fmt.Sprintf("data class %s(\n", modelName))
|
|
for name, value := range model.Properties {
|
|
sbModels.WriteString(fmt.Sprintf("\tvar %s: ", name))
|
|
sbModels.WriteString(value.toKt())
|
|
sbModels.WriteString(",\n")
|
|
}
|
|
sbModels.WriteString(")\n\n")
|
|
}
|
|
|
|
sbClient := strings.Builder{}
|
|
sbClient.WriteString("package client\n\n")
|
|
sbClient.WriteString("import io.micronaut.http.HttpResponse\n")
|
|
sbClient.WriteString("import io.micronaut.http.annotation.*\n")
|
|
sbClient.WriteString("import io.micronaut.http.client.annotation.Client\n")
|
|
sbClient.WriteString("\n")
|
|
sbClient.WriteString("@Client(value = \"INPUT URL\")\n")
|
|
sbClient.WriteString("interface GDSClient {\n\n")
|
|
|
|
pathKeys := getSortKeys(config.Paths)
|
|
for _, path := range pathKeys {
|
|
methods := config.Paths[path]
|
|
methodKeys := getSortKeys(methods)
|
|
for _, method := range methodKeys {
|
|
v := methods[method]
|
|
|
|
if v.Summary != "" {
|
|
sbClient.WriteString(fmt.Sprintf("\t// %s\n", v.Summary))
|
|
}
|
|
sbClient.WriteString(fmt.Sprintf("\t@%s(value = \"%s\")\n", toMicronautKotlinMethod(method), path))
|
|
sbClient.WriteString(fmt.Sprintf("\tfun %s(", v.OperationID))
|
|
|
|
if len(v.Parameters) != 0 || v.RequestBody != nil {
|
|
sbClient.WriteString("\n")
|
|
}
|
|
for _, p := range v.Parameters {
|
|
sbClient.WriteString("\t\t")
|
|
switch p.In {
|
|
case "header":
|
|
sbClient.WriteString("@Header")
|
|
case "path":
|
|
sbClient.WriteString("@PathVariable")
|
|
default:
|
|
sbClient.WriteString(fmt.Sprintf("(type %s not support)", p.In))
|
|
}
|
|
sbClient.WriteString(fmt.Sprintf(" %s: %s,\n", p.Name, p.Schema.toKt()))
|
|
}
|
|
if v.RequestBody != nil {
|
|
sbClient.WriteString(fmt.Sprintf("\t\t@Body %s: %s,\n", "body", v.RequestBody.Content.ApplicationJSON.Schema.toKt()))
|
|
}
|
|
if len(v.Parameters) != 0 || v.RequestBody != nil {
|
|
sbClient.WriteString("\t")
|
|
}
|
|
|
|
sbClient.WriteString(")")
|
|
|
|
resp := v.Responses.Num200.Content.ApplicationJSON.Schema.toKt()
|
|
if resp != "" {
|
|
sbClient.WriteString(fmt.Sprintf(": HttpResponse<%s>", resp))
|
|
}
|
|
sbClient.WriteString("\n\n")
|
|
}
|
|
}
|
|
sbClient.WriteString("}\n\n")
|
|
|
|
return map[string]string{
|
|
"models": sbModels.String(),
|
|
"client": sbClient.String(),
|
|
}
|
|
}
|
|
|
|
func toMicronautKotlinType(prop property) string {
|
|
switch prop.Type {
|
|
case "string":
|
|
return "String"
|
|
case "integer":
|
|
return "Int"
|
|
case "boolean":
|
|
return "Boolean"
|
|
case "number":
|
|
return "Double"
|
|
case "array":
|
|
return fmt.Sprintf("List<%s>", refToName(prop.Items.Ref))
|
|
}
|
|
return fmt.Sprintf("type %s not support", prop.Type)
|
|
}
|
|
|
|
func toMicronautKotlinMethod(method string) string {
|
|
switch method {
|
|
case "get":
|
|
return "Get"
|
|
case "post":
|
|
return "Post"
|
|
case "put":
|
|
return "Put"
|
|
case "delete":
|
|
return "Delete"
|
|
}
|
|
return fmt.Sprintf("mmethod %s not support", method)
|
|
}
|
|
|
|
func refToName(ref string) string {
|
|
arr := strings.Split(ref, "/")
|
|
return arr[len(arr)-1]
|
|
}
|
|
|
|
func getSortKeys[T any](m map[string]T) []string {
|
|
keys := make([]string, 0, len(m))
|
|
for k := range m {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
return keys
|
|
}
|