forked from chanced/openapi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema.go
594 lines (560 loc) · 24.5 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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
package openapi
import (
"encoding/json"
"errors"
"strings"
"github.com/chanced/dynamic"
"github.com/chanced/openapi/yamlutil"
"github.com/tidwall/sjson"
"gopkg.in/yaml.v2"
)
// SchemaKind indicates whether the *SchemaObj is a SchemaObj, Reference, or Boolean
type SchemaKind uint8
const (
// SchemaKindObj = *SchemaObj
SchemaKindObj SchemaKind = iota
// SchemaKindBool = *Boolean
SchemaKindBool
)
// Schemas is a map of Schemas
type Schemas map[string]*SchemaObj
// UnmarshalJSON unmarshals JSON
func (s *Schemas) UnmarshalJSON(data []byte) error {
var dm map[string]json.RawMessage
if err := json.Unmarshal(data, &dm); err != nil {
return err
}
res := make(Schemas, len(dm))
for k, d := range dm {
v, err := unmarshalSchemaJSON(d)
if err != nil {
return err
}
res[k] = v
}
*s = res
return nil
}
// SchemaObj allows the definition of input and output data types. These types can
// be objects, but also primitives and arrays. This object is a superset of the
// [JSON SchemaObj Specification Draft
// 2020-12](https://tools.ietf.org/html/draft-bhutton-json-schema-00).
//
// For more information about the properties, see [JSON SchemaObj
// Core](https://tools.ietf.org/html/draft-bhutton-json-schema-00) and [JSON
// SchemaObj
// Validation](https://tools.ietf.org/html/draft-bhutton-json-schema-validation-00).
//
// Unless stated otherwise, the property definitions follow those of JSON SchemaObj
// and do not add any additional semantics. Where JSON SchemaObj indicates that
// behavior is defined by the application (e.g. for annotations), OAS also
// defers the definition of semantics to the application consuming the OpenAPI
// document.
//
// The OpenAPI SchemaObj Object
// [dialect](https://tools.ietf.org/html/draft-bhutton-json-schema-00#section-4.3.3)
// is defined as requiring the [OAS base vocabulary](#baseVocabulary), in
// addition to the vocabularies as specified in the JSON SchemaObj draft 2020-12
// [general purpose
// meta-schema](https://tools.ietf.org/html/draft-bhutton-json-schema-00#section-8).
//
// The OpenAPI SchemaObj Object dialect for this version of the specification is
// identified by the URI `https://spec.openapis.org/oas/3.1/dialect/base` (the
// <a name="dialectSchemaId"></a>"OAS dialect schema id").
//
// The following properties are taken from the JSON SchemaObj specification but
// their definitions have been extended by the OAS:
//
// - description - [CommonMark syntax](https://spec.commonmark.org/) MAY be used
// for rich text representation. - format - See [Data Type
// Formats](#dataTypeFormat) for further details. While relying on JSON SchemaObj's
// defined formats, the OAS offers a few additional predefined formats.
//
// In addition to the JSON SchemaObj properties comprising the OAS dialect, the
// SchemaObj Object supports keywords from any other vocabularies, or entirely
// arbitrary properties.
// A SchemaObj represents compiled version of json-schema.
type SchemaObj struct {
// Always will be assigned if the schema value is a boolean
Always *bool `json:"-"`
Schema string `json:"$schema,omitempty"`
// The value of $id is a URI-reference without a fragment that resolves
// against the Retrieval URI. The resulting URI is the base URI for the
// schema.
//
// https://json-schema.org/understanding-json-schema/structuring.html?highlight=id#id
ID string `json:"$id,omitempty"`
// At its core, JSON *SchemaObj defines the following basic types:
//
// "string", "number", "integer", "object", "array", "boolean", "null"
//
// https://json-schema.org/understanding-json-schema/reference/type.html#type
Type Types `json:"type,omitempty"`
// The "$ref" keyword is an applicator that is used to reference a
// statically identified schema. Its results are the results of the
// referenced schema. [CREF5]
//
// The value of the "$ref" keyword MUST be a string which is a
// URI-Reference. Resolved against the current URI base, it produces the URI
// of the schema to apply. This resolution is safe to perform on schema
// load, as the process of evaluating an instance cannot change how the
// reference resolves.
//
// https://json-schema.org/draft/2020-12/json-schema-core.html#ref
//
// https://json-schema.org/understanding-json-schema/structuring.html?highlight=ref#ref
Ref string `json:"$ref,omitempty"`
// The "$defs" keyword reserves a location for schema authors to inline
// re-usable JSON Schemas into a more general schema. The keyword does not
// directly affect the validation result.
//
// This keyword's value MUST be an object. Each member value of this object
// MUST be a valid JSON *SchemaObj.
//
// https://json-schema.org/draft/2020-12/json-schema-core.html#defs
//
// https://json-schema.org/understanding-json-schema/structuring.html?highlight=defs#defs
Definitions Schemas `json:"$defs,omitempty"`
// The format keyword allows for basic semantic identification of certain kinds of string values that are commonly used. For example, because JSON doesn’t have a “DateTime” type, dates need to be encoded as strings. format allows the schema author to indicate that the string value should be interpreted as a date. By default, format is just an annotation and does not effect validation.
//
// Optionally, validator implementations can provide a configuration option to
// enable format to function as an assertion rather than just an annotation.
// That means that validation will fail if, for example, a value with a date
// format isn’t in a form that can be parsed as a date. This can allow values to
// be constrained beyond what the other tools in JSON *SchemaObj, including Regular
// Expressions can do.
//
// https://json-schema.org/understanding-json-schema/reference/string.html#format
Format string `json:"format,omitempty"`
DynamicAnchor string `json:"$dynamicAnchor,omitempty"`
// The "$dynamicRef" keyword is an applicator that allows for deferring the
// full resolution until runtime, at which point it is resolved each time it
// is encountered while evaluating an instance.
//
// https://json-schema.org/draft/2020-12/json-schema-core.html#dynamic-ref
DynamicRef string `json:"$dynamicRef,omitempty"`
// A less common way to identify a subschema is to create a named anchor in
// the schema using the $anchor keyword and using that name in the URI
// fragment. Anchors must start with a letter followed by any number of
// letters, digits, -, _, :, or ..
//
// https://json-schema.org/understanding-json-schema/structuring.html?highlight=anchor#anchor
Anchor string `json:"$anchor,omitempty"`
// The const keyword is used to restrict a value to a single value.
//
// https://json-schema.org/understanding-json-schema/reference/generic.html?highlight=const#constant-values
Const json.RawMessage `json:"const,omitempty"`
// The enum keyword is used to restrict a value to a fixed set of values. It
// must be an array with at least one element, where each element is unique.
//
// https://json-schema.org/understanding-json-schema/reference/generic.html?highlight=const#enumerated-values
Enum []string `json:"enum,omitempty"`
// The $comment keyword is strictly intended for adding comments to a
// schema. Its value must always be a string. Unlike the annotations title,
// description, and examples, JSON schema implementations aren’t allowed to
// attach any meaning or behavior to it whatsoever, and may even strip them
// at any time. Therefore, they are useful for leaving notes to future
// editors of a JSON schema, but should not be used to communicate to users
// of the schema.
//
// https://json-schema.org/understanding-json-schema/reference/generic.html?highlight=const#comments
Comments string `json:"$comment,omitempty"`
// The not keyword declares that an instance validates if it doesn’t
// validate against the given subschema.
//
// https://json-schema.org/understanding-json-schema/reference/combining.html?highlight=not#not
Not *SchemaObj `json:"not,omitempty"`
// validate against allOf, the given data must be valid against all of the
// given subschemas.
//
// https://json-schema.org/understanding-json-schema/reference/combining.html?highlight=anyof#anyof
AllOf SchemaSet `json:"allOf,omitempty"`
// validate against anyOf, the given data must be valid against any (one or
// more) of the given subschemas.
//
// https://json-schema.org/understanding-json-schema/reference/combining.html?highlight=allof#allof
AnyOf SchemaSet `json:"anyOf,omitempty"`
// alidate against oneOf, the given data must be valid against exactly one of the given subschemas.
//
// https://json-schema.org/understanding-json-schema/reference/combining.html?highlight=oneof#oneof
OneOf SchemaSet `json:"oneOf,omitempty"`
// if, then and else keywords allow the application of a subschema based on
// the outcome of another schema, much like the if/then/else constructs
// you’ve probably seen in traditional programming languages.
//
// https://json-schema.org/understanding-json-schema/reference/conditionals.html#if-then-else
If *SchemaObj `json:"if,omitempty"`
// https://json-schema.org/understanding-json-schema/reference/conditionals.html#if-then-else
Then *SchemaObj `json:"then,omitempty"`
// https://json-schema.org/understanding-json-schema/reference/conditionals.html#if-then-else
Else *SchemaObj `json:"else,omitempty"`
MinProperties *int `json:"minProperties,omitempty"`
MaxProperties *int `json:"maxProperties,omitempty"`
Required []string `json:"required,omitempty"`
Properties Schemas `json:"properties,omitempty"`
PropertyNames *SchemaObj `json:"propertyNames,omitempty"`
RegexProperties *bool `json:"regexProperties,omitempty"`
PatternProperties Schemas `json:"patternProperties,omitempty"`
AdditionalProperties *SchemaObj `json:"additionalProperties,omitempty"`
// The dependentRequired keyword conditionally requires that certain
// properties must be present if a given property is present in an object.
// For example, suppose we have a schema representing a customer. If you
// have their credit card number, you also want to ensure you have a billing
// address. If you don’t have their credit card number, a billing address
// would not be required. We represent this dependency of one property on
// another using the dependentRequired keyword. The value of the
// dependentRequired keyword is an object. Each entry in the object maps
// from the name of a property, p, to an array of strings listing properties
// that are required if p is present.
DependentRequired map[string][]string `json:"dependentRequired,omitempty"`
// The dependentSchemas keyword conditionally applies a subschema when a
// given property is present. This schema is applied in the same way allOf
// applies schemas. Nothing is merged or extended. Both schemas apply
// independently.
DependentSchemas Schemas `json:"dependentSchemas,omitempty"`
UnevaluatedProperties *SchemaObj `json:"unevaluatedProperties,omitempty"`
UniqueObjs *bool `json:"uniqueObjs,omitempty"`
// List validation is useful for arrays of arbitrary length where each item
// matches the same schema. For this kind of array, set the items keyword to
// a single schema that will be used to validate all of the items in the
// array.
Items *SchemaObj `json:"items,omitempty"`
UnevaluatedObjs *SchemaObj `json:"unevaluatedObjs,omitempty"`
AdditionalObjs *SchemaObj `json:"additionalObjs,omitempty"`
PrefixObjs SchemaSet `json:"prefixObjs,omitempty"`
Contains *SchemaObj `json:"contains,omitempty"`
MinContains *Number `json:"minContains,omitempty"`
MaxContains *Number `json:"maxContains,omitempty"`
MinLength *Number `json:"minLength,omitempty"`
MaxLength *Number `json:"maxLength,omitempty"`
Pattern *Regexp `json:"pattern,omitempty"`
ContentEncoding string `json:"contentEncoding,omitempty"`
ContentMediaType string `json:"contentMediaType,omitempty"`
Minimum *Number `json:"minimum,omitempty"`
ExclusiveMinimum *Number `json:"exclusiveMinimum,omitempty"`
Maximum *Number `json:"maximum,omitempty"`
ExclusiveMaximum *Number `json:"exclusiveMaximum,omitempty"`
MultipleOf *Number `json:"multipleOf,omitempty"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Default json.RawMessage `json:"default,omitempty"`
ReadOnly *bool `json:"readOnly,omitempty"`
WriteOnly *bool `json:"writeOnly,omitempty"`
Examples []json.RawMessage `json:"examples,omitempty"`
Example json.RawMessage `json:"example,omitempty"`
Deprecated *bool `json:"deprecated,omitempty"`
ExternalDocs string `json:"externalDocs,omitempty"`
// Deprecated: renamed to dynamicAnchor
RecursiveAnchor *bool `json:"$recursiveAnchor,omitempty"`
// Deprecated: renamed to dynamicRef
RecursiveRef string `json:"$recursiveRef,omitempty"`
Discriminator *Discriminator `json:"discriminator,omitempty"`
// This MAY be used only on properties schemas. It has no effect on root
// schemas. Adds additional metadata to describe the XML representation of
// this property.
XML *XML `json:"xml,omitempty"`
Extensions `json:"-"`
Keywords map[string]json.RawMessage `json:"-"`
}
type schema SchemaObj
// Detail returns a ptr to the *SchemaObj
func (s SchemaObj) Detail() *SchemaObj {
return &s
}
// MarshalJSON marshals JSON
func (s SchemaObj) MarshalJSON() ([]byte, error) {
if s.Always != nil {
return json.Marshal(s.Always)
}
data, err := marshalExtendedJSON(schema(s))
if s.Keywords != nil {
for k, v := range s.Keywords {
data, err = sjson.SetBytes(data, k, v)
if err != nil {
return data, err
}
}
}
return data, err
}
// SchemaKind returns SchemaKindObj
func (s *SchemaObj) SchemaKind() SchemaKind { return SchemaKindObj }
// ResolveSchema resolves *SchemaObj by returning s
func (s *SchemaObj) ResolveSchema(SchemaResolver) (*SchemaObj, error) {
return s, nil
}
// UnmarshalJSON unmarshals JSON
func (s *SchemaObj) UnmarshalJSON(data []byte) error {
sv, err := unmarshalSchemaJSON(data)
*s = *sv
return err
}
// MarshalYAML first marshals and unmarshals into JSON and then marshals into
// YAML
func (s SchemaObj) MarshalYAML() (interface{}, error) {
b, err := json.Marshal(s)
if err != nil {
return nil, err
}
var v interface{}
err = json.Unmarshal(b, &v)
return v, err
}
// UnmarshalYAML unmarshals yaml into s
func (s *SchemaObj) UnmarshalYAML(unmarshal func(interface{}) error) error {
return yamlutil.Unmarshal(unmarshal, s)
}
// IsStrings returns false
func (s *SchemaObj) IsStrings() bool {
return false
}
// IsBool returns false
func (s *SchemaObj) IsBool() bool {
return false
}
// IsRef returns true if s.Ref is set
func (s *SchemaObj) IsRef() bool {
return s.Ref != ""
}
// SetKeyword encodes and sets the keyword key to the encoded value
func (s *SchemaObj) SetKeyword(key string, value interface{}) error {
b, err := json.Marshal(value)
if err != nil {
return err
}
return s.SetEncodedKeyword(key, b)
}
// SetEncodedKeyword sets the keyword key to value
func (s *SchemaObj) SetEncodedKeyword(key string, value []byte) error {
if strings.HasPrefix(key, "x-") {
return errors.New("keyword keys may not start with \"x-\"")
}
s.Keywords[key] = value
return nil
}
// DecodeKeyword unmarshals the keyword's raw data into dst
func (s *SchemaObj) DecodeKeyword(key string, dst interface{}) error {
return json.Unmarshal(s.Keywords[key], dst)
}
// DecodeKeywords unmarshals all keywords raw data into dst
func (s *SchemaObj) DecodeKeywords(dst interface{}) error {
data, err := json.Marshal(s.Keywords)
if err != nil {
return err
}
return json.Unmarshal(data, dst)
}
// SchemaSet is a slice of **SchemaObj
type SchemaSet []*SchemaObj
// UnmarshalJSON unmarshals JSON
func (s *SchemaSet) UnmarshalJSON(data []byte) error {
var j []dynamic.JSON
if err := json.Unmarshal(data, &j); err != nil {
return err
}
res := make(SchemaSet, len(j))
for i, d := range j {
v, err := unmarshalSchemaJSON(d)
if err != nil {
return err
}
res[i] = v
}
*s = res
return nil
}
func unmarshalSchemaJSON(data []byte) (*SchemaObj, error) {
var str string
l := len(data)
if l >= 4 && l <= 5 {
str = string(data)
}
switch {
case str == "true":
t := true
return &SchemaObj{Always: &t}, nil
case str == "false":
f := false
return &SchemaObj{Always: &f}, nil
default:
return unmarshalSchemaObjJSON(data)
}
}
func unmarshalSchemaObjJSON(data []byte) (*SchemaObj, error) {
var err error
exts := Extensions{}
kw := make(map[string]json.RawMessage)
var dst partialschema
if err = json.Unmarshal(data, &dst); err != nil {
return nil, err
}
var jm map[string]json.RawMessage
if err = json.Unmarshal(data, &jm); err != nil {
return nil, err
}
for key, d := range jm {
if strings.HasPrefix(key, "x-") {
exts[key] = d
} else if set, isSchema := schemaFieldSetters[key]; isSchema {
var v *SchemaObj
v, err = unmarshalSchemaJSON(d)
if err != nil {
return nil, err
}
set(&dst, v)
} else if _, isfield := jsfields[key]; !isfield {
kw[key] = d
}
}
res := SchemaObj(dst)
res.Keywords = kw
res.Extensions = exts
return &res, err
}
var schemaFieldSetters = map[string]func(s *partialschema, v *SchemaObj){
"not": func(s *partialschema, v *SchemaObj) { s.Not = v },
"if": func(s *partialschema, v *SchemaObj) { s.If = v },
"then": func(s *partialschema, v *SchemaObj) { s.Then = v },
"else": func(s *partialschema, v *SchemaObj) { s.Else = v },
"propertyNames": func(s *partialschema, v *SchemaObj) { s.PropertyNames = v },
"additionalProperties": func(s *partialschema, v *SchemaObj) { s.AdditionalProperties = v },
"unevaluatedProperties": func(s *partialschema, v *SchemaObj) { s.UnevaluatedProperties = v },
"items": func(s *partialschema, v *SchemaObj) { s.Items = v },
"contains": func(s *partialschema, v *SchemaObj) { s.Contains = v },
"unevaluatedObjs": func(s *partialschema, v *SchemaObj) { s.UnevaluatedObjs = v },
"additionalObjs": func(s *partialschema, v *SchemaObj) { s.AdditionalObjs = v },
}
var jsfields = map[string]struct{}{
"$schema": {},
"$id": {},
"type": {},
"$ref": {},
"$defs": {},
"format": {},
"$dynamicAnchor": {},
"$dynamicRef": {},
"$anchor": {},
"const": {},
"enum": {},
"$comment": {},
"not": {},
"allOf": {},
"anyOf": {},
"oneOf": {},
"if": {},
"then": {},
"else": {},
"minProperties": {},
"maxProperties": {},
"required": {},
"properties": {},
"propertyNames": {},
"regexProperties": {},
"patternProperties": {},
"additionalProperties": {},
"dependentRequired": {},
"dependentSchemas": {},
"unevaluatedProperties": {},
"uniqueObjs": {},
"items": {},
"unevaluatedObjs": {},
"additionalObjs": {},
"prefixObjs": {},
"contains": {},
"minContains": {},
"maxContains": {},
"minLength": {},
"maxLength": {},
"pattern": {},
"contentEncoding": {},
"contentMediaType": {},
"minimum": {},
"exclusiveMinimum": {},
"maximum": {},
"exclusiveMaximum": {},
"multipleOf": {},
"title": {},
"description": {},
"default": {},
"readOnly": {},
"writeOnly": {},
"examples": {},
"deprecated": {},
"externalDocs": {},
"$recursiveAnchor": {},
"$recursiveRef": {},
"discriminator": {},
"xml": {},
}
type partialschema struct {
Always *bool `json:"-"`
Schema string `json:"$schema,omitempty"`
ID string `json:"$id,omitempty"`
Type Types `json:"type,omitempty"`
Ref string `json:"$ref,omitempty"`
Definitions Schemas `json:"$defs,omitempty"`
Format string `json:"format,omitempty"`
DynamicAnchor string `json:"$dynamicAnchor,omitempty"`
DynamicRef string `json:"$dynamicRef,omitempty"`
Anchor string `json:"$anchor,omitempty"`
Const json.RawMessage `json:"const,omitempty"`
Enum []string `json:"enum,omitempty"`
Comments string `json:"$comment,omitempty"`
Not *SchemaObj `json:"-"`
AllOf SchemaSet `json:"allOf,omitempty"`
AnyOf SchemaSet `json:"anyOf,omitempty"`
OneOf SchemaSet `json:"oneOf,omitempty"`
If *SchemaObj `json:"-"`
Then *SchemaObj `json:"-"`
Else *SchemaObj `json:"-"`
MinProperties *int `json:"minProperties,omitempty"`
MaxProperties *int `json:"maxProperties,omitempty"`
Required []string `json:"required,omitempty"`
Properties Schemas `json:"properties,omitempty"`
PropertyNames *SchemaObj `json:"-"`
RegexProperties *bool `json:"regexProperties,omitempty"`
PatternProperties Schemas `json:"patternProperties,omitempty"`
AdditionalProperties *SchemaObj `json:"-"`
DependentRequired map[string][]string `json:"dependentRequired,omitempty"`
DependentSchemas Schemas `json:"dependentSchemas,omitempty"`
UnevaluatedProperties *SchemaObj `json:"-"`
UniqueObjs *bool `json:"uniqueObjs,omitempty"`
Items *SchemaObj `json:"-"`
UnevaluatedObjs *SchemaObj `json:"-"`
AdditionalObjs *SchemaObj `json:"-"`
PrefixObjs SchemaSet `json:"prefixObjs,omitempty"`
Contains *SchemaObj `json:"-"`
MinContains *Number `json:"minContains,omitempty"`
MaxContains *Number `json:"maxContains,omitempty"`
MinLength *Number `json:"minLength,omitempty"`
MaxLength *Number `json:"maxLength,omitempty"`
Pattern *Regexp `json:"pattern,omitempty"`
ContentEncoding string `json:"contentEncoding,omitempty"`
ContentMediaType string `json:"contentMediaType,omitempty"`
Minimum *Number `json:"minimum,omitempty"`
ExclusiveMinimum *Number `json:"exclusiveMinimum,omitempty"`
Maximum *Number `json:"maximum,omitempty"`
ExclusiveMaximum *Number `json:"exclusiveMaximum,omitempty"`
MultipleOf *Number `json:"multipleOf,omitempty"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Default json.RawMessage `json:"default,omitempty"`
ReadOnly *bool `json:"readOnly,omitempty"`
WriteOnly *bool `json:"writeOnly,omitempty"`
Examples []json.RawMessage `json:"examples,omitempty"`
Example json.RawMessage `json:"example,omitempty"`
Deprecated *bool `json:"deprecated,omitempty"`
ExternalDocs string `json:"externalDocs,omitempty"`
RecursiveAnchor *bool `json:"$recursiveAnchor,omitempty"`
RecursiveRef string `json:"$recursiveRef,omitempty"`
Discriminator *Discriminator `json:"discriminator,omitempty"`
XML *XML `json:"xml,omitempty"`
Extensions `json:"-"`
Keywords map[string]json.RawMessage `json:"-"`
}
var (
_ json.Marshaler = (*SchemaObj)(nil)
_ json.Unmarshaler = (*SchemaObj)(nil)
_ yaml.Unmarshaler = (*SchemaObj)(nil)
_ yaml.Marshaler = (*SchemaObj)(nil)
)