forked from nytimes/openapi2proto
-
Notifications
You must be signed in to change notification settings - Fork 0
/
schema.go
128 lines (106 loc) · 2.52 KB
/
schema.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package openapi
import (
"encoding/json"
"reflect"
"github.com/pkg/errors"
)
// Using reflect is reaaaaaal slow, so we should really be generating
// code, but I'm going to punt it for now
var schemaProxyType reflect.Type
func init() {
rt := reflect.TypeOf(Schema{})
var fields []reflect.StructField
for i := 0; i < rt.NumField(); i++ {
ft := rt.Field(i)
if ft.PkgPath != "" {
continue
}
fields = append(fields, ft)
}
schemaProxyType = reflect.StructOf(fields)
}
// UnmarshalJSON decodes JSON data into a Schema
func (s *Schema) UnmarshalJSON(data []byte) error {
var b bool
if err := json.Unmarshal(data, &b); err == nil {
if b {
*s = Schema{}
} else {
*s = Schema{isNil: true}
}
return nil
}
nv := reflect.New(schemaProxyType)
if err := json.Unmarshal(data, nv.Interface()); err != nil {
return errors.Wrap(err, `failed to unmarshal JSON`)
}
nv = nv.Elem()
sv := reflect.ValueOf(s).Elem()
for i := 0; i < nv.NumField(); i++ {
ft := nv.Type().Field(i)
fv := nv.Field(i)
sv.FieldByName(ft.Name).Set(fv)
}
return nil
}
// IsNil returns true if it's nil schema (e.g.: `additionalProperties: false`)
func (s Schema) IsNil() bool {
return s.isNil
}
// UnmarshalJSON decodes JSON data into a SchemaType
func (s *SchemaType) UnmarshalJSON(data []byte) error {
var str string
if err := json.Unmarshal(data, &str); err == nil {
*s = []string{str}
return nil
}
var l []string
if err := json.Unmarshal(data, &l); err == nil {
*s = l
return nil
}
return errors.Errorf(`invalid type '%s'`, data)
}
// UnmarshalYAML decodes YAML data into a SchemaType
func (s *SchemaType) UnmarshalYAML(unmarshal func(interface{}) error) error {
var str string
if err := unmarshal(&str); err == nil {
if str == "" {
*s = []string(nil)
} else {
*s = []string{str}
}
return nil
}
var l []string
if err := unmarshal(&l); err == nil {
*s = l
return nil
}
return errors.New(`invalid type for schema type`)
}
// Empty returns true if there was no type specified
func (s *SchemaType) Empty() bool {
return len(*s) == 0
}
// Contains returns true if the specified type is listed within
// the list of schema types
func (s *SchemaType) Contains(t string) bool {
for _, v := range *s {
if v == t {
return true
}
}
return false
}
// Len returns the number of types listed under this SchemaType
func (s *SchemaType) Len() int {
return len(*s)
}
// First returns the first type listed under this SchemaType
func (s *SchemaType) First() string {
if !s.Empty() {
return (*s)[0]
}
return ""
}