· 6 years ago · Feb 06, 2020, 02:04 PM
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "log"
7 "net/http"
8 "strconv"
9 "strings"
10
11 clipboard "github.com/atotto/clipboard"
12 "github.com/gorilla/mux"
13)
14
15type jsonRequest struct {
16 JSON interface{} `json:"json_schema"`
17}
18
19func main() {
20 routes := mux.NewRouter()
21 server := "3000"
22
23 routes.HandleFunc("/convert", convertToSwagger).Methods("POST", "OPTIONS")
24 routes.HandleFunc("/ping", ping).Methods("GET")
25
26 log.Printf("server running on %v", server)
27 err := http.ListenAndServe(":"+server, routes)
28 if err != nil {
29 log.Fatalf("Unable to run http server: %v", err)
30 }
31
32 log.Println("Stopping API Service...")
33}
34
35func ping(w http.ResponseWriter, r *http.Request) {
36 w.Header().Set("Content-Type", "text/html; charset=utf-8")
37 w.Header().Set("Access-Control-Allow-Origin", "*")
38 w.Header().Set("Access-Control-Allow-Headers", "Content-Type,access-control-allow-origin, access-control-allow-headers")
39
40 fmt.Fprintf(w, "pong")
41}
42
43func convertToSwagger(w http.ResponseWriter, r *http.Request) {
44 w.Header().Set("Content-Type", "text/html; charset=utf-8")
45 w.Header().Set("Access-Control-Allow-Origin", "*")
46 w.Header().Set("Access-Control-Allow-Headers", "Content-Type,access-control-allow-origin, access-control-allow-headers")
47
48 decoder := json.NewDecoder(r.Body)
49 jsonSchema := jsonRequest{}
50
51 err := decoder.Decode(&jsonSchema)
52 if err != nil {
53 w.Header().Set("Content-Type", "application/json")
54 fmt.Fprintf(w, err.Error())
55 fmt.Println(err.Error())
56 return
57 }
58
59 yamlSchema := converToYAML(jsonSchema.JSON.(map[string]interface{}))
60 fmt.Fprintf(w, yamlSchema)
61 fmt.Println("success")
62}
63
64func converToYAML(oneLevelJSON map[string]interface{}) string {
65 var yamlSchema string
66
67 for k, v := range oneLevelJSON {
68 var dataType string
69 var description string
70 description = k
71 description = strings.Replace(description, "_", " ", -1)
72 description = strings.Title(strings.ToLower(description))
73 switch v.(type) {
74 case string:
75 dataType = "string"
76 yamlSchema += fmt.Sprintf("%v:\n type: %v\n description: %v\n", k, dataType, description)
77 case int, int16, int32, int64, int8, float32, float64, uint, uint16, uint32, uint64, uint8:
78 dataType = "integer"
79 yamlSchema += fmt.Sprintf("%v:\n type: %v\n description: %v\n", k, dataType, description)
80 case bool:
81 dataType = "boolean"
82 yamlSchema += fmt.Sprintf("%v:\n type: %v\n description: %v\n", k, dataType, description)
83 case []interface{}:
84 temp := (v.([]interface{}))
85 var ex string
86 description += " Array"
87 yamlSchema += fmt.Sprintf("%v:\n type: %v\n description: %v\n minItems: 1\n items:\n", k, "array", description)
88 for _, v := range temp {
89 switch v.(type) {
90 case float64, float32:
91 ex = strconv.FormatFloat(v.(float64), 'f', 0, 64)
92 dataType = " - " + ex
93 yamlSchema += fmt.Sprintf(" type: float\n description: Items\n")
94 break
95 case string:
96 ex = v.(string)
97 dataType = "" + ex
98 yamlSchema += fmt.Sprintf(" type: string\n description: Items\n")
99 break
100 case int, int16, int32, int64, int8, uint, uint16, uint32, uint64, uint8:
101 yamlSchema += fmt.Sprintf(" type: integer\n description: Items\n")
102 break
103 case map[string]interface{}:
104 properties := (v.(map[string]interface{}))
105 var dataProperties string
106 for k, v := range properties {
107 dataProperties += parse(k, v, 6, 8)
108 }
109 yamlSchema += fmt.Sprintf(" type: object\n description: Items\n properties:\n%v", dataProperties)
110 break
111 }
112 }
113 case map[string]interface{}:
114 properties := (v.(map[string]interface{}))
115 var dataProperties string
116 for k, v := range properties {
117 dataProperties += parse(k, v, 4, 6)
118 }
119 yamlSchema += fmt.Sprintf("%v:\n type: object\n properties:\n%v", k, dataProperties)
120 }
121 }
122
123 clipboard.WriteAll(yamlSchema)
124
125 return yamlSchema
126}
127
128func parse(key interface{}, value interface{}, indentationOne int, indentationTwo int) string {
129 var firstIndentation int = indentationOne
130 var secondIndentation int = indentationTwo
131 var yamlSchema string
132 var description string
133 description = fmt.Sprintf("%v", key)
134 description = strings.Replace(description, "_", " ", -1)
135 description = strings.Title(strings.ToLower(description))
136
137 switch value.(type) {
138 case string:
139 dataType := "string"
140 yamlSchema += fmt.Sprintf("%*s%v:\n%*stype: %v\n%*sdescription: %v\n", firstIndentation, "", key, secondIndentation, "", dataType, secondIndentation, "", description)
141 firstIndentation += 2
142 secondIndentation += 2
143 case int, int16, int32, int64, int8, float32, float64, uint, uint16, uint32, uint64, uint8:
144 dataType := "integer"
145 yamlSchema += fmt.Sprintf("%*s%v:\n%*stype: %v\n%*sdescription: %v\n", firstIndentation, "", key, secondIndentation, "", dataType, secondIndentation, "", description)
146 firstIndentation += 2
147 secondIndentation += 2
148 case bool:
149 dataType := "boolean"
150 yamlSchema += fmt.Sprintf("%*s%v:\n%*stype: %v\n%*sdescription: %v\n", firstIndentation, "", key, secondIndentation, "", dataType, secondIndentation, "", description)
151 firstIndentation += 2
152 secondIndentation += 2
153 case []interface{}:
154 temp := (value.([]interface{}))
155 description += " Array"
156 yamlSchema += fmt.Sprintf("%*s%v:\n%*stype: %v\n%*sdescription: %v\n%*sminItems: 1\n%*sitems:\n", firstIndentation, "", key, secondIndentation, "", "array", secondIndentation, "", description, secondIndentation, "", secondIndentation, "")
157 for _, v := range temp {
158 switch v.(type) {
159 case float64:
160 yamlSchema += fmt.Sprintf(" type: float\n description: Items\n")
161 firstIndentation += 2
162 secondIndentation += 2
163 break
164 case string:
165 yamlSchema += fmt.Sprintf(" type: string\n description: Items\n")
166 firstIndentation += 2
167 secondIndentation += 2
168 break
169 case int, int16, int32, int64, int8, uint, uint16, uint32, uint64, uint8:
170 yamlSchema += fmt.Sprintf(" type: integer\n description: Items\n")
171 break
172 case map[string]interface{}:
173 properties := (v.(map[string]interface{}))
174 var dataProperties string
175 for k, v := range properties {
176 dataProperties += parse(k, v, firstIndentation+6, secondIndentation+6)
177 }
178 /*yamlSchema += fmt.Sprintf(" type: object\n description: Items\n properties:\n%v", dataProperties)*/
179
180 yamlSchema += fmt.Sprintf("%*s type: object\n%*s description: Items\n%*s properties:\n%v", secondIndentation, "", secondIndentation, "", secondIndentation, "", dataProperties)
181 /*yamlSchema += fmt.Sprintf("%*s%v:\n%*stype: array5\n%*sitems:\n%*stype: object\n%*sproperties:\n%v", firstIndentation, "", key, secondIndentation, "", secondIndentation, "", secondIndentation+2, "", secondIndentation+2, "", dataProperties)*/
182 firstIndentation += 2
183 secondIndentation += 2
184 break
185 }
186 }
187 case map[string]interface{}:
188 properties := (value.(map[string]interface{}))
189 var dataProperties string
190 for k, v := range properties {
191 dataProperties += parse(k, v, firstIndentation+4, secondIndentation+4)
192 }
193 yamlSchema += fmt.Sprintf("%*s%v:\n%*stype: object\n%*sdescription: %v\n%*sproperties:\n%v", firstIndentation, "", key, secondIndentation, "", secondIndentation, "", description, secondIndentation, "", dataProperties)
194 firstIndentation += 2
195 secondIndentation += 2
196 }
197
198 return yamlSchema
199}