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
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/datamodel/low/3.0"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
@@ -20,7 +21,7 @@ x-b33f: princess`
idx := index.NewSpecIndex(&idxNode)
var n v3.ExternalDoc
err := v3.BuildModel(&idxNode, &n)
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
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] {
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 {
cb.Extensions = ExtractExtensions(root)
cb.Extensions = low.ExtractExtensions(root)
// handle callback
var currentCB *yaml.Node
@@ -30,7 +30,7 @@ func (cb *Callback) Build(root *yaml.Node, idx *index.SpecIndex) error {
currentCB = callbackNode
continue
}
callback, eErr := ExtractObjectRaw[*PathItem](callbackNode, idx)
callback, eErr := low.ExtractObjectRaw[*PathItem](callbackNode, idx)
if eErr != nil {
return eErr
}

View File

@@ -1,6 +1,7 @@
package v3
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
@@ -26,7 +27,7 @@ func TestCallback_Build_Success(t *testing.T) {
assert.NoError(t, mErr)
var n Callback
err := BuildModel(rootNode.Content[0], &n)
err := low.BuildModel(rootNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(rootNode.Content[0], nil)
@@ -59,7 +60,7 @@ func TestCallback_Build_Error(t *testing.T) {
assert.NoError(t, mErr)
var n Callback
err := BuildModel(rootNode.Content[0], &n)
err := low.BuildModel(rootNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(rootNode.Content[0], idx)
@@ -94,7 +95,7 @@ func TestCallback_Build_Using_InlineRef(t *testing.T) {
assert.NoError(t, mErr)
var n Callback
err := BuildModel(rootNode.Content[0], &n)
err := low.BuildModel(rootNode.Content[0], &n)
assert.NoError(t, err)
err = n.Build(rootNode.Content[0], idx)
@@ -142,7 +143,7 @@ components:
assert.NoError(t, mErr)
var n Callback
err := BuildModel(rootNode.Content[0], &n)
err := low.BuildModel(rootNode.Content[0], &n)
assert.NoError(t, err)
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] {
return FindItemInMap[*Schema](schema, co.Schemas.Value)
return low.FindItemInMap[*Schema](schema, co.Schemas.Value)
}
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] {
return FindItemInMap[*Parameter](response, co.Parameters.Value)
return low.FindItemInMap[*Parameter](response, co.Parameters.Value)
}
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] {
return FindItemInMap[*Example](example, co.Examples.Value)
return low.FindItemInMap[*Example](example, co.Examples.Value)
}
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] {
return FindItemInMap[*Header](header, co.Headers.Value)
return low.FindItemInMap[*Header](header, co.Headers.Value)
}
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] {
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 {
co.Extensions = ExtractExtensions(root)
co.Extensions = low.ExtractExtensions(root)
// build out components asynchronously for speed. There could be some significant weight here.
skipChan := make(chan bool)
@@ -178,7 +178,7 @@ func extractComponentValues[T low.Buildable[N], N any](label string, root *yaml.
continue
}
var n T = new(N)
_ = BuildModel(v, n)
_ = low.BuildModel(v, n)
err := n.Build(v, idx)
if err != nil {
errorChan <- err

View File

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

View File

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

View File

@@ -19,12 +19,12 @@ type Encoding struct {
}
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 {
headers, hL, hN, err := ExtractMapFlat[*Header](HeadersLabel, root, idx)
headers, hL, hN, err := low.ExtractMapFlat[*Header](HeadersLabel, root, idx)
if err != nil {
return err
}

View File

@@ -1,6 +1,7 @@
package v3
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
@@ -24,7 +25,7 @@ explode: true`
idx := index.NewSpecIndex(&idxNode)
var n Encoding
err := BuildModel(&idxNode, &n)
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
err = n.Build(idxNode.Content[0], idx)
@@ -52,7 +53,7 @@ headers:
idx := index.NewSpecIndex(&idxNode)
var n Encoding
err := BuildModel(&idxNode, &n)
err := low.BuildModel(&idxNode, &n)
assert.NoError(t, err)
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] {
return FindItemInMap[any](ext, ex.Extensions)
return low.FindItemInMap[any](ext, ex.Extensions)
}
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)

View File

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

View File

@@ -12,7 +12,11 @@ type ExternalDoc struct {
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 {
ex.Extensions = ExtractExtensions(root)
ex.Extensions = low.ExtractExtensions(root)
return nil
}

View File

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

View File

@@ -27,11 +27,11 @@ func (i *Info) Build(root *yaml.Node) error {
contact := Contact{}
_, kln, cn := utils.FindKeyNodeFull("contact", root.Content)
go BuildModelAsync(cn, &contact, &wg, &errs)
go low.BuildModelAsync(cn, &contact, &wg, &errs)
license := License{}
_, kln, ln := utils.FindKeyNodeFull("license", root.Content)
go BuildModelAsync(ln, &license, &wg, &errs)
go low.BuildModelAsync(ln, &license, &wg, &errs)
//wg.Wait()
i.Contact = low.NodeReference[*Contact]{Value: &contact, ValueNode: cn, 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] {
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 {
l.Extensions = ExtractExtensions(root)
l.Extensions = low.ExtractExtensions(root)
// extract parameters
_, 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] {
return FindItemInMap[*Encoding](eType, mt.Encoding.Value)
return low.FindItemInMap[*Encoding](eType, mt.Encoding.Value)
}
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] {
@@ -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 {
mt.Extensions = ExtractExtensions(root)
mt.Extensions = low.ExtractExtensions(root)
// handle example if set.
_, 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.
exps, expsL, expsN, eErr := ExtractMapFlat[*Example](ExamplesLabel, root, idx)
exps, expsL, expsN, eErr := low.ExtractMapFlat[*Example](ExamplesLabel, root, idx)
if eErr != nil {
return eErr
}
@@ -59,7 +59,7 @@ func (mt *MediaType) Build(root *yaml.Node, idx *index.SpecIndex) error {
}
// handle encoding
encs, encsL, encsN, encErr := ExtractMapFlat[*Encoding](EncodingLabel, root, idx)
encs, encsL, encsN, encErr := low.ExtractMapFlat[*Encoding](EncodingLabel, root, idx)
if encErr != nil {
return encErr
}

View File

@@ -24,27 +24,27 @@ type OAuthFlows struct {
}
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 {
return vErr
}
o.Implicit = v
v, vErr = ExtractObject[*OAuthFlow](PasswordLabel, root, idx)
v, vErr = low.ExtractObject[*OAuthFlow](PasswordLabel, root, idx)
if vErr != nil {
return vErr
}
o.Password = v
v, vErr = ExtractObject[*OAuthFlow](ClientCredentialsLabel, root, idx)
v, vErr = low.ExtractObject[*OAuthFlow](ClientCredentialsLabel, root, idx)
if vErr != nil {
return vErr
}
o.ClientCredentials = v
v, vErr = ExtractObject[*OAuthFlow](AuthorizationCodeLabel, root, idx)
v, vErr = low.ExtractObject[*OAuthFlow](AuthorizationCodeLabel, root, idx)
if vErr != nil {
return vErr
}
@@ -62,11 +62,11 @@ type OAuthFlow struct {
}
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 {
o.Extensions = ExtractExtensions(root)
o.Extensions = low.ExtractExtensions(root)
var currSec *yaml.Node

View File

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

View File

@@ -30,15 +30,15 @@ type Parameter struct {
}
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] {
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 {
p.Extensions = ExtractExtensions(root)
p.Extensions = low.ExtractExtensions(root)
// handle example if set.
_, 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.
exps, expsL, expsN, eErr := ExtractMapFlat[*Example](ExamplesLabel, root, idx)
exps, expsL, expsN, eErr := low.ExtractMapFlat[*Example](ExamplesLabel, root, idx)
if eErr != nil {
return eErr
}
@@ -69,7 +69,7 @@ func (p *Parameter) Build(root *yaml.Node, idx *index.SpecIndex) error {
}
// 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 {
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 {
p.Extensions = ExtractExtensions(root)
p.Extensions = low.ExtractExtensions(root)
skip := false
var currentNode *yaml.Node
@@ -57,7 +57,7 @@ func (p *Paths) Build(root *yaml.Node, idx *index.SpecIndex) error {
continue
}
var path = PathItem{}
err := BuildModel(pathNode, &path)
err := low.BuildModel(pathNode, &path)
if err != nil {
}
@@ -98,7 +98,7 @@ type PathItem struct {
}
func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
p.Extensions = ExtractExtensions(root)
p.Extensions = low.ExtractExtensions(root)
skip := false
var currentNode *yaml.Node
@@ -108,7 +108,7 @@ func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
var ops []low.NodeReference[*Operation]
if ok, _, _ := utils.IsNodeRefValue(root); ok {
r := LocateRefNode(root, idx)
r := low.LocateRefNode(root, idx)
if r != nil {
root = r
} else {
@@ -133,7 +133,7 @@ func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
var op Operation
wg.Add(1)
go BuildModelAsync(pathNode, &op, &wg, &errors)
go low.BuildModelAsync(pathNode, &op, &wg, &errors)
opRef := low.NodeReference[*Operation]{
Value: &op,
@@ -176,7 +176,7 @@ func (p *PathItem) Build(root *yaml.Node, idx *index.SpecIndex) error {
//build out the operation.
if ok, _, _ := utils.IsNodeRefValue(op.ValueNode); ok {
r := LocateRefNode(op.ValueNode, idx)
r := low.LocateRefNode(op.ValueNode, idx)
if r != nil {
op.ValueNode = r
} else {

View File

@@ -14,14 +14,14 @@ type RequestBody struct {
}
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 {
rb.Extensions = ExtractExtensions(root)
rb.Extensions = low.ExtractExtensions(root)
// 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 {
return cErr
}

View File

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

View File

@@ -1,6 +1,7 @@
package v3
import (
"fmt"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils"
@@ -60,7 +61,7 @@ type Schema struct {
}
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 {
@@ -84,7 +85,7 @@ func (s *Schema) BuildLevel(root *yaml.Node, idx *index.SpecIndex, level int) er
_, addPLabel, addPNode := utils.FindKeyNodeFull(AdditionalPropertiesLabel, root.Content)
if addPNode != nil {
if utils.IsNodeMap(addPNode) {
schema, serr := ExtractObjectRaw[*Schema](addPNode, idx)
schema, serr := low.ExtractObjectRaw[*Schema](addPNode, idx)
if serr != nil {
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)
if discNode != nil {
var discriminator Discriminator
err := BuildModel(discNode, &discriminator)
err := low.BuildModel(discNode, &discriminator)
if err != nil {
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)
if extDocNode != nil {
var exDoc ExternalDoc
err := BuildModel(extDocNode, &exDoc)
err := low.BuildModel(extDocNode, &exDoc)
if err != nil {
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)
if xmlNode != nil {
var xml XML
err := BuildModel(xmlNode, &xml)
err := low.BuildModel(xmlNode, &xml)
if err != nil {
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
if h, _, _ := utils.IsNodeRefValue(prop); h {
ref := LocateRefNode(prop, idx)
ref := low.LocateRefNode(prop, idx)
if ref != nil {
prop = ref
}
}
var property Schema
err := BuildModel(prop, &property)
err := low.BuildModel(prop, &property)
if err != nil {
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) {
s.Extensions = ExtractExtensions(root)
s.Extensions = low.ExtractExtensions(root)
}
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 {
var build = func(kn *yaml.Node, vn *yaml.Node) *low.NodeReference[*Schema] {
var schema Schema
err := BuildModel(vn, &schema)
err := low.BuildModel(vn, &schema)
if err != nil {
*errors = append(*errors, err)
return nil
@@ -284,3 +285,41 @@ func buildSchema(schemas *[]low.NodeReference[*Schema], attribute string, rootNo
//wg.Done()
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
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
@@ -108,7 +109,7 @@ additionalProperties: true `
assert.NoError(t, mErr)
sch := Schema{}
mbErr := BuildModel(&rootNode, &sch)
mbErr := low.BuildModel(&rootNode, &sch)
assert.NoError(t, mbErr)
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 {
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 {
return oaErr
}

View File

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

View File

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

View File

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

View File

@@ -1,9 +1,7 @@
package datamodel
package low
import (
"fmt"
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/datamodel/low/3.0"
"github.com/pb33f/libopenapi/index"
"github.com/pb33f/libopenapi/utils"
"github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath"
@@ -13,14 +11,7 @@ import (
"sync"
)
var KnownSchemas map[string]low.NodeReference[*v3.Schema]
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] {
func FindItemInMap[T any](item string, collection map[KeyReference[string]]ValueReference[T]) *ValueReference[T] {
for n, o := range collection {
if n.Value == item {
return &o
@@ -29,44 +20,6 @@ func FindItemInMap[T any](item string, collection map[low.KeyReference[string]]l
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
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
}
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)
err := v3.BuildModel(root, n)
err := BuildModel(root, n)
if err != nil {
return n, err
}
@@ -124,7 +77,7 @@ func ExtractObjectRaw[T low.Buildable[N], N any](root *yaml.Node, idx *index.Spe
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
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
// locate reference in index.
@@ -133,7 +86,7 @@ func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node, idx
vn = ref
ln = rl
} 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)
}
} else {
@@ -144,32 +97,32 @@ func ExtractObject[T low.Buildable[N], N any](label string, root *yaml.Node, idx
if ref != nil {
vn = ref
} 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)
}
}
}
}
var n T = new(N)
err := v3.BuildModel(vn, n)
err := BuildModel(vn, n)
if err != nil {
return low.NodeReference[T]{}, err
return NodeReference[T]{}, err
}
if ln == nil {
return low.NodeReference[T]{}, nil
return NodeReference[T]{}, nil
}
err = n.Build(vn, idx)
if err != nil {
return low.NodeReference[T]{}, err
return NodeReference[T]{}, err
}
return low.NodeReference[T]{
return NodeReference[T]{
Value: n,
KeyNode: ln,
ValueNode: vn,
}, 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) {
var ln, vn *yaml.Node
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
ln = rl
} 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)
}
} else {
@@ -190,13 +143,13 @@ func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node, idx
if ref != nil {
vn = ref
} 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)
}
}
}
}
var items []low.ValueReference[T]
var items []ValueReference[T]
if vn != nil && ln != nil {
for _, node := range vn.Content {
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 {
node = ref
} 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)
}
}
var n T = new(N)
err := v3.BuildModel(node, n)
err := BuildModel(node, n)
if err != nil {
return []low.ValueReference[T]{}, ln, vn, err
return []ValueReference[T]{}, ln, vn, err
}
berr := n.Build(node, idx)
if berr != nil {
return nil, ln, vn, berr
}
items = append(items, low.ValueReference[T]{
items = append(items, ValueReference[T]{
Value: n,
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
}
func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node, idx *index.SpecIndex) (map[low.KeyReference[string]]low.ValueReference[PT], error) {
valueMap := make(map[low.KeyReference[string]]low.ValueReference[PT])
func ExtractMapFlatNoLookup[PT Buildable[N], N any](root *yaml.Node, idx *index.SpecIndex) (map[KeyReference[string]]ValueReference[PT], error) {
valueMap := make(map[KeyReference[string]]ValueReference[PT])
if utils.IsNodeMap(root) {
var currentKey *yaml.Node
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)
err := v3.BuildModel(node, n)
err := BuildModel(node, n)
if err != nil {
return nil, err
}
@@ -255,10 +208,10 @@ func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node, idx *in
if berr != nil {
return nil, berr
}
valueMap[low.KeyReference[string]{
valueMap[KeyReference[string]{
Value: currentKey.Value,
KeyNode: currentKey,
}] = low.ValueReference[PT]{
}] = ValueReference[PT]{
Value: n,
ValueNode: node,
}
@@ -267,7 +220,7 @@ func ExtractMapFlatNoLookup[PT low.Buildable[N], N any](root *yaml.Node, idx *in
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
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
// 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 {
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 {
if i%2 == 0 {
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.
}
var n PT = new(N)
err := v3.BuildModel(en, n)
err := BuildModel(en, n)
if err != nil {
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 {
return nil, labelNode, valueNode, berr
}
valueMap[low.KeyReference[string]{
valueMap[KeyReference[string]{
Value: currentLabelNode.Value,
KeyNode: currentLabelNode,
}] = low.ValueReference[PT]{
}] = ValueReference[PT]{
Value: n,
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
}
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
if rf, rl, _ := utils.IsNodeRefValue(root); rf {
// 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 {
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 {
if i%2 == 0 {
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.
}
var n PT = new(N)
err := v3.BuildModel(en, n)
err := BuildModel(en, n)
if err != nil {
return nil, err
}
@@ -373,16 +326,16 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *
if berr != nil {
return nil, berr
}
valueMap[low.KeyReference[string]{
valueMap[KeyReference[string]{
Value: currentLabelNode.Value,
KeyNode: currentLabelNode,
}] = low.ValueReference[PT]{
}] = ValueReference[PT]{
Value: n,
ValueNode: en,
}
}
resMap := make(map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[PT])
resMap[low.KeyReference[string]{
resMap := make(map[KeyReference[string]]map[KeyReference[string]]ValueReference[PT])
resMap[KeyReference[string]{
Value: labelNode.Value,
KeyNode: labelNode,
}] = valueMap
@@ -391,52 +344,52 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node, idx *
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)
extensionMap := make(map[low.KeyReference[string]]low.ValueReference[any])
extensionMap := make(map[KeyReference[string]]ValueReference[any])
for _, ext := range extensions {
if utils.IsNodeMap(ext.Value) {
var v interface{}
_ = ext.Value.Decode(&v)
extensionMap[low.KeyReference[string]{
extensionMap[KeyReference[string]{
Value: ext.Key.Value,
KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: v, ValueNode: ext.Value}
}] = ValueReference[any]{Value: v, ValueNode: ext.Value}
}
if utils.IsNodeStringValue(ext.Value) {
extensionMap[low.KeyReference[string]{
extensionMap[KeyReference[string]{
Value: ext.Key.Value,
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) {
fv, _ := strconv.ParseFloat(ext.Value.Value, 64)
extensionMap[low.KeyReference[string]{
extensionMap[KeyReference[string]{
Value: ext.Key.Value,
KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: fv, ValueNode: ext.Value}
}] = ValueReference[any]{Value: fv, ValueNode: ext.Value}
}
if utils.IsNodeIntValue(ext.Value) {
iv, _ := strconv.ParseInt(ext.Value.Value, 10, 64)
extensionMap[low.KeyReference[string]{
extensionMap[KeyReference[string]{
Value: ext.Key.Value,
KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: iv, ValueNode: ext.Value}
}] = ValueReference[any]{Value: iv, ValueNode: ext.Value}
}
if utils.IsNodeBoolValue(ext.Value) {
bv, _ := strconv.ParseBool(ext.Value.Value)
extensionMap[low.KeyReference[string]{
extensionMap[KeyReference[string]{
Value: ext.Key.Value,
KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: bv, ValueNode: ext.Value}
}] = ValueReference[any]{Value: bv, ValueNode: ext.Value}
}
if utils.IsNodeArray(ext.Value) {
var v []interface{}
_ = ext.Value.Decode(&v)
extensionMap[low.KeyReference[string]{
extensionMap[KeyReference[string]{
Value: ext.Key.Value,
KeyNode: ext.Key,
}] = low.ValueReference[any]{Value: v, ValueNode: ext.Value}
}] = ValueReference[any]{Value: v, ValueNode: ext.Value}
}
}
return extensionMap

View File

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

View File

@@ -1,31 +1,30 @@
package v3
package low
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
type hotdog struct {
Name low.NodeReference[string]
Fat low.NodeReference[int]
Ketchup low.NodeReference[float32]
Mustard low.NodeReference[float64]
Grilled low.NodeReference[bool]
MaxTemp low.NodeReference[int]
MaxTempHigh low.NodeReference[int64]
MaxTempAlt []low.NodeReference[int]
Drinks []low.NodeReference[string]
Sides []low.NodeReference[float32]
BigSides []low.NodeReference[float64]
Temps []low.NodeReference[int]
HighTemps []low.NodeReference[int64]
Buns []low.NodeReference[bool]
UnknownElements low.NodeReference[any]
LotsOfUnknowns []low.NodeReference[any]
Where map[string]low.NodeReference[any]
There map[string]low.NodeReference[string]
Name NodeReference[string]
Fat NodeReference[int]
Ketchup NodeReference[float32]
Mustard NodeReference[float64]
Grilled NodeReference[bool]
MaxTemp NodeReference[int]
MaxTempHigh NodeReference[int64]
MaxTempAlt []NodeReference[int]
Drinks []NodeReference[string]
Sides []NodeReference[float32]
BigSides []NodeReference[float64]
Temps []NodeReference[int]
HighTemps []NodeReference[int64]
Buns []NodeReference[bool]
UnknownElements NodeReference[any]
LotsOfUnknowns []NodeReference[any]
Where map[string]NodeReference[any]
There map[string]NodeReference[string]
}
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)
if vn != nil {
ir := v3.Info{}
err := v3.BuildModel(vn, &ir)
err := low.BuildModel(vn, &ir)
if err != nil {
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 {
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 {
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 {
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 {
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)
if vn != nil {
ir := v3.Components{}
err := v3.BuildModel(vn, &ir)
err := low.BuildModel(vn, &ir)
if err != nil {
return err
}
@@ -108,7 +108,7 @@ func extractServers(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecI
for _, srvN := range vn.Content {
if utils.IsNodeMap(srvN) {
srvr := v3.Server{}
err := v3.BuildModel(srvN, &srvr)
err := low.BuildModel(srvN, &srvr)
if err != nil {
return err
}
@@ -137,7 +137,7 @@ func extractTags(info *datamodel.SpecInfo, doc *v3.Document, idx *index.SpecInde
for _, tagN := range vn.Content {
if utils.IsNodeMap(tagN) {
tag := v3.Tag{}
err := v3.BuildModel(tagN, &tag)
err := low.BuildModel(tagN, &tag)
if err != nil {
return err
}