Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / github.com / go-openapi / swag / yaml.go
1 // Copyright 2015 go-swagger maintainers
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package swag
16
17 import (
18         "encoding/json"
19         "fmt"
20         "path/filepath"
21         "strconv"
22
23         "github.com/mailru/easyjson/jlexer"
24         "github.com/mailru/easyjson/jwriter"
25         yaml "gopkg.in/yaml.v2"
26 )
27
28 // YAMLMatcher matches yaml
29 func YAMLMatcher(path string) bool {
30         ext := filepath.Ext(path)
31         return ext == ".yaml" || ext == ".yml"
32 }
33
34 // YAMLToJSON converts YAML unmarshaled data into json compatible data
35 func YAMLToJSON(data interface{}) (json.RawMessage, error) {
36         jm, err := transformData(data)
37         if err != nil {
38                 return nil, err
39         }
40         b, err := WriteJSON(jm)
41         return json.RawMessage(b), err
42 }
43
44 // BytesToYAMLDoc converts a byte slice into a YAML document
45 func BytesToYAMLDoc(data []byte) (interface{}, error) {
46         var canary map[interface{}]interface{} // validate this is an object and not a different type
47         if err := yaml.Unmarshal(data, &canary); err != nil {
48                 return nil, err
49         }
50
51         var document yaml.MapSlice // preserve order that is present in the document
52         if err := yaml.Unmarshal(data, &document); err != nil {
53                 return nil, err
54         }
55         return document, nil
56 }
57
58 // JSONMapSlice represent a JSON object, with the order of keys maintained
59 type JSONMapSlice []JSONMapItem
60
61 // MarshalJSON renders a JSONMapSlice as JSON
62 func (s JSONMapSlice) MarshalJSON() ([]byte, error) {
63         w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty}
64         s.MarshalEasyJSON(w)
65         return w.BuildBytes()
66 }
67
68 // MarshalEasyJSON renders a JSONMapSlice as JSON, using easyJSON
69 func (s JSONMapSlice) MarshalEasyJSON(w *jwriter.Writer) {
70         w.RawByte('{')
71
72         ln := len(s)
73         last := ln - 1
74         for i := 0; i < ln; i++ {
75                 s[i].MarshalEasyJSON(w)
76                 if i != last { // last item
77                         w.RawByte(',')
78                 }
79         }
80
81         w.RawByte('}')
82 }
83
84 // UnmarshalJSON makes a JSONMapSlice from JSON
85 func (s *JSONMapSlice) UnmarshalJSON(data []byte) error {
86         l := jlexer.Lexer{Data: data}
87         s.UnmarshalEasyJSON(&l)
88         return l.Error()
89 }
90
91 // UnmarshalEasyJSON makes a JSONMapSlice from JSON, using easyJSON
92 func (s *JSONMapSlice) UnmarshalEasyJSON(in *jlexer.Lexer) {
93         if in.IsNull() {
94                 in.Skip()
95                 return
96         }
97
98         var result JSONMapSlice
99         in.Delim('{')
100         for !in.IsDelim('}') {
101                 var mi JSONMapItem
102                 mi.UnmarshalEasyJSON(in)
103                 result = append(result, mi)
104         }
105         *s = result
106 }
107
108 // JSONMapItem represents the value of a key in a JSON object held by JSONMapSlice
109 type JSONMapItem struct {
110         Key   string
111         Value interface{}
112 }
113
114 // MarshalJSON renders a JSONMapItem as JSON
115 func (s JSONMapItem) MarshalJSON() ([]byte, error) {
116         w := &jwriter.Writer{Flags: jwriter.NilMapAsEmpty | jwriter.NilSliceAsEmpty}
117         s.MarshalEasyJSON(w)
118         return w.BuildBytes()
119 }
120
121 // MarshalEasyJSON renders a JSONMapItem as JSON, using easyJSON
122 func (s JSONMapItem) MarshalEasyJSON(w *jwriter.Writer) {
123         w.String(s.Key)
124         w.RawByte(':')
125         w.Raw(WriteJSON(s.Value))
126 }
127
128 // UnmarshalJSON makes a JSONMapItem from JSON
129 func (s *JSONMapItem) UnmarshalJSON(data []byte) error {
130         l := jlexer.Lexer{Data: data}
131         s.UnmarshalEasyJSON(&l)
132         return l.Error()
133 }
134
135 // UnmarshalEasyJSON makes a JSONMapItem from JSON, using easyJSON
136 func (s *JSONMapItem) UnmarshalEasyJSON(in *jlexer.Lexer) {
137         key := in.UnsafeString()
138         in.WantColon()
139         value := in.Interface()
140         in.WantComma()
141         s.Key = key
142         s.Value = value
143 }
144
145 func transformData(input interface{}) (out interface{}, err error) {
146         switch in := input.(type) {
147         case yaml.MapSlice:
148
149                 o := make(JSONMapSlice, len(in))
150                 for i, mi := range in {
151                         var nmi JSONMapItem
152                         switch k := mi.Key.(type) {
153                         case string:
154                                 nmi.Key = k
155                         case int:
156                                 nmi.Key = strconv.Itoa(k)
157                         default:
158                                 return nil, fmt.Errorf("types don't match expect map key string or int got: %T", mi.Key)
159                         }
160
161                         v, ert := transformData(mi.Value)
162                         if ert != nil {
163                                 return nil, ert
164                         }
165                         nmi.Value = v
166                         o[i] = nmi
167                 }
168                 return o, nil
169         case map[interface{}]interface{}:
170                 o := make(JSONMapSlice, 0, len(in))
171                 for ke, va := range in {
172                         var nmi JSONMapItem
173                         switch k := ke.(type) {
174                         case string:
175                                 nmi.Key = k
176                         case int:
177                                 nmi.Key = strconv.Itoa(k)
178                         default:
179                                 return nil, fmt.Errorf("types don't match expect map key string or int got: %T", ke)
180                         }
181
182                         v, ert := transformData(va)
183                         if ert != nil {
184                                 return nil, ert
185                         }
186                         nmi.Value = v
187                         o = append(o, nmi)
188                 }
189                 return o, nil
190         case []interface{}:
191                 len1 := len(in)
192                 o := make([]interface{}, len1)
193                 for i := 0; i < len1; i++ {
194                         o[i], err = transformData(in[i])
195                         if err != nil {
196                                 return nil, err
197                         }
198                 }
199                 return o, nil
200         }
201         return input, nil
202 }
203
204 // YAMLDoc loads a yaml document from either http or a file and converts it to json
205 func YAMLDoc(path string) (json.RawMessage, error) {
206         yamlDoc, err := YAMLData(path)
207         if err != nil {
208                 return nil, err
209         }
210
211         data, err := YAMLToJSON(yamlDoc)
212         if err != nil {
213                 return nil, err
214         }
215
216         return data, nil
217 }
218
219 // YAMLData loads a yaml document from either http or a file
220 func YAMLData(path string) (interface{}, error) {
221         data, err := LoadFromFileOrHTTP(path)
222         if err != nil {
223                 return nil, err
224         }
225
226         return BytesToYAMLDoc(data)
227 }