From e71cec0d643a67ca07e127682fe138f19be44748 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Sun, 4 Dec 2022 23:43:09 +0100 Subject: [PATCH] Try decoding as JSON first then YAML, for speed Signed-off-by: Pierre Fenoll --- .github/workflows/go.yml | 5 +++++ openapi3/loader.go | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index d6950ebbb..809476343 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -97,6 +97,11 @@ jobs: run: | ! grep -IErn '\s$' --exclude-dir={.git,target,pgdata} + - if: runner.os == 'Linux' + name: Ensure use of unmarshal + run: | + [[ "$(git grep -F yaml. -- openapi3/ | grep -v _test.go | wc -l)" = 1 ]] + - if: runner.os == 'Linux' name: Missing specification object link to definition run: | diff --git a/openapi3/loader.go b/openapi3/loader.go index 138431fc0..3979e5d54 100644 --- a/openapi3/loader.go +++ b/openapi3/loader.go @@ -115,7 +115,7 @@ func (loader *Loader) loadSingleElementFromURI(ref string, rootPath *url.URL, el if err != nil { return nil, err } - if err := yaml.Unmarshal(data, element); err != nil { + if err := unmarshal(data, element); err != nil { return nil, err } @@ -133,7 +133,7 @@ func (loader *Loader) readURL(location *url.URL) ([]byte, error) { func (loader *Loader) LoadFromData(data []byte) (*T, error) { loader.resetVisitedPathItemRefs() doc := &T{} - if err := yaml.Unmarshal(data, doc); err != nil { + if err := unmarshal(data, doc); err != nil { return nil, err } if err := loader.ResolveRefsIn(doc, nil); err != nil { @@ -162,7 +162,7 @@ func (loader *Loader) loadFromDataWithPathInternal(data []byte, location *url.UR doc := &T{} loader.visitedDocuments[uri] = doc - if err := yaml.Unmarshal(data, doc); err != nil { + if err := unmarshal(data, doc); err != nil { return nil, err } if err := loader.ResolveRefsIn(doc, location); err != nil { @@ -172,6 +172,14 @@ func (loader *Loader) loadFromDataWithPathInternal(data []byte, location *url.UR return doc, nil } +func unmarshal(data []byte, v interface{}) error { + // See https://github.com/getkin/kin-openapi/issues/680 + if err := json.Unmarshal(data, v); err != nil { + return yaml.Unmarshal(data, v) + } + return nil +} + // ResolveRefsIn expands references if for instance spec was just unmarshalled func (loader *Loader) ResolveRefsIn(doc *T, location *url.URL) (err error) { if loader.Context == nil { @@ -319,7 +327,7 @@ func (loader *Loader) resolveComponent( if err2 != nil { return nil, err } - if err2 = yaml.Unmarshal(data, &cursor); err2 != nil { + if err2 = unmarshal(data, &cursor); err2 != nil { return nil, err } if cursor, err2 = drill(cursor); err2 != nil || cursor == nil {