forked from swaggest/jsonschema-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontext.go
149 lines (121 loc) · 4.33 KB
/
context.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package jsonschema
import (
"reflect"
"github.com/swaggest/refl"
)
// CollectDefinitions enables collecting definitions with provided func instead of result schema.
func CollectDefinitions(f func(name string, schema Schema)) func(*ReflectContext) {
return func(rc *ReflectContext) {
rc.CollectDefinitions = f
}
}
// DefinitionsPrefix sets up location for newly created references, default "#/definitions/".
func DefinitionsPrefix(prefix string) func(*ReflectContext) {
return func(rc *ReflectContext) {
rc.DefinitionsPrefix = prefix
}
}
// PropertyNameTag sets up which field tag to use for property name, default "json".
func PropertyNameTag(tag string) func(*ReflectContext) {
return func(rc *ReflectContext) {
rc.PropertyNameTag = tag
}
}
// InterceptTypeFunc can intercept type reflection to control or modify schema.
//
// True bool result demands no further processing for the Schema.
type InterceptTypeFunc func(reflect.Value, *Schema) (bool, error)
// InterceptPropertyFunc can intercept field reflection to control or modify schema.
type InterceptPropertyFunc func(name string, field reflect.StructField, propertySchema *Schema) error
// InterceptType adds hook to customize schema.
func InterceptType(f InterceptTypeFunc) func(*ReflectContext) {
return func(rc *ReflectContext) {
if rc.InterceptType != nil {
prev := rc.InterceptType
rc.InterceptType = func(v reflect.Value, s *Schema) (b bool, err error) {
ret, err := prev(v, s)
if err != nil || ret {
return ret, err
}
return f(v, s)
}
} else {
rc.InterceptType = f
}
}
}
// InterceptProperty adds hook to customize property schema.
func InterceptProperty(f InterceptPropertyFunc) func(*ReflectContext) {
return func(rc *ReflectContext) {
if rc.InterceptProperty != nil {
prev := rc.InterceptProperty
rc.InterceptProperty = func(name string, field reflect.StructField, propertySchema *Schema) error {
err := prev(name, field, propertySchema)
if err != nil {
return err
}
return f(name, field, propertySchema)
}
} else {
rc.InterceptProperty = f
}
}
}
// InlineRefs prevents references.
func InlineRefs(rc *ReflectContext) {
rc.InlineRefs = true
}
// RootNullable enables nullability (by pointer) for root schema, disabled by default.
func RootNullable(rc *ReflectContext) {
rc.RootNullable = true
}
// RootRef enables referencing root schema.
func RootRef(rc *ReflectContext) {
rc.RootRef = true
}
// SkipEmbeddedMapsSlices disables shortcutting into embedded maps and slices.
func SkipEmbeddedMapsSlices(rc *ReflectContext) {
rc.SkipEmbeddedMapsSlices = true
}
// PropertyNameMapping enables property name mapping from a struct field name.
func PropertyNameMapping(mapping map[string]string) func(rc *ReflectContext) {
return func(rc *ReflectContext) {
rc.PropertyNameMapping = mapping
}
}
// ReflectContext accompanies single reflect operation.
type ReflectContext struct {
// DefName returns custom definition name for a type, can be nil.
DefName func(t reflect.Type, defaultDefName string) string
// CollectDefinitions is triggered when named schema is created, can be nil.
CollectDefinitions func(name string, schema Schema)
// DefinitionsPrefix defines location of named schemas, default #/definitions/.
DefinitionsPrefix string
// PropertyNameTag enables property naming from a field tag, e.g. `header:"first_name"`.
PropertyNameTag string
// PropertyNameMapping enables property name mapping from a struct field name, e.g. "FirstName":"first_name".
// Only applicable to top-level properties (including embedded).
PropertyNameMapping map[string]string
// EnvelopNullability enables `anyOf` enveloping ot "type":"null" instead of injecting into definition.
EnvelopNullability bool
InlineRefs bool
RootRef bool
RootNullable bool
// SkipEmbeddedMapsSlices disables shortcutting into embedded maps and slices.
SkipEmbeddedMapsSlices bool
InterceptType InterceptTypeFunc
InterceptProperty InterceptPropertyFunc
Path []string
definitions map[refl.TypeString]Schema // list of all definition objects
definitionRefs map[refl.TypeString]Ref
typeCycles map[refl.TypeString]bool
rootDefName string
}
func (rc *ReflectContext) getDefinition(ref string) Schema {
for ts, r := range rc.definitionRefs {
if r.Path+r.Name == ref {
return rc.definitions[ts]
}
}
return Schema{}
}