1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package spec
16
17 import (
18 "encoding/json"
19 "strconv"
20 "strings"
21
22 "github.com/go-openapi/jsonpointer"
23 "github.com/go-openapi/swag"
24 )
25
26
27 type Extensions map[string]interface{}
28
29
30 func (e Extensions) Add(key string, value interface{}) {
31 realKey := strings.ToLower(key)
32 e[realKey] = value
33 }
34
35
36 func (e Extensions) GetString(key string) (string, bool) {
37 if v, ok := e[strings.ToLower(key)]; ok {
38 str, ok := v.(string)
39 return str, ok
40 }
41 return "", false
42 }
43
44
45 func (e Extensions) GetInt(key string) (int, bool) {
46 realKey := strings.ToLower(key)
47
48 if v, ok := e.GetString(realKey); ok {
49 if r, err := strconv.Atoi(v); err == nil {
50 return r, true
51 }
52 }
53
54 if v, ok := e[realKey]; ok {
55 if r, rOk := v.(float64); rOk {
56 return int(r), true
57 }
58 }
59 return -1, false
60 }
61
62
63 func (e Extensions) GetBool(key string) (bool, bool) {
64 if v, ok := e[strings.ToLower(key)]; ok {
65 str, ok := v.(bool)
66 return str, ok
67 }
68 return false, false
69 }
70
71
72 func (e Extensions) GetStringSlice(key string) ([]string, bool) {
73 if v, ok := e[strings.ToLower(key)]; ok {
74 arr, isSlice := v.([]interface{})
75 if !isSlice {
76 return nil, false
77 }
78 var strs []string
79 for _, iface := range arr {
80 str, isString := iface.(string)
81 if !isString {
82 return nil, false
83 }
84 strs = append(strs, str)
85 }
86 return strs, ok
87 }
88 return nil, false
89 }
90
91
92 type VendorExtensible struct {
93 Extensions Extensions
94 }
95
96
97 func (v *VendorExtensible) AddExtension(key string, value interface{}) {
98 if value == nil {
99 return
100 }
101 if v.Extensions == nil {
102 v.Extensions = make(map[string]interface{})
103 }
104 v.Extensions.Add(key, value)
105 }
106
107
108 func (v VendorExtensible) MarshalJSON() ([]byte, error) {
109 toser := make(map[string]interface{})
110 for k, v := range v.Extensions {
111 lk := strings.ToLower(k)
112 if strings.HasPrefix(lk, "x-") {
113 toser[k] = v
114 }
115 }
116 return json.Marshal(toser)
117 }
118
119
120 func (v *VendorExtensible) UnmarshalJSON(data []byte) error {
121 var d map[string]interface{}
122 if err := json.Unmarshal(data, &d); err != nil {
123 return err
124 }
125 for k, vv := range d {
126 lk := strings.ToLower(k)
127 if strings.HasPrefix(lk, "x-") {
128 if v.Extensions == nil {
129 v.Extensions = map[string]interface{}{}
130 }
131 v.Extensions[k] = vv
132 }
133 }
134 return nil
135 }
136
137
138 type InfoProps struct {
139 Description string `json:"description,omitempty"`
140 Title string `json:"title,omitempty"`
141 TermsOfService string `json:"termsOfService,omitempty"`
142 Contact *ContactInfo `json:"contact,omitempty"`
143 License *License `json:"license,omitempty"`
144 Version string `json:"version,omitempty"`
145 }
146
147
148
149
150
151 type Info struct {
152 VendorExtensible
153 InfoProps
154 }
155
156
157 func (i Info) JSONLookup(token string) (interface{}, error) {
158 if ex, ok := i.Extensions[token]; ok {
159 return &ex, nil
160 }
161 r, _, err := jsonpointer.GetForToken(i.InfoProps, token)
162 return r, err
163 }
164
165
166 func (i Info) MarshalJSON() ([]byte, error) {
167 b1, err := json.Marshal(i.InfoProps)
168 if err != nil {
169 return nil, err
170 }
171 b2, err := json.Marshal(i.VendorExtensible)
172 if err != nil {
173 return nil, err
174 }
175 return swag.ConcatJSON(b1, b2), nil
176 }
177
178
179 func (i *Info) UnmarshalJSON(data []byte) error {
180 if err := json.Unmarshal(data, &i.InfoProps); err != nil {
181 return err
182 }
183 return json.Unmarshal(data, &i.VendorExtensible)
184 }
185
View as plain text