-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathloader.go
115 lines (98 loc) · 3.55 KB
/
loader.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
package openapi
import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
"github.com/go-json-experiment/json/jsontext"
)
// loader helps deserialize an OpenAPI v3 document
type loader struct {
schemas map[string]*Schema
headers map[string]*Header
responses map[string]*Response
parameters map[string]*Parameter
requestBodies map[string]*RequestBody
links map[string]*Link
pathItems map[string]*PathItem
examples map[string]*Example
securitySchemes map[string]*SecurityScheme
callbacks map[string]*Callback
}
func (l *loader) reset() {
l.schemas = map[string]*Schema{}
l.headers = map[string]*Header{}
l.responses = map[string]*Response{}
l.parameters = map[string]*Parameter{}
l.requestBodies = map[string]*RequestBody{}
l.links = map[string]*Link{}
l.pathItems = map[string]*PathItem{}
l.examples = map[string]*Example{}
l.securitySchemes = map[string]*SecurityScheme{}
l.callbacks = map[string]*Callback{}
}
// newLoader returns an empty Loader
func newLoader() *loader {
return &loader{}
}
// LoadFromFile reads an OpenAPI specification from a file and parses it into a structured format
func LoadFromFile(location string) (*Document, error) {
return newLoader().LoadFromFile(location)
}
// LoadFromFile reads an OpenAPI specification from a file and parses it into a structured format.
func (l *loader) LoadFromFile(location string) (*Document, error) {
f, err := os.Open(location)
if err != nil {
return nil, err
}
defer f.Close()
// determine the file type and load accordingly
switch ext := filepath.Ext(location); ext {
case ".json":
return l.LoadFromReaderJSON(f)
case ".yaml", ".yml": // NOTE: openapi.yaml is recommended by the spec
return l.LoadFromReaderYAML(f)
default:
return nil, fmt.Errorf("unknown file extension: %s", ext)
}
}
func LoadFromData(data []byte) (*Document, error) {
return newLoader().LoadFromData(data)
}
// LoadFromData reads an OpenAPI specification from a byte array and parses it into a structured format.
// It will try to determine the format of the data and load it accordingly.
// If you know the format of the data, use LoadFromDataJSON or LoadFromDataYAML instead.
func (l *loader) LoadFromData(data []byte) (*Document, error) {
if jsontext.Value(data).IsValid() {
return l.LoadFromDataJSON(data)
}
return l.LoadFromDataYAML(data)
}
// LoadFromReader reads an OpenAPI specification from an io.Reader and parses it into a structured format.
// It will try to determine the format of the data and load it accordingly.
// If you know the format of the data, use LoadFromReaderJSON or LoadFromReaderYAML instead.
func LoadFromReader(r io.Reader) (*Document, error) {
return newLoader().LoadFromReader(r)
}
// LoadFromReader reads an OpenAPI specification from an io.Reader and parses it into a structured format.
// It will try to determine the format of the data and load it accordingly.
// If you know the format of the data, use LoadFromReaderJSON or LoadFromReaderYAML instead.
func (l *loader) LoadFromReader(r io.Reader) (*Document, error) {
l.reset()
// by default, assume the data is JSON
load := l.LoadFromReaderJSON
// check if the data is JSON, save read data to buffer
buff := &bytes.Buffer{}
ok, err := isJSONRead(io.TeeReader(r, buff))
if err != nil {
return nil, err
}
// if the data is not JSON, use YAML
if !ok {
load = l.LoadFromReaderYAML
}
// load the document using appropriate loader
// use multi-reader to combine what was read and the rest of the data
return load(io.MultiReader(buff, r)) // already includes resolving of references
}