Refactoring extraction and builder functions.

now things are robust, we can move things around a little to prepare for the next set of incoming models. The extraction and builder functions have all been moved to the low packakge, and out of the v3 package.
This commit is contained in:
Dave Shanley
2022-08-14 04:03:13 -04:00
parent acee81f126
commit 67c701ff07
31 changed files with 331 additions and 330 deletions

View File

@@ -1,6 +1,7 @@
package datamodel package datamodel
import ( import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/datamodel/low/3.0" "github.com/pb33f/libopenapi/datamodel/low/3.0"
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -20,7 +21,7 @@ x-b33f: princess`
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n v3.ExternalDoc var n v3.ExternalDoc
err := v3.BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)

View File

@@ -15,11 +15,11 @@ type Callback struct {
} }
func (cb *Callback) FindExpression(exp string) *low.ValueReference[*PathItem] { func (cb *Callback) FindExpression(exp string) *low.ValueReference[*PathItem] {
return FindItemInMap[*PathItem](exp, cb.Expression.Value) return low.FindItemInMap[*PathItem](exp, cb.Expression.Value)
} }
func (cb *Callback) Build(root *yaml.Node, idx *index.SpecIndex) error { func (cb *Callback) Build(root *yaml.Node, idx *index.SpecIndex) error {
cb.Extensions = ExtractExtensions(root) cb.Extensions = low.ExtractExtensions(root)
// handle callback // handle callback
var currentCB *yaml.Node var currentCB *yaml.Node
@@ -30,7 +30,7 @@ func (cb *Callback) Build(root *yaml.Node, idx *index.SpecIndex) error {
currentCB = callbackNode currentCB = callbackNode
continue continue
} }
callback, eErr := ExtractObjectRaw[*PathItem](callbackNode, idx) callback, eErr := low.ExtractObjectRaw[*PathItem](callbackNode, idx)
if eErr != nil { if eErr != nil {
return eErr return eErr
} }

View File

@@ -1,6 +1,7 @@
package v3 package v3
import ( import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@@ -26,7 +27,7 @@ func TestCallback_Build_Success(t *testing.T) {
assert.NoError(t, mErr) assert.NoError(t, mErr)
var n Callback var n Callback
err := BuildModel(rootNode.Content[0], &n) err := low.BuildModel(rootNode.Content[0], &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(rootNode.Content[0], nil) err = n.Build(rootNode.Content[0], nil)
@@ -59,7 +60,7 @@ func TestCallback_Build_Error(t *testing.T) {
assert.NoError(t, mErr) assert.NoError(t, mErr)
var n Callback var n Callback
err := BuildModel(rootNode.Content[0], &n) err := low.BuildModel(rootNode.Content[0], &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(rootNode.Content[0], idx) err = n.Build(rootNode.Content[0], idx)
@@ -94,7 +95,7 @@ func TestCallback_Build_Using_InlineRef(t *testing.T) {
assert.NoError(t, mErr) assert.NoError(t, mErr)
var n Callback var n Callback
err := BuildModel(rootNode.Content[0], &n) err := low.BuildModel(rootNode.Content[0], &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(rootNode.Content[0], idx) err = n.Build(rootNode.Content[0], idx)
@@ -142,7 +143,7 @@ components:
assert.NoError(t, mErr) assert.NoError(t, mErr)
var n Callback var n Callback
err := BuildModel(rootNode.Content[0], &n) err := low.BuildModel(rootNode.Content[0], &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(rootNode.Content[0], idx) err = n.Build(rootNode.Content[0], idx)

View File

@@ -27,43 +27,43 @@ type Components struct {
} }
func (co *Components) FindSchema(schema string) *low.ValueReference[*Schema] { func (co *Components) FindSchema(schema string) *low.ValueReference[*Schema] {
return FindItemInMap[*Schema](schema, co.Schemas.Value) return low.FindItemInMap[*Schema](schema, co.Schemas.Value)
} }
func (co *Components) FindResponse(response string) *low.ValueReference[*Response] { func (co *Components) FindResponse(response string) *low.ValueReference[*Response] {
return FindItemInMap[*Response](response, co.Responses.Value) return low.FindItemInMap[*Response](response, co.Responses.Value)
} }
func (co *Components) FindParameter(response string) *low.ValueReference[*Parameter] { func (co *Components) FindParameter(response string) *low.ValueReference[*Parameter] {
return FindItemInMap[*Parameter](response, co.Parameters.Value) return low.FindItemInMap[*Parameter](response, co.Parameters.Value)
} }
func (co *Components) FindSecurityScheme(sScheme string) *low.ValueReference[*SecurityScheme] { func (co *Components) FindSecurityScheme(sScheme string) *low.ValueReference[*SecurityScheme] {
return FindItemInMap[*SecurityScheme](sScheme, co.SecuritySchemes.Value) return low.FindItemInMap[*SecurityScheme](sScheme, co.SecuritySchemes.Value)
} }
func (co *Components) FindExample(example string) *low.ValueReference[*Example] { func (co *Components) FindExample(example string) *low.ValueReference[*Example] {
return FindItemInMap[*Example](example, co.Examples.Value) return low.FindItemInMap[*Example](example, co.Examples.Value)
} }
func (co *Components) FindRequestBody(requestBody string) *low.ValueReference[*RequestBody] { func (co *Components) FindRequestBody(requestBody string) *low.ValueReference[*RequestBody] {
return FindItemInMap[*RequestBody](requestBody, co.RequestBodies.Value) return low.FindItemInMap[*RequestBody](requestBody, co.RequestBodies.Value)
} }
func (co *Components) FindHeader(header string) *low.ValueReference[*Header] { func (co *Components) FindHeader(header string) *low.ValueReference[*Header] {
return FindItemInMap[*Header](header, co.Headers.Value) return low.FindItemInMap[*Header](header, co.Headers.Value)
} }
func (co *Components) FindLink(link string) *low.ValueReference[*Link] { func (co *Components) FindLink(link string) *low.ValueReference[*Link] {
return FindItemInMap[*Link](link, co.Links.Value) return low.FindItemInMap[*Link](link, co.Links.Value)
} }
func (co *Components) FindCallback(callback string) *low.ValueReference[*Callback] { func (co *Components) FindCallback(callback string) *low.ValueReference[*Callback] {
return FindItemInMap[*Callback](callback, co.Callbacks.Value) return low.FindItemInMap[*Callback](callback, co.Callbacks.Value)
} }
func (co *Components) Build(root *yaml.Node, idx *index.SpecIndex) error { func (co *Components) Build(root *yaml.Node, idx *index.SpecIndex) error {
co.Extensions = ExtractExtensions(root) co.Extensions = low.ExtractExtensions(root)
// build out components asynchronously for speed. There could be some significant weight here. // build out components asynchronously for speed. There could be some significant weight here.
skipChan := make(chan bool) skipChan := make(chan bool)
@@ -178,7 +178,7 @@ func extractComponentValues[T low.Buildable[N], N any](label string, root *yaml.
continue continue
} }
var n T = new(N) var n T = new(N)
_ = BuildModel(v, n) _ = low.BuildModel(v, n)
err := n.Build(v, idx) err := n.Build(v, idx)
if err != nil { if err != nil {
errorChan <- err errorChan <- err

View File

@@ -1,6 +1,7 @@
package v3 package v3
import ( import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@@ -66,7 +67,7 @@ func TestComponents_Build_Success(t *testing.T) {
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n Components var n Components
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)
@@ -103,7 +104,7 @@ func TestComponents_Build_Success_Skip(t *testing.T) {
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n Components var n Components
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)
@@ -124,7 +125,7 @@ func TestComponents_Build_Fail(t *testing.T) {
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n Components var n Components
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)
@@ -145,7 +146,7 @@ func TestComponents_Build_Fail_TypeFail(t *testing.T) {
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n Components var n Components
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)

View File

@@ -1,6 +1,7 @@
package v3 package v3
import ( import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"testing" "testing"
@@ -16,7 +17,7 @@ mapping:
assert.NoError(t, mErr) assert.NoError(t, mErr)
var n Discriminator var n Discriminator
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "nothing", n.FindMappingValue("something").Value) assert.Equal(t, "nothing", n.FindMappingValue("something").Value)
assert.Nil(t, n.FindMappingValue("freshCakes")) assert.Nil(t, n.FindMappingValue("freshCakes"))

View File

@@ -19,12 +19,12 @@ type Encoding struct {
} }
func (en *Encoding) FindHeader(hType string) *low.ValueReference[*Header] { func (en *Encoding) FindHeader(hType string) *low.ValueReference[*Header] {
return FindItemInMap[*Header](hType, en.Headers.Value) return low.FindItemInMap[*Header](hType, en.Headers.Value)
} }
func (en *Encoding) Build(root *yaml.Node, idx *index.SpecIndex) error { func (en *Encoding) Build(root *yaml.Node, idx *index.SpecIndex) error {
headers, hL, hN, err := ExtractMapFlat[*Header](HeadersLabel, root, idx) headers, hL, hN, err := low.ExtractMapFlat[*Header](HeadersLabel, root, idx)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -1,6 +1,7 @@
package v3 package v3
import ( import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@@ -24,7 +25,7 @@ explode: true`
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n Encoding var n Encoding
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)
@@ -52,7 +53,7 @@ headers:
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n Encoding var n Encoding
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)

View File

@@ -22,11 +22,11 @@ type Example struct {
} }
func (ex *Example) FindExtension(ext string) *low.ValueReference[any] { func (ex *Example) FindExtension(ext string) *low.ValueReference[any] {
return FindItemInMap[any](ext, ex.Extensions) return low.FindItemInMap[any](ext, ex.Extensions)
} }
func (ex *Example) Build(root *yaml.Node, idx *index.SpecIndex) error { func (ex *Example) Build(root *yaml.Node, idx *index.SpecIndex) error {
ex.Extensions = ExtractExtensions(root) ex.Extensions = low.ExtractExtensions(root)
_, ln, vn := utils.FindKeyNodeFull(ValueLabel, root.Content) _, ln, vn := utils.FindKeyNodeFull(ValueLabel, root.Content)

View File

@@ -1,6 +1,7 @@
package v3 package v3
import ( import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@@ -19,7 +20,7 @@ x-cake: hot`
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n Example var n Example
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)
@@ -45,7 +46,7 @@ x-cake: hot`
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n Example var n Example
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)
@@ -72,7 +73,7 @@ value:
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n Example var n Example
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)
@@ -103,7 +104,7 @@ value:
idx := index.NewSpecIndex(&idxNode) idx := index.NewSpecIndex(&idxNode)
var n Example var n Example
err := BuildModel(&idxNode, &n) err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err) assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx) err = n.Build(idxNode.Content[0], idx)

View File

@@ -12,7 +12,11 @@ type ExternalDoc struct {
Extensions map[low.KeyReference[string]]low.ValueReference[any] Extensions map[low.KeyReference[string]]low.ValueReference[any]
} }
func (ex *ExternalDoc) FindExtension(ext string) *low.ValueReference[any] {
return low.FindItemInMap[any](ext, ex.Extensions)
}
func (ex *ExternalDoc) Build(root *yaml.Node, idx *index.SpecIndex) error { func (ex *ExternalDoc) Build(root *yaml.Node, idx *index.SpecIndex) error {
ex.Extensions = ExtractExtensions(root) ex.Extensions = low.ExtractExtensions(root)
return nil return nil
} }

View File

@@ -26,10 +26,10 @@ type Header struct {
} }
func (h *Header) Build(root *yaml.Node, idx *index.SpecIndex) error { func (h *Header) Build(root *yaml.Node, idx *index.SpecIndex) error {
h.Extensions = ExtractExtensions(root) h.Extensions = low.ExtractExtensions(root)
// handle examples if set. // handle examples if set.
exps, eErr := ExtractMap[*Example](ExamplesLabel, root, idx) exps, eErr := low.ExtractMap[*Example](ExamplesLabel, root, idx)
if eErr != nil { if eErr != nil {
return eErr return eErr
} }
@@ -47,7 +47,7 @@ func (h *Header) Build(root *yaml.Node, idx *index.SpecIndex) error {
} }
// handle content, if set. // handle content, if set.
con, cErr := ExtractMap[*MediaType](ContentLabel, root, idx) con, cErr := low.ExtractMap[*MediaType](ContentLabel, root, idx)
if cErr != nil { if cErr != nil {
return cErr return cErr
} }

View File

@@ -27,11 +27,11 @@ func (i *Info) Build(root *yaml.Node) error {
contact := Contact{} contact := Contact{}
_, kln, cn := utils.FindKeyNodeFull("contact", root.Content) _, kln, cn := utils.FindKeyNodeFull("contact", root.Content)
go BuildModelAsync(cn, &contact, &wg, &errs) go low.BuildModelAsync(cn, &contact, &wg, &errs)
license := License{} license := License{}
_, kln, ln := utils.FindKeyNodeFull("license", root.Content) _, kln, ln := utils.FindKeyNodeFull("license", root.Content)
go BuildModelAsync(ln, &license, &wg, &errs) go low.BuildModelAsync(ln, &license, &wg, &errs)
//wg.Wait() //wg.Wait()
i.Contact = low.NodeReference[*Contact]{Value: &contact, ValueNode: cn, KeyNode: kln} i.Contact = low.NodeReference[*Contact]{Value: &contact, ValueNode: cn, KeyNode: kln}
i.License = low.NodeReference[*License]{Value: &license, ValueNode: ln, KeyNode: kln} i.License = low.NodeReference[*License]{Value: &license, ValueNode: ln, KeyNode: kln}

View File

@@ -18,11 +18,11 @@ type Link struct {
} }
func (l *Link) FindParameter(pName string) *low.ValueReference[string] { func (l *Link) FindParameter(pName string) *low.ValueReference[string] {
return FindItemInMap[string](pName, l.Parameters.Value) return low.FindItemInMap[string](pName, l.Parameters.Value)
} }
func (l *Link) Build(root *yaml.Node, idx *index.SpecIndex) error { func (l *Link) Build(root *yaml.Node, idx *index.SpecIndex) error {
l.Extensions = ExtractExtensions(root) l.Extensions = low.ExtractExtensions(root)
// extract parameters // extract parameters
_, pl, pv := utils.FindKeyNodeFull(ParametersLabel, root.Content) _, pl, pv := utils.FindKeyNodeFull(ParametersLabel, root.Content)

View File

@@ -16,11 +16,11 @@ type MediaType struct {
} }
func (mt *MediaType) FindPropertyEncoding(eType string) *low.ValueReference[*Encoding] { func (mt *MediaType) FindPropertyEncoding(eType string) *low.ValueReference[*Encoding] {
return FindItemInMap[*Encoding](eType, mt.Encoding.Value) return low.FindItemInMap[*Encoding](eType, mt.Encoding.Value)
} }
func (mt *MediaType) FindExample(eType string) *low.ValueReference[*Example] { func (mt *MediaType) FindExample(eType string) *low.ValueReference[*Example] {
return FindItemInMap[*Example](eType, mt.Examples.Value) return low.FindItemInMap[*Example](eType, mt.Examples.Value)
} }
func (mt *MediaType) GetAllExamples() map[low.KeyReference[string]]low.ValueReference[*Example] { func (mt *MediaType) GetAllExamples() map[low.KeyReference[string]]low.ValueReference[*Example] {
@@ -28,7 +28,7 @@ func (mt *MediaType) GetAllExamples() map[low.KeyReference[string]]low.ValueRefe
} }
func (mt *MediaType) Build(root *yaml.Node, idx *index.SpecIndex) error { func (mt *MediaType) Build(root *yaml.Node, idx *index.SpecIndex) error {
mt.Extensions = ExtractExtensions(root) mt.Extensions = low.ExtractExtensions(root)
// handle example if set. // handle example if set.
_, expLabel, expNode := utils.FindKeyNodeFull(ExampleLabel, root.Content) _, expLabel, expNode := utils.FindKeyNodeFull(ExampleLabel, root.Content)
@@ -46,7 +46,7 @@ func (mt *MediaType) Build(root *yaml.Node, idx *index.SpecIndex) error {
} }
// handle examples if set. // handle examples if set.
exps, expsL, expsN, eErr := ExtractMapFlat[*Example](ExamplesLabel, root, idx) exps, expsL, expsN, eErr := low.ExtractMapFlat[*Example](ExamplesLabel, root, idx)
if eErr != nil { if eErr != nil {
return eErr return eErr
} }
@@ -59,7 +59,7 @@ func (mt *MediaType) Build(root *yaml.Node, idx *index.SpecIndex) error {
} }
// handle encoding // handle encoding
encs, encsL, encsN, encErr := ExtractMapFlat[*Encoding](EncodingLabel, root, idx) encs, encsL, encsN, encErr := low.ExtractMapFlat[*Encoding](EncodingLabel, root, idx)
if encErr != nil { if encErr != nil {
return encErr return encErr
} }

View File

@@ -24,27 +24,27 @@ type OAuthFlows struct {
} }
func (o *OAuthFlows) Build(root *yaml.Node, idx *index.SpecIndex) error { func (o *OAuthFlows) Build(root *yaml.Node, idx *index.SpecIndex) error {
o.Extensions = ExtractExtensions(root) o.Extensions = low.ExtractExtensions(root)
v, vErr := ExtractObject[*OAuthFlow](ImplicitLabel, root, idx) v, vErr := low.ExtractObject[*OAuthFlow](ImplicitLabel, root, idx)
if vErr != nil { if vErr != nil {
return vErr return vErr
} }
o.Implicit = v o.Implicit = v
v, vErr = ExtractObject[*OAuthFlow](PasswordLabel, root, idx) v, vErr = low.ExtractObject[*OAuthFlow](PasswordLabel, root, idx)
if vErr != nil { if vErr != nil {
return vErr return vErr
} }
o.Password = v o.Password = v
v, vErr = ExtractObject[*OAuthFlow](ClientCredentialsLabel, root, idx) v, vErr = low.ExtractObject[*OAuthFlow](ClientCredentialsLabel, root, idx)
if vErr != nil { if vErr != nil {
return vErr return vErr
} }
o.ClientCredentials = v o.ClientCredentials = v
v, vErr = ExtractObject[*OAuthFlow](AuthorizationCodeLabel, root, idx) v, vErr = low.ExtractObject[*OAuthFlow](AuthorizationCodeLabel, root, idx)
if vErr != nil { if vErr != nil {
return vErr return vErr
} }
@@ -62,11 +62,11 @@ type OAuthFlow struct {
} }
func (o *OAuthFlow) FindScope(scope string) *low.ValueReference[string] { func (o *OAuthFlow) FindScope(scope string) *low.ValueReference[string] {
return FindItemInMap[string](scope, o.Scopes.Value) return low.FindItemInMap[string](scope, o.Scopes.Value)
} }
func (o *OAuthFlow) Build(root *yaml.Node, idx *index.SpecIndex) error { func (o *OAuthFlow) Build(root *yaml.Node, idx *index.SpecIndex) error {
o.Extensions = ExtractExtensions(root) o.Extensions = low.ExtractExtensions(root)
var currSec *yaml.Node var currSec *yaml.Node

View File

@@ -31,17 +31,17 @@ type Operation struct {
} }
func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error { func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
o.Extensions = ExtractExtensions(root) o.Extensions = low.ExtractExtensions(root)
// extract externalDocs // extract externalDocs
extDocs, dErr := ExtractObject[*ExternalDoc](ExternalDocsLabel, root, idx) extDocs, dErr := low.ExtractObject[*ExternalDoc](ExternalDocsLabel, root, idx)
if dErr != nil { if dErr != nil {
return dErr return dErr
} }
o.ExternalDocs = extDocs o.ExternalDocs = extDocs
// extract parameters // extract parameters
params, ln, vn, pErr := ExtractArray[*Parameter](ParametersLabel, root, idx) params, ln, vn, pErr := low.ExtractArray[*Parameter](ParametersLabel, root, idx)
if pErr != nil { if pErr != nil {
return pErr return pErr
} }
@@ -54,21 +54,21 @@ func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
} }
// extract request body // extract request body
rBody, rErr := ExtractObject[*RequestBody](RequestBodyLabel, root, idx) rBody, rErr := low.ExtractObject[*RequestBody](RequestBodyLabel, root, idx)
if rErr != nil { if rErr != nil {
return rErr return rErr
} }
o.RequestBody = rBody o.RequestBody = rBody
// extract responses // extract responses
respBody, respErr := ExtractObject[*Responses](ResponsesLabel, root, idx) respBody, respErr := low.ExtractObject[*Responses](ResponsesLabel, root, idx)
if respErr != nil { if respErr != nil {
return rErr return rErr
} }
o.Responses = respBody o.Responses = respBody
// extract callbacks // extract callbacks
callbacks, cbL, cbN, cbErr := ExtractMapFlat[*Callback](CallbacksLabel, root, idx) callbacks, cbL, cbN, cbErr := low.ExtractMapFlat[*Callback](CallbacksLabel, root, idx)
if cbErr != nil { if cbErr != nil {
return cbErr return cbErr
} }
@@ -81,14 +81,14 @@ func (o *Operation) Build(root *yaml.Node, idx *index.SpecIndex) error {
} }
// extract security // extract security
sec, sErr := ExtractObject[*SecurityRequirement](SecurityLabel, root, idx) sec, sErr := low.ExtractObject[*SecurityRequirement](SecurityLabel, root, idx)
if sErr != nil { if sErr != nil {
return sErr return sErr
} }
o.Security = sec o.Security = sec
// extract servers // extract servers
servers, sl, sn, serErr := ExtractArray[*Server](ServersLabel, root, idx) servers, sl, sn, serErr := low.ExtractArray[*Server](ServersLabel, root, idx)
if serErr != nil { if serErr != nil {
return serErr return serErr
} }

View File

@@ -30,15 +30,15 @@ type Parameter struct {
} }
func (p *Parameter) FindContent(cType string) *low.ValueReference[*MediaType] { func (p *Parameter) FindContent(cType string) *low.ValueReference[*MediaType] {
return FindItemInMap[*MediaType](cType, p.Content.Value) return low.FindItemInMap[*MediaType](cType, p.Content.Value)
} }
func (p *Parameter) FindExample(eType string) *low.ValueReference[*Example] { func (p *Parameter) FindExample(eType string) *low.ValueReference[*Example] {
return FindItemInMap[*Example](eType, p.Examples.Value) return low.FindItemInMap[*Example](eType, p.Examples.Value)
} }
func (p *Parameter) Build(root *yaml.Node, idx *index.SpecIndex) error { func (p *Parameter) Build(root *yaml.Node, idx *index.SpecIndex) error {
p.Extensions = ExtractExtensions(root) p.Extensions = low.ExtractExtensions(root)
// handle example if set. // handle example if set.
_, expLabel, expNode := utils.FindKeyNodeFull(ExampleLabel, root.Content) _, expLabel, expNode := utils.FindKeyNodeFull(ExampleLabel, root.Content)
@@ -56,7 +56,7 @@ func (p *Parameter) Build(root *yaml.Node, idx *index.SpecIndex) error {
} }
// handle examples if set. // handle examples if set.
exps, expsL, expsN, eErr := ExtractMapFlat[*Example](ExamplesLabel, root, idx) exps, expsL, expsN, eErr := low.ExtractMapFlat[*Example](ExamplesLabel, root, idx)
if eErr != nil { if eErr != nil {
return eErr return eErr
} }
@@ -69,7 +69,7 @@ func (p *Parameter) Build(root *yaml.Node, idx *index.SpecIndex) error {
} }
// handle content, if set. // handle content, if set.
con, cL, cN, cErr := ExtractMapFlat[*MediaType](ContentLabel, root, idx) con, cL, cN, cErr := low.ExtractMapFlat[*MediaType](ContentLabel, root, idx)
if cErr != nil { if cErr != nil {
return cErr return cErr
} }

View File

@@ -37,7 +37,7 @@ func (p *Paths) FindPath(path string) *low.ValueReference[*PathItem] {
} }
func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error { func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
p.Extensions = ExtractExtensions(root) p.Extensions = low.ExtractExtensions(root)
skip := false skip := false
var currentNode *yaml.Node var currentNode *yaml.Node
@@ -57,7 +57,7 @@ func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
continue continue
} }
var path = PathItem{} var path = PathItem{}
err := BuildModel(pathNode, &path) err := low.BuildModel(pathNode, &path)
if err != nil { if err != nil {
} }
@@ -98,7 +98,7 @@ type PathItem struct {
} }
func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error { func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
p.Extensions = ExtractExtensions(root) p.Extensions = low.ExtractExtensions(root)
skip := false skip := false
var currentNode *yaml.Node var currentNode *yaml.Node
@@ -108,7 +108,7 @@ func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
var ops []low.NodeReference[*Operation] var ops []low.NodeReference[*Operation]
if ok, _, _ := utils.IsNodeRefValue(root); ok { if ok, _, _ := utils.IsNodeRefValue(root); ok {
r := LocateRefNode(root, idx) r := low.LocateRefNode(root, idx)
if r != nil { if r != nil {
root = r root = r
} else { } else {
@@ -133,7 +133,7 @@ func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
var op Operation var op Operation
wg.Add(1) wg.Add(1)
go BuildModelAsync(pathNode, &op, &wg, &errors) go low.BuildModelAsync(pathNode, &op, &wg, &errors)
opRef := low.NodeReference[*Operation]{ opRef := low.NodeReference[*Operation]{
Value: &op, Value: &op,
@@ -176,7 +176,7 @@ func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
//build out the operation. //build out the operation.
if ok, _, _ := utils.IsNodeRefValue(op.ValueNode); ok { if ok, _, _ := utils.IsNodeRefValue(op.ValueNode); ok {
r := LocateRefNode(op.ValueNode, idx) r := low.LocateRefNode(op.ValueNode, idx)
if r != nil { if r != nil {
op.ValueNode = r op.ValueNode = r
} else { } else {

View File

@@ -14,14 +14,14 @@ type RequestBody struct {
} }
func (rb *RequestBody) FindContent(cType string) *low.ValueReference[*MediaType] { func (rb *RequestBody) FindContent(cType string) *low.ValueReference[*MediaType] {
return FindItemInMap[*MediaType](cType, rb.Content.Value) return low.FindItemInMap[*MediaType](cType, rb.Content.Value)
} }
func (rb *RequestBody) Build(root *yaml.Node, idx *index.SpecIndex) error { func (rb *RequestBody) Build(root *yaml.Node, idx *index.SpecIndex) error {
rb.Extensions = ExtractExtensions(root) rb.Extensions = low.ExtractExtensions(root)
// handle content, if set. // handle content, if set.
con, cL, cN, cErr := ExtractMapFlat[*MediaType](ContentLabel, root, idx) con, cL, cN, cErr := low.ExtractMapFlat[*MediaType](ContentLabel, root, idx)
if cErr != nil { if cErr != nil {
return cErr return cErr
} }

View File

@@ -1,98 +1,98 @@
package v3 package v3
import ( import (
"github.com/pb33f/libopenapi/datamodel/low" "github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils" "github.com/pb33f/libopenapi/utils"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
const ( const (
LinksLabel = "links" LinksLabel = "links"
) )
type Responses struct { type Responses struct {
Codes map[low.KeyReference[string]]low.ValueReference[*Response] Codes map[low.KeyReference[string]]low.ValueReference[*Response]
Default low.NodeReference[*Response] Default low.NodeReference[*Response]
} }
func (r *Responses) Build(root *yaml.Node, idx *index.SpecIndex) error { func (r *Responses) Build(root *yaml.Node, idx *index.SpecIndex) error {
if utils.IsNodeMap(root) { if utils.IsNodeMap(root) {
codes, err := ExtractMapFlatNoLookup[*Response](root, idx) codes, err := low.ExtractMapFlatNoLookup[*Response](root, idx)
if err != nil { if err != nil {
return err return err
} }
if codes != nil { if codes != nil {
r.Codes = codes r.Codes = codes
} }
} }
return nil return nil
} }
func (r *Responses) FindResponseByCode(code string) *low.ValueReference[*Response] { func (r *Responses) FindResponseByCode(code string) *low.ValueReference[*Response] {
return FindItemInMap[*Response](code, r.Codes) return low.FindItemInMap[*Response](code, r.Codes)
} }
type Response struct { type Response struct {
Description low.NodeReference[string] Description low.NodeReference[string]
Headers low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]] Headers low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]]
Content low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*MediaType]] Content low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*MediaType]]
Extensions map[low.KeyReference[string]]low.ValueReference[any] Extensions map[low.KeyReference[string]]low.ValueReference[any]
Links low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Link]] Links low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Link]]
} }
func (r *Response) FindContent(cType string) *low.ValueReference[*MediaType] { func (r *Response) FindContent(cType string) *low.ValueReference[*MediaType] {
return FindItemInMap[*MediaType](cType, r.Content.Value) return low.FindItemInMap[*MediaType](cType, r.Content.Value)
} }
func (r *Response) FindHeader(hType string) *low.ValueReference[*Header] { func (r *Response) FindHeader(hType string) *low.ValueReference[*Header] {
return FindItemInMap[*Header](hType, r.Headers.Value) return low.FindItemInMap[*Header](hType, r.Headers.Value)
} }
func (r *Response) FindLink(hType string) *low.ValueReference[*Link] { func (r *Response) FindLink(hType string) *low.ValueReference[*Link] {
return FindItemInMap[*Link](hType, r.Links.Value) return low.FindItemInMap[*Link](hType, r.Links.Value)
} }
func (r *Response) Build(root *yaml.Node, idx *index.SpecIndex) error { func (r *Response) Build(root *yaml.Node, idx *index.SpecIndex) error {
r.Extensions = ExtractExtensions(root) r.Extensions = low.ExtractExtensions(root)
// extract headers // extract headers
headers, lN, kN, err := ExtractMapFlat[*Header](HeadersLabel, root, idx) headers, lN, kN, err := low.ExtractMapFlat[*Header](HeadersLabel, root, idx)
if err != nil { if err != nil {
return err return err
} }
if headers != nil { if headers != nil {
r.Headers = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]]{ r.Headers = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Header]]{
Value: headers, Value: headers,
KeyNode: lN, KeyNode: lN,
ValueNode: kN, ValueNode: kN,
} }
} }
con, clN, cN, cErr := ExtractMapFlat[*MediaType](ContentLabel, root, idx) con, clN, cN, cErr := low.ExtractMapFlat[*MediaType](ContentLabel, root, idx)
if cErr != nil { if cErr != nil {
return cErr return cErr
} }
if con != nil { if con != nil {
r.Content = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*MediaType]]{ r.Content = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*MediaType]]{
Value: con, Value: con,
KeyNode: clN, KeyNode: clN,
ValueNode: cN, ValueNode: cN,
} }
} }
// handle links if set // handle links if set
links, linkLabel, linkValue, lErr := ExtractMapFlat[*Link](LinksLabel, root, idx) links, linkLabel, linkValue, lErr := low.ExtractMapFlat[*Link](LinksLabel, root, idx)
if lErr != nil { if lErr != nil {
return lErr return lErr
} }
if links != nil { if links != nil {
r.Links = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Link]]{ r.Links = low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Link]]{
Value: links, Value: links,
KeyNode: linkLabel, KeyNode: linkLabel,
ValueNode: linkValue, ValueNode: linkValue,
} }
} }
return nil return nil
} }

View File

@@ -1,6 +1,7 @@
package v3 package v3
import ( import (
"fmt"
"github.com/pb33f/libopenapi/datamodel/low" "github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils" "github.com/pb33f/libopenapi/utils"
@@ -60,7 +61,7 @@ type Schema struct {
} }
func (s *Schema) FindProperty(name string) *low.ValueReference[*Schema] { func (s *Schema) FindProperty(name string) *low.ValueReference[*Schema] {
return FindItemInMap[*Schema](name, s.Properties.Value) return low.FindItemInMap[*Schema](name, s.Properties.Value)
} }
func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error { func (s *Schema) Build(root *yaml.Node, idx *index.SpecIndex) error {
@@ -84,7 +85,7 @@ func (s *Schema) BuildLevel(root *yaml.Node, idx *index.SpecIndex, level int) er
_, addPLabel, addPNode := utils.FindKeyNodeFull(AdditionalPropertiesLabel, root.Content) _, addPLabel, addPNode := utils.FindKeyNodeFull(AdditionalPropertiesLabel, root.Content)
if addPNode != nil { if addPNode != nil {
if utils.IsNodeMap(addPNode) { if utils.IsNodeMap(addPNode) {
schema, serr := ExtractObjectRaw[*Schema](addPNode, idx) schema, serr := low.ExtractObjectRaw[*Schema](addPNode, idx)
if serr != nil { if serr != nil {
return serr return serr
} }
@@ -101,7 +102,7 @@ func (s *Schema) BuildLevel(root *yaml.Node, idx *index.SpecIndex, level int) er
_, discLabel, discNode := utils.FindKeyNodeFull(DiscriminatorLabel, root.Content) _, discLabel, discNode := utils.FindKeyNodeFull(DiscriminatorLabel, root.Content)
if discNode != nil { if discNode != nil {
var discriminator Discriminator var discriminator Discriminator
err := BuildModel(discNode, &discriminator) err := low.BuildModel(discNode, &discriminator)
if err != nil { if err != nil {
return err return err
} }
@@ -112,7 +113,7 @@ func (s *Schema) BuildLevel(root *yaml.Node, idx *index.SpecIndex, level int) er
_, extDocLabel, extDocNode := utils.FindKeyNodeFull(ExternalDocsLabel, root.Content) _, extDocLabel, extDocNode := utils.FindKeyNodeFull(ExternalDocsLabel, root.Content)
if extDocNode != nil { if extDocNode != nil {
var exDoc ExternalDoc var exDoc ExternalDoc
err := BuildModel(extDocNode, &exDoc) err := low.BuildModel(extDocNode, &exDoc)
if err != nil { if err != nil {
return err return err
} }
@@ -127,7 +128,7 @@ func (s *Schema) BuildLevel(root *yaml.Node, idx *index.SpecIndex, level int) er
_, xmlLabel, xmlNode := utils.FindKeyNodeFull(XMLLabel, root.Content) _, xmlLabel, xmlNode := utils.FindKeyNodeFull(XMLLabel, root.Content)
if xmlNode != nil { if xmlNode != nil {
var xml XML var xml XML
err := BuildModel(xmlNode, &xml) err := low.BuildModel(xmlNode, &xml)
if err != nil { if err != nil {
return err return err
} }
@@ -152,14 +153,14 @@ func (s *Schema) BuildLevel(root *yaml.Node, idx *index.SpecIndex, level int) er
// check our prop isn't reference // check our prop isn't reference
if h, _, _ := utils.IsNodeRefValue(prop); h { if h, _, _ := utils.IsNodeRefValue(prop); h {
ref := LocateRefNode(prop, idx) ref := low.LocateRefNode(prop, idx)
if ref != nil { if ref != nil {
prop = ref prop = ref
} }
} }
var property Schema var property Schema
err := BuildModel(prop, &property) err := low.BuildModel(prop, &property)
if err != nil { if err != nil {
return err return err
} }
@@ -237,7 +238,7 @@ func (s *Schema) BuildLevel(root *yaml.Node, idx *index.SpecIndex, level int) er
} }
func (s *Schema) extractExtensions(root *yaml.Node) { func (s *Schema) extractExtensions(root *yaml.Node) {
s.Extensions = ExtractExtensions(root) s.Extensions = low.ExtractExtensions(root)
} }
func buildSchema(schemas *[]low.NodeReference[*Schema], attribute string, rootNode *yaml.Node, level int, func buildSchema(schemas *[]low.NodeReference[*Schema], attribute string, rootNode *yaml.Node, level int,
@@ -248,7 +249,7 @@ func buildSchema(schemas *[]low.NodeReference[*Schema], attribute string, rootNo
if valueNode != nil { if valueNode != nil {
var build = func(kn *yaml.Node, vn *yaml.Node) *low.NodeReference[*Schema] { var build = func(kn *yaml.Node, vn *yaml.Node) *low.NodeReference[*Schema] {
var schema Schema var schema Schema
err := BuildModel(vn, &schema) err := low.BuildModel(vn, &schema)
if err != nil { if err != nil {
*errors = append(*errors, err) *errors = append(*errors, err)
return nil return nil
@@ -284,3 +285,41 @@ func buildSchema(schemas *[]low.NodeReference[*Schema], attribute string, rootNo
//wg.Done() //wg.Done()
return labelNode, valueNode return labelNode, valueNode
} }
func ExtractSchema(root *yaml.Node, idx *index.SpecIndex) (*low.NodeReference[*Schema], error) {
var schLabel, schNode *yaml.Node
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
// locate reference in index.
ref := low.LocateRefNode(root, idx)
if ref != nil {
schNode = ref
schLabel = rl
} else {
return nil, fmt.Errorf("schema build failed: reference cannot be found: %s", root.Content[1].Value)
}
} else {
_, schLabel, schNode = utils.FindKeyNodeFull(SchemaLabel, root.Content)
if schNode != nil {
if h, _, _ := utils.IsNodeRefValue(schNode); h {
ref := low.LocateRefNode(schNode, idx)
if ref != nil {
schNode = ref
}
}
}
}
if schNode != nil {
var schema Schema
err := low.BuildModel(schNode, &schema)
if err != nil {
return nil, err
}
err = schema.Build(schNode, idx)
if err != nil {
return nil, err
}
return &low.NodeReference[*Schema]{Value: &schema, KeyNode: schLabel, ValueNode: schNode}, nil
}
return nil, nil
}

View File

@@ -1,6 +1,7 @@
package v3 package v3
import ( import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"testing" "testing"
@@ -108,7 +109,7 @@ additionalProperties: true `
assert.NoError(t, mErr) assert.NoError(t, mErr)
sch := Schema{} sch := Schema{}
mbErr := BuildModel(&rootNode, &sch) mbErr := low.BuildModel(&rootNode, &sch)
assert.NoError(t, mbErr) assert.NoError(t, mbErr)
schErr := sch.Build(rootNode.Content[0], nil) schErr := sch.Build(rootNode.Content[0], nil)

View File

@@ -30,9 +30,9 @@ type SecurityRequirement struct {
} }
func (ss *SecurityScheme) Build(root *yaml.Node, idx *index.SpecIndex) error { func (ss *SecurityScheme) Build(root *yaml.Node, idx *index.SpecIndex) error {
ss.Extensions = ExtractExtensions(root) ss.Extensions = low.ExtractExtensions(root)
oa, oaErr := ExtractObject[*OAuthFlows](OAuthFlowsLabel, root, idx) oa, oaErr := low.ExtractObject[*OAuthFlows](OAuthFlowsLabel, root, idx)
if oaErr != nil { if oaErr != nil {
return oaErr return oaErr
} }

View File

@@ -34,7 +34,7 @@ func (s *Server) Build(root *yaml.Node, idx *index.SpecIndex) error {
continue continue
} }
variable := ServerVariable{} variable := ServerVariable{}
err := BuildModel(varNode, &variable) err := low.BuildModel(varNode, &variable)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -19,10 +19,10 @@ type Tag struct {
} }
func (t *Tag) Build(root *yaml.Node, idx *index.SpecIndex) error { func (t *Tag) Build(root *yaml.Node, idx *index.SpecIndex) error {
t.Extensions = ExtractExtensions(root) t.Extensions = low.ExtractExtensions(root)
// extract externalDocs // extract externalDocs
extDocs, dErr := ExtractObject[*ExternalDoc](ExternalDocsLabel, root, idx) extDocs, dErr := low.ExtractObject[*ExternalDoc](ExternalDocsLabel, root, idx)
if dErr != nil { if dErr != nil {
return dErr return dErr
} }

View File

@@ -15,6 +15,6 @@ type XML struct {
} }
func (x *XML) Build(root *yaml.Node) error { func (x *XML) Build(root *yaml.Node) error {
x.Extensions = ExtractExtensions(root) x.Extensions = low.ExtractExtensions(root)
return nil return nil
} }

View File

@@ -1,9 +1,7 @@
package datamodel package low
import ( import (
"fmt" "fmt"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/datamodel/low/3.0"
"github.com/pb33f/libopenapi/index" "github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils" "github.com/pb33f/libopenapi/utils"
"github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath" "github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath"
@@ -13,14 +11,7 @@ import (
"sync" "sync"
) )
var KnownSchemas map[string]low.NodeReference[*v3.Schema] func FindItemInMap[T any](item string, collection map[KeyReference[string]]ValueReference[T]) *ValueReference[T] {
func init() {
KnownSchemas = make(map[string]low.NodeReference[*v3.Schema])
}
func FindItemInMap[T any](item string, collection map[low.KeyReference[string]]low.ValueReference[T]) *low.ValueReference[T] {
for n, o := range collection { for n, o := range collection {
if n.Value == item { if n.Value == item {
return &o return &o
@@ -29,44 +20,6 @@ func FindItemInMap[T any](item string, collection map[low.KeyReference[string]]l
return nil return nil
} }
func ExtractSchema(root *yaml.Node, idx *index.SpecIndex) (*low.NodeReference[*v3.Schema], error) {
var schLabel, schNode *yaml.Node
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
// locate reference in index.
ref := LocateRefNode(root, idx)
if ref != nil {
schNode = ref
schLabel = rl
} else {
return nil, fmt.Errorf("schema build failed: reference cannot be found: %s", root.Content[1].Value)
}
} else {
_, schLabel, schNode = utils.FindKeyNodeFull(v3.SchemaLabel, root.Content)
if schNode != nil {
if h, _, _ := utils.IsNodeRefValue(schNode); h {
ref := LocateRefNode(schNode, idx)
if ref != nil {
schNode = ref
}
}
}
}
if schNode != nil {
var schema v3.Schema
err := v3.BuildModel(schNode, &schema)
if err != nil {
return nil, err
}
err = schema.Build(schNode, idx)
if err != nil {
return nil, err
}
return &low.NodeReference[*v3.Schema]{Value: &schema, KeyNode: schLabel, ValueNode: schNode}, nil
}
return nil, nil
}
var mapLock sync.Mutex var mapLock sync.Mutex
func LocateRefNode(root *yaml.Node, idx *index.SpecIndex) *yaml.Node { func LocateRefNode(root *yaml.Node, idx *index.SpecIndex) *yaml.Node {
@@ -111,9 +64,9 @@ func LocateRefNode(root *yaml.Node, idx *index.SpecIndex) *yaml.Node {
return nil return nil
} }
func ExtractObjectRaw[T low.Buildable[N], N any](root *yaml.Node, idx *index.SpecIndex) (T, error) { func ExtractObjectRaw[T Buildable[N], N any](root *yaml.Node, idx *index.SpecIndex) (T, error) {
var n T = new(N) var n T = new(N)
err := v3.BuildModel(root, n) err := BuildModel(root, n)
if err != nil { if err != nil {
return n, err return n, err
} }
@@ -124,7 +77,7 @@ func ExtractObjectRaw[T low.Buildable[N], N any](root *yaml.Node, idx *index.Spe
return n, nil return n, nil
} }
func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (low.NodeReference[T], error) { func ExtractObject[T Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (NodeReference[T], error) {
var ln, vn *yaml.Node var ln, vn *yaml.Node
if rf, rl, _ := utils.IsNodeRefValue(root); rf { if rf, rl, _ := utils.IsNodeRefValue(root); rf {
// locate reference in index. // locate reference in index.
@@ -133,7 +86,7 @@ func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node, idx
vn = ref vn = ref
ln = rl ln = rl
} else { } else {
return low.NodeReference[T]{}, fmt.Errorf("object build failed: reference cannot be found: %s", return NodeReference[T]{}, fmt.Errorf("object build failed: reference cannot be found: %s",
root.Content[1].Value) root.Content[1].Value)
} }
} else { } else {
@@ -144,32 +97,32 @@ func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node, idx
if ref != nil { if ref != nil {
vn = ref vn = ref
} else { } else {
return low.NodeReference[T]{}, fmt.Errorf("object build failed: reference cannot be found: %s", return NodeReference[T]{}, fmt.Errorf("object build failed: reference cannot be found: %s",
root.Content[1].Value) root.Content[1].Value)
} }
} }
} }
} }
var n T = new(N) var n T = new(N)
err := v3.BuildModel(vn, n) err := BuildModel(vn, n)
if err != nil { if err != nil {
return low.NodeReference[T]{}, err return NodeReference[T]{}, err
} }
if ln == nil { if ln == nil {
return low.NodeReference[T]{}, nil return NodeReference[T]{}, nil
} }
err = n.Build(vn, idx) err = n.Build(vn, idx)
if err != nil { if err != nil {
return low.NodeReference[T]{}, err return NodeReference[T]{}, err
} }
return low.NodeReference[T]{ return NodeReference[T]{
Value: n, Value: n,
KeyNode: ln, KeyNode: ln,
ValueNode: vn, ValueNode: vn,
}, nil }, nil
} }
func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) ([]low.ValueReference[T], func ExtractArray[T Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) ([]ValueReference[T],
*yaml.Node, *yaml.Node, error) { *yaml.Node, *yaml.Node, error) {
var ln, vn *yaml.Node var ln, vn *yaml.Node
if rf, rl, _ := utils.IsNodeRefValue(root); rf { if rf, rl, _ := utils.IsNodeRefValue(root); rf {
@@ -179,7 +132,7 @@ func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node, idx
vn = ref vn = ref
ln = rl ln = rl
} else { } else {
return []low.ValueReference[T]{}, nil, nil, fmt.Errorf("array build failed: reference cannot be found: %s", return []ValueReference[T]{}, nil, nil, fmt.Errorf("array build failed: reference cannot be found: %s",
root.Content[1].Value) root.Content[1].Value)
} }
} else { } else {
@@ -190,13 +143,13 @@ func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node, idx
if ref != nil { if ref != nil {
vn = ref vn = ref
} else { } else {
return []low.ValueReference[T]{}, nil, nil, fmt.Errorf("array build failed: reference cannot be found: %s", return []ValueReference[T]{}, nil, nil, fmt.Errorf("array build failed: reference cannot be found: %s",
root.Content[1].Value) root.Content[1].Value)
} }
} }
} }
} }
var items []low.ValueReference[T] var items []ValueReference[T]
if vn != nil && ln != nil { if vn != nil && ln != nil {
for _, node := range vn.Content { for _, node := range vn.Content {
if rf, _, _ := utils.IsNodeRefValue(node); rf { if rf, _, _ := utils.IsNodeRefValue(node); rf {
@@ -204,20 +157,20 @@ func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node, idx
if ref != nil { if ref != nil {
node = ref node = ref
} else { } else {
return []low.ValueReference[T]{}, nil, nil, fmt.Errorf("array build failed: reference cannot be found: %s", return []ValueReference[T]{}, nil, nil, fmt.Errorf("array build failed: reference cannot be found: %s",
root.Content[1].Value) root.Content[1].Value)
} }
} }
var n T = new(N) var n T = new(N)
err := v3.BuildModel(node, n) err := BuildModel(node, n)
if err != nil { if err != nil {
return []low.ValueReference[T]{}, ln, vn, err return []ValueReference[T]{}, ln, vn, err
} }
berr := n.Build(node, idx) berr := n.Build(node, idx)
if berr != nil { if berr != nil {
return nil, ln, vn, berr return nil, ln, vn, berr
} }
items = append(items, low.ValueReference[T]{ items = append(items, ValueReference[T]{
Value: n, Value: n,
ValueNode: node, ValueNode: node,
}) })
@@ -226,8 +179,8 @@ func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node, idx
return items, ln, vn, nil return items, ln, vn, nil
} }
func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node, idx *index.SpecIndex) (map[low.KeyReference[string]]low.ValueReference[PT], error) { func ExtractMapFlatNoLookup[PT Buildable[N], N any](root *yaml.Node, idx *index.SpecIndex) (map[KeyReference[string]]ValueReference[PT], error) {
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT]) valueMap := make(map[KeyReference[string]]ValueReference[PT])
if utils.IsNodeMap(root) { if utils.IsNodeMap(root) {
var currentKey *yaml.Node var currentKey *yaml.Node
for i, node := range root.Content { for i, node := range root.Content {
@@ -247,7 +200,7 @@ func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node, idx *in
} }
var n PT = new(N) var n PT = new(N)
err := v3.BuildModel(node, n) err := BuildModel(node, n)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -255,10 +208,10 @@ func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node, idx *in
if berr != nil { if berr != nil {
return nil, berr return nil, berr
} }
valueMap[low.KeyReference[string]{ valueMap[KeyReference[string]{
Value: currentKey.Value, Value: currentKey.Value,
KeyNode: currentKey, KeyNode: currentKey,
}] = low.ValueReference[PT]{ }] = ValueReference[PT]{
Value: n, Value: n,
ValueNode: node, ValueNode: node,
} }
@@ -267,7 +220,7 @@ func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node, idx *in
return valueMap, nil return valueMap, nil
} }
func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (map[low.KeyReference[string]]low.ValueReference[PT], *yaml.Node, *yaml.Node, error) { func ExtractMapFlat[PT Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (map[KeyReference[string]]ValueReference[PT], *yaml.Node, *yaml.Node, error) {
var labelNode, valueNode *yaml.Node var labelNode, valueNode *yaml.Node
if rf, rl, _ := utils.IsNodeRefValue(root); rf { if rf, rl, _ := utils.IsNodeRefValue(root); rf {
// locate reference in index. // locate reference in index.
@@ -295,7 +248,7 @@ func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node, i
} }
if valueNode != nil { if valueNode != nil {
var currentLabelNode *yaml.Node var currentLabelNode *yaml.Node
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT]) valueMap := make(map[KeyReference[string]]ValueReference[PT])
for i, en := range valueNode.Content { for i, en := range valueNode.Content {
if i%2 == 0 { if i%2 == 0 {
currentLabelNode = en currentLabelNode = en
@@ -317,7 +270,7 @@ func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node, i
continue // yo, don't pay any attention to extensions, not here anyway. continue // yo, don't pay any attention to extensions, not here anyway.
} }
var n PT = new(N) var n PT = new(N)
err := v3.BuildModel(en, n) err := BuildModel(en, n)
if err != nil { if err != nil {
return nil, labelNode, valueNode, err return nil, labelNode, valueNode, err
} }
@@ -325,10 +278,10 @@ func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node, i
if berr != nil { if berr != nil {
return nil, labelNode, valueNode, berr return nil, labelNode, valueNode, berr
} }
valueMap[low.KeyReference[string]{ valueMap[KeyReference[string]{
Value: currentLabelNode.Value, Value: currentLabelNode.Value,
KeyNode: currentLabelNode, KeyNode: currentLabelNode,
}] = low.ValueReference[PT]{ }] = ValueReference[PT]{
Value: n, Value: n,
ValueNode: en, ValueNode: en,
} }
@@ -338,7 +291,7 @@ func ExtractMapFlat[PT low.Buildable[N], N any](label string, root *yaml.Node, i
return nil, labelNode, valueNode, nil return nil, labelNode, valueNode, nil
} }
func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[PT], error) { func ExtractMap[PT Buildable[N], N any](label string, root *yaml.Node, idx *index.SpecIndex) (map[KeyReference[string]]map[KeyReference[string]]ValueReference[PT], error) {
var labelNode, valueNode *yaml.Node var labelNode, valueNode *yaml.Node
if rf, rl, _ := utils.IsNodeRefValue(root); rf { if rf, rl, _ := utils.IsNodeRefValue(root); rf {
// locate reference in index. // locate reference in index.
@@ -355,7 +308,7 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *
if valueNode != nil { if valueNode != nil {
var currentLabelNode *yaml.Node var currentLabelNode *yaml.Node
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT]) valueMap := make(map[KeyReference[string]]ValueReference[PT])
for i, en := range valueNode.Content { for i, en := range valueNode.Content {
if i%2 == 0 { if i%2 == 0 {
currentLabelNode = en currentLabelNode = en
@@ -365,7 +318,7 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *
continue // yo, don't pay any attention to extensions, not here anyway. continue // yo, don't pay any attention to extensions, not here anyway.
} }
var n PT = new(N) var n PT = new(N)
err := v3.BuildModel(en, n) err := BuildModel(en, n)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -373,16 +326,16 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *
if berr != nil { if berr != nil {
return nil, berr return nil, berr
} }
valueMap[low.KeyReference[string]{ valueMap[KeyReference[string]{
Value: currentLabelNode.Value, Value: currentLabelNode.Value,
KeyNode: currentLabelNode, KeyNode: currentLabelNode,
}] = low.ValueReference[PT]{ }] = ValueReference[PT]{
Value: n, Value: n,
ValueNode: en, ValueNode: en,
} }
} }
resMap := make(map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[PT]) resMap := make(map[KeyReference[string]]map[KeyReference[string]]ValueReference[PT])
resMap[low.KeyReference[string]{ resMap[KeyReference[string]{
Value: labelNode.Value, Value: labelNode.Value,
KeyNode: labelNode, KeyNode: labelNode,
}] = valueMap }] = valueMap
@@ -391,52 +344,52 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *
return nil, nil return nil, nil
} }
func ExtractExtensions(root *yaml.Node) map[low.KeyReference[string]]low.ValueReference[any] { func ExtractExtensions(root *yaml.Node) map[KeyReference[string]]ValueReference[any] {
extensions := utils.FindExtensionNodes(root.Content) extensions := utils.FindExtensionNodes(root.Content)
extensionMap := make(map[low.KeyReference[string]]low.ValueReference[any]) extensionMap := make(map[KeyReference[string]]ValueReference[any])
for _, ext := range extensions { for _, ext := range extensions {
if utils.IsNodeMap(ext.Value) { if utils.IsNodeMap(ext.Value) {
var v interface{} var v interface{}
_ = ext.Value.Decode(&v) _ = ext.Value.Decode(&v)
extensionMap[low.KeyReference[string]{ extensionMap[KeyReference[string]{
Value: ext.Key.Value, Value: ext.Key.Value,
KeyNode: ext.Key, KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: v, ValueNode: ext.Value} }] = ValueReference[any]{Value: v, ValueNode: ext.Value}
} }
if utils.IsNodeStringValue(ext.Value) { if utils.IsNodeStringValue(ext.Value) {
extensionMap[low.KeyReference[string]{ extensionMap[KeyReference[string]{
Value: ext.Key.Value, Value: ext.Key.Value,
KeyNode: ext.Key, KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: ext.Value.Value, ValueNode: ext.Value} }] = ValueReference[any]{Value: ext.Value.Value, ValueNode: ext.Value}
} }
if utils.IsNodeFloatValue(ext.Value) { if utils.IsNodeFloatValue(ext.Value) {
fv, _ := strconv.ParseFloat(ext.Value.Value, 64) fv, _ := strconv.ParseFloat(ext.Value.Value, 64)
extensionMap[low.KeyReference[string]{ extensionMap[KeyReference[string]{
Value: ext.Key.Value, Value: ext.Key.Value,
KeyNode: ext.Key, KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: fv, ValueNode: ext.Value} }] = ValueReference[any]{Value: fv, ValueNode: ext.Value}
} }
if utils.IsNodeIntValue(ext.Value) { if utils.IsNodeIntValue(ext.Value) {
iv, _ := strconv.ParseInt(ext.Value.Value, 10, 64) iv, _ := strconv.ParseInt(ext.Value.Value, 10, 64)
extensionMap[low.KeyReference[string]{ extensionMap[KeyReference[string]{
Value: ext.Key.Value, Value: ext.Key.Value,
KeyNode: ext.Key, KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: iv, ValueNode: ext.Value} }] = ValueReference[any]{Value: iv, ValueNode: ext.Value}
} }
if utils.IsNodeBoolValue(ext.Value) { if utils.IsNodeBoolValue(ext.Value) {
bv, _ := strconv.ParseBool(ext.Value.Value) bv, _ := strconv.ParseBool(ext.Value.Value)
extensionMap[low.KeyReference[string]{ extensionMap[KeyReference[string]{
Value: ext.Key.Value, Value: ext.Key.Value,
KeyNode: ext.Key, KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: bv, ValueNode: ext.Value} }] = ValueReference[any]{Value: bv, ValueNode: ext.Value}
} }
if utils.IsNodeArray(ext.Value) { if utils.IsNodeArray(ext.Value) {
var v []interface{} var v []interface{}
_ = ext.Value.Decode(&v) _ = ext.Value.Decode(&v)
extensionMap[low.KeyReference[string]{ extensionMap[KeyReference[string]{
Value: ext.Key.Value, Value: ext.Key.Value,
KeyNode: ext.Key, KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: v, ValueNode: ext.Value} }] = ValueReference[any]{Value: v, ValueNode: ext.Value}
} }
} }
return extensionMap return extensionMap

View File

@@ -1,8 +1,7 @@
package v3 package low
import ( import (
"fmt" "fmt"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/utils" "github.com/pb33f/libopenapi/utils"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"reflect" "reflect"
@@ -61,11 +60,11 @@ func BuildModel(node *yaml.Node, model interface{}) error {
func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) error { func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) error {
switch field.Type() { switch field.Type() {
case reflect.TypeOf(map[string]low.NodeReference[any]{}): case reflect.TypeOf(map[string]NodeReference[any]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeMap(valueNode) { if utils.IsNodeMap(valueNode) {
if field.CanSet() { if field.CanSet() {
items := make(map[string]low.NodeReference[any]) items := make(map[string]NodeReference[any])
var currentLabel string var currentLabel string
for i, sliceItem := range valueNode.Content { for i, sliceItem := range valueNode.Content {
if i%2 == 0 { if i%2 == 0 {
@@ -77,7 +76,7 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
if err != nil { if err != nil {
return err return err
} }
items[currentLabel] = low.NodeReference[any]{ items[currentLabel] = NodeReference[any]{
Value: decoded, Value: decoded,
ValueNode: sliceItem, ValueNode: sliceItem,
KeyNode: valueNode, KeyNode: valueNode,
@@ -89,18 +88,18 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
break break
case reflect.TypeOf(map[string]low.NodeReference[string]{}): case reflect.TypeOf(map[string]NodeReference[string]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeMap(valueNode) { if utils.IsNodeMap(valueNode) {
if field.CanSet() { if field.CanSet() {
items := make(map[string]low.NodeReference[string]) items := make(map[string]NodeReference[string])
var currentLabel string var currentLabel string
for i, sliceItem := range valueNode.Content { for i, sliceItem := range valueNode.Content {
if i%2 == 0 { if i%2 == 0 {
currentLabel = sliceItem.Value currentLabel = sliceItem.Value
continue continue
} }
items[currentLabel] = low.NodeReference[string]{ items[currentLabel] = NodeReference[string]{
Value: sliceItem.Value, Value: sliceItem.Value,
ValueNode: sliceItem, ValueNode: sliceItem,
KeyNode: valueNode, KeyNode: valueNode,
@@ -111,7 +110,7 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf(low.NodeReference[any]{}): case reflect.TypeOf(NodeReference[any]{}):
if valueNode != nil { if valueNode != nil {
var decoded interface{} var decoded interface{}
err := valueNode.Decode(&decoded) err := valueNode.Decode(&decoded)
@@ -120,24 +119,24 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
if utils.IsNodeMap(valueNode) { if utils.IsNodeMap(valueNode) {
if field.CanSet() { if field.CanSet() {
or := low.NodeReference[any]{Value: decoded, ValueNode: valueNode} or := NodeReference[any]{Value: decoded, ValueNode: valueNode}
field.Set(reflect.ValueOf(or)) field.Set(reflect.ValueOf(or))
} }
} }
} }
break break
case reflect.TypeOf([]low.NodeReference[any]{}): case reflect.TypeOf([]NodeReference[any]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeArray(valueNode) { if utils.IsNodeArray(valueNode) {
if field.CanSet() { if field.CanSet() {
var items []low.NodeReference[any] var items []NodeReference[any]
for _, sliceItem := range valueNode.Content { for _, sliceItem := range valueNode.Content {
var decoded map[string]interface{} var decoded map[string]interface{}
err := sliceItem.Decode(&decoded) err := sliceItem.Decode(&decoded)
if err != nil { if err != nil {
return err return err
} }
items = append(items, low.NodeReference[any]{ items = append(items, NodeReference[any]{
Value: decoded, Value: decoded,
ValueNode: sliceItem, ValueNode: sliceItem,
KeyNode: valueNode, KeyNode: valueNode,
@@ -148,11 +147,11 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf(low.NodeReference[string]{}): case reflect.TypeOf(NodeReference[string]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeStringValue(valueNode) { if utils.IsNodeStringValue(valueNode) {
if field.CanSet() { if field.CanSet() {
nr := low.NodeReference[string]{ nr := NodeReference[string]{
Value: valueNode.Value, Value: valueNode.Value,
ValueNode: valueNode, ValueNode: valueNode,
KeyNode: keyNode, KeyNode: keyNode,
@@ -162,12 +161,12 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf(low.NodeReference[bool]{}): case reflect.TypeOf(NodeReference[bool]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeBoolValue(valueNode) { if utils.IsNodeBoolValue(valueNode) {
if field.CanSet() { if field.CanSet() {
bv, _ := strconv.ParseBool(valueNode.Value) bv, _ := strconv.ParseBool(valueNode.Value)
nr := low.NodeReference[bool]{ nr := NodeReference[bool]{
Value: bv, Value: bv,
ValueNode: valueNode, ValueNode: valueNode,
KeyNode: keyNode, KeyNode: keyNode,
@@ -177,12 +176,12 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf(low.NodeReference[int]{}): case reflect.TypeOf(NodeReference[int]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeIntValue(valueNode) { if utils.IsNodeIntValue(valueNode) {
if field.CanSet() { if field.CanSet() {
fv, _ := strconv.Atoi(valueNode.Value) fv, _ := strconv.Atoi(valueNode.Value)
nr := low.NodeReference[int]{ nr := NodeReference[int]{
Value: fv, Value: fv,
ValueNode: valueNode, ValueNode: valueNode,
KeyNode: keyNode, KeyNode: keyNode,
@@ -192,12 +191,12 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf(low.NodeReference[int64]{}): case reflect.TypeOf(NodeReference[int64]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeIntValue(valueNode) || utils.IsNodeFloatValue(valueNode) { // if utils.IsNodeIntValue(valueNode) || utils.IsNodeFloatValue(valueNode) { //
if field.CanSet() { if field.CanSet() {
fv, _ := strconv.ParseInt(valueNode.Value, 10, 64) fv, _ := strconv.ParseInt(valueNode.Value, 10, 64)
nr := low.NodeReference[int64]{ nr := NodeReference[int64]{
Value: fv, Value: fv,
ValueNode: valueNode, ValueNode: valueNode,
KeyNode: keyNode, KeyNode: keyNode,
@@ -207,12 +206,12 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf(low.NodeReference[float32]{}): case reflect.TypeOf(NodeReference[float32]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeFloatValue(valueNode) { if utils.IsNodeFloatValue(valueNode) {
if field.CanSet() { if field.CanSet() {
fv, _ := strconv.ParseFloat(valueNode.Value, 32) fv, _ := strconv.ParseFloat(valueNode.Value, 32)
nr := low.NodeReference[float32]{ nr := NodeReference[float32]{
Value: float32(fv), Value: float32(fv),
ValueNode: valueNode, ValueNode: valueNode,
KeyNode: keyNode, KeyNode: keyNode,
@@ -222,12 +221,12 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf(low.NodeReference[float64]{}): case reflect.TypeOf(NodeReference[float64]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeFloatValue(valueNode) { if utils.IsNodeFloatValue(valueNode) {
if field.CanSet() { if field.CanSet() {
fv, _ := strconv.ParseFloat(valueNode.Value, 64) fv, _ := strconv.ParseFloat(valueNode.Value, 64)
nr := low.NodeReference[float64]{ nr := NodeReference[float64]{
Value: fv, Value: fv,
ValueNode: valueNode, ValueNode: valueNode,
KeyNode: keyNode, KeyNode: keyNode,
@@ -237,13 +236,13 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf([]low.NodeReference[string]{}): case reflect.TypeOf([]NodeReference[string]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeArray(valueNode) { if utils.IsNodeArray(valueNode) {
if field.CanSet() { if field.CanSet() {
var items []low.NodeReference[string] var items []NodeReference[string]
for _, sliceItem := range valueNode.Content { for _, sliceItem := range valueNode.Content {
items = append(items, low.NodeReference[string]{ items = append(items, NodeReference[string]{
Value: sliceItem.Value, Value: sliceItem.Value,
ValueNode: sliceItem, ValueNode: sliceItem,
KeyNode: valueNode, KeyNode: valueNode,
@@ -254,14 +253,14 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf([]low.NodeReference[float32]{}): case reflect.TypeOf([]NodeReference[float32]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeArray(valueNode) { if utils.IsNodeArray(valueNode) {
if field.CanSet() { if field.CanSet() {
var items []low.NodeReference[float32] var items []NodeReference[float32]
for _, sliceItem := range valueNode.Content { for _, sliceItem := range valueNode.Content {
fv, _ := strconv.ParseFloat(sliceItem.Value, 32) fv, _ := strconv.ParseFloat(sliceItem.Value, 32)
items = append(items, low.NodeReference[float32]{ items = append(items, NodeReference[float32]{
Value: float32(fv), Value: float32(fv),
ValueNode: sliceItem, ValueNode: sliceItem,
KeyNode: valueNode, KeyNode: valueNode,
@@ -272,28 +271,28 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf([]low.NodeReference[float64]{}): case reflect.TypeOf([]NodeReference[float64]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeArray(valueNode) { if utils.IsNodeArray(valueNode) {
if field.CanSet() { if field.CanSet() {
var items []low.NodeReference[float64] var items []NodeReference[float64]
for _, sliceItem := range valueNode.Content { for _, sliceItem := range valueNode.Content {
fv, _ := strconv.ParseFloat(sliceItem.Value, 64) fv, _ := strconv.ParseFloat(sliceItem.Value, 64)
items = append(items, low.NodeReference[float64]{Value: fv, ValueNode: sliceItem}) items = append(items, NodeReference[float64]{Value: fv, ValueNode: sliceItem})
} }
field.Set(reflect.ValueOf(items)) field.Set(reflect.ValueOf(items))
} }
} }
} }
break break
case reflect.TypeOf([]low.NodeReference[int]{}): case reflect.TypeOf([]NodeReference[int]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeArray(valueNode) { if utils.IsNodeArray(valueNode) {
if field.CanSet() { if field.CanSet() {
var items []low.NodeReference[int] var items []NodeReference[int]
for _, sliceItem := range valueNode.Content { for _, sliceItem := range valueNode.Content {
iv, _ := strconv.Atoi(sliceItem.Value) iv, _ := strconv.Atoi(sliceItem.Value)
items = append(items, low.NodeReference[int]{ items = append(items, NodeReference[int]{
Value: iv, Value: iv,
ValueNode: sliceItem, ValueNode: sliceItem,
KeyNode: valueNode, KeyNode: valueNode,
@@ -304,14 +303,14 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf([]low.NodeReference[int64]{}): case reflect.TypeOf([]NodeReference[int64]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeArray(valueNode) { if utils.IsNodeArray(valueNode) {
if field.CanSet() { if field.CanSet() {
var items []low.NodeReference[int64] var items []NodeReference[int64]
for _, sliceItem := range valueNode.Content { for _, sliceItem := range valueNode.Content {
iv, _ := strconv.ParseInt(sliceItem.Value, 10, 64) iv, _ := strconv.ParseInt(sliceItem.Value, 10, 64)
items = append(items, low.NodeReference[int64]{ items = append(items, NodeReference[int64]{
Value: iv, Value: iv,
ValueNode: sliceItem, ValueNode: sliceItem,
KeyNode: valueNode, KeyNode: valueNode,
@@ -322,14 +321,14 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
break break
case reflect.TypeOf([]low.NodeReference[bool]{}): case reflect.TypeOf([]NodeReference[bool]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeArray(valueNode) { if utils.IsNodeArray(valueNode) {
if field.CanSet() { if field.CanSet() {
var items []low.NodeReference[bool] var items []NodeReference[bool]
for _, sliceItem := range valueNode.Content { for _, sliceItem := range valueNode.Content {
bv, _ := strconv.ParseBool(sliceItem.Value) bv, _ := strconv.ParseBool(sliceItem.Value)
items = append(items, low.NodeReference[bool]{ items = append(items, NodeReference[bool]{
Value: bv, Value: bv,
ValueNode: sliceItem, ValueNode: sliceItem,
KeyNode: valueNode, KeyNode: valueNode,
@@ -341,21 +340,21 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
break break
// helper for unpacking string maps. // helper for unpacking string maps.
case reflect.TypeOf(map[low.KeyReference[string]]low.ValueReference[string]{}): case reflect.TypeOf(map[KeyReference[string]]ValueReference[string]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeMap(valueNode) { if utils.IsNodeMap(valueNode) {
if field.CanSet() { if field.CanSet() {
items := make(map[low.KeyReference[string]]low.ValueReference[string]) items := make(map[KeyReference[string]]ValueReference[string])
var cf *yaml.Node var cf *yaml.Node
for i, sliceItem := range valueNode.Content { for i, sliceItem := range valueNode.Content {
if i%2 == 0 { if i%2 == 0 {
cf = sliceItem cf = sliceItem
continue continue
} }
items[low.KeyReference[string]{ items[KeyReference[string]{
Value: cf.Value, Value: cf.Value,
KeyNode: cf, KeyNode: cf,
}] = low.ValueReference[string]{ }] = ValueReference[string]{
Value: sliceItem.Value, Value: sliceItem.Value,
ValueNode: sliceItem, ValueNode: sliceItem,
} }
@@ -364,18 +363,18 @@ func SetField(field reflect.Value, valueNode *yaml.Node, keyNode *yaml.Node) err
} }
} }
} }
case reflect.TypeOf(low.NodeReference[[]low.ValueReference[string]]{}): case reflect.TypeOf(NodeReference[[]ValueReference[string]]{}):
if valueNode != nil { if valueNode != nil {
if utils.IsNodeArray(valueNode) { if utils.IsNodeArray(valueNode) {
if field.CanSet() { if field.CanSet() {
var items []low.ValueReference[string] var items []ValueReference[string]
for _, sliceItem := range valueNode.Content { for _, sliceItem := range valueNode.Content {
items = append(items, low.ValueReference[string]{ items = append(items, ValueReference[string]{
Value: sliceItem.Value, Value: sliceItem.Value,
ValueNode: sliceItem, ValueNode: sliceItem,
}) })
} }
n := low.NodeReference[[]low.ValueReference[string]]{ n := NodeReference[[]ValueReference[string]]{
Value: items, Value: items,
KeyNode: keyNode, KeyNode: keyNode,
ValueNode: valueNode, ValueNode: valueNode,

View File

@@ -1,31 +1,30 @@
package v3 package low
import ( import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"testing" "testing"
) )
type hotdog struct { type hotdog struct {
Name low.NodeReference[string] Name NodeReference[string]
Fat low.NodeReference[int] Fat NodeReference[int]
Ketchup low.NodeReference[float32] Ketchup NodeReference[float32]
Mustard low.NodeReference[float64] Mustard NodeReference[float64]
Grilled low.NodeReference[bool] Grilled NodeReference[bool]
MaxTemp low.NodeReference[int] MaxTemp NodeReference[int]
MaxTempHigh low.NodeReference[int64] MaxTempHigh NodeReference[int64]
MaxTempAlt []low.NodeReference[int] MaxTempAlt []NodeReference[int]
Drinks []low.NodeReference[string] Drinks []NodeReference[string]
Sides []low.NodeReference[float32] Sides []NodeReference[float32]
BigSides []low.NodeReference[float64] BigSides []NodeReference[float64]
Temps []low.NodeReference[int] Temps []NodeReference[int]
HighTemps []low.NodeReference[int64] HighTemps []NodeReference[int64]
Buns []low.NodeReference[bool] Buns []NodeReference[bool]
UnknownElements low.NodeReference[any] UnknownElements NodeReference[any]
LotsOfUnknowns []low.NodeReference[any] LotsOfUnknowns []NodeReference[any]
Where map[string]low.NodeReference[any] Where map[string]NodeReference[any]
There map[string]low.NodeReference[string] There map[string]NodeReference[string]
} }
func TestBuildModel_Mismatch(t *testing.T) { func TestBuildModel_Mismatch(t *testing.T) {

View File

@@ -56,7 +56,7 @@ func extractInfo(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecInde
_, ln, vn := utils.FindKeyNodeFull(v3.InfoLabel, info.RootNode.Content) _, ln, vn := utils.FindKeyNodeFull(v3.InfoLabel, info.RootNode.Content)
if vn != nil { if vn != nil {
ir := v3.Info{} ir := v3.Info{}
err := v3.BuildModel(vn, &ir) err := low.BuildModel(vn, &ir)
if err != nil { if err != nil {
return err return err
} }
@@ -68,7 +68,7 @@ func extractInfo(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecInde
} }
func extractSecurity(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error { func extractSecurity(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error {
sec, sErr := v3.ExtractObject[*v3.SecurityRequirement](v3.SecurityLabel, info.RootNode, idx) sec, sErr := low.ExtractObject[*v3.SecurityRequirement](v3.SecurityLabel, info.RootNode, idx)
if sErr != nil { if sErr != nil {
return sErr return sErr
} }
@@ -77,7 +77,7 @@ func extractSecurity(info *datamodel.SpecInfo, doc *v3.Document, idx *index.Spec
} }
func extractExternalDocs(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error { func extractExternalDocs(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecIndex) error {
extDocs, dErr := v3.ExtractObject[*v3.ExternalDoc](v3.ExternalDocsLabel, info.RootNode, idx) extDocs, dErr := low.ExtractObject[*v3.ExternalDoc](v3.ExternalDocsLabel, info.RootNode, idx)
if dErr != nil { if dErr != nil {
return dErr return dErr
} }
@@ -89,7 +89,7 @@ func extractComponents(info *datamodel.SpecInfo, doc *v3.Document, idx *index.Sp
_, ln, vn := utils.FindKeyNodeFull(v3.ComponentsLabel, info.RootNode.Content) _, ln, vn := utils.FindKeyNodeFull(v3.ComponentsLabel, info.RootNode.Content)
if vn != nil { if vn != nil {
ir := v3.Components{} ir := v3.Components{}
err := v3.BuildModel(vn, &ir) err := low.BuildModel(vn, &ir)
if err != nil { if err != nil {
return err return err
} }
@@ -108,7 +108,7 @@ func extractServers(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecI
for _, srvN := range vn.Content { for _, srvN := range vn.Content {
if utils.IsNodeMap(srvN) { if utils.IsNodeMap(srvN) {
srvr := v3.Server{} srvr := v3.Server{}
err := v3.BuildModel(srvN, &srvr) err := low.BuildModel(srvN, &srvr)
if err != nil { if err != nil {
return err return err
} }
@@ -137,7 +137,7 @@ func extractTags(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecInde
for _, tagN := range vn.Content { for _, tagN := range vn.Content {
if utils.IsNodeMap(tagN) { if utils.IsNodeMap(tagN) {
tag := v3.Tag{} tag := v3.Tag{}
err := v3.BuildModel(tagN, &tag) err := low.BuildModel(tagN, &tag)
if err != nil { if err != nil {
return err return err
} }