Most of the core functions are now in place

The hardest part has come and gone! it's all downhill now.
This commit is contained in:
Dave Shanley
2022-08-06 09:32:48 -04:00
parent 13781cbbde
commit 016595c905
9 changed files with 236 additions and 162 deletions

View File

@@ -17,7 +17,18 @@ type Encoding struct {
AllowReserved low.NodeReference[bool]
}
func (en Encoding) Build(root *yaml.Node) error {
func (en *Encoding) FindHeader(hType string) *low.ValueReference[*Header] {
for _, c := range en.Headers {
for n, o := range c {
if n.Value == hType {
return &o
}
}
}
return nil
}
func (en *Encoding) Build(root *yaml.Node) error {
headers, err := ExtractMap[*Header](HeadersLabel, root)
if err != nil {

View File

@@ -5,6 +5,7 @@ import (
"github.com/pb33f/libopenapi/utils"
"gopkg.in/yaml.v3"
"strconv"
"strings"
"sync"
)
@@ -27,6 +28,44 @@ func ExtractSchema(root *yaml.Node) (*low.NodeReference[*Schema], error) {
var mapLock sync.Mutex
func ExtractObject[T any](label string, root *yaml.Node) (low.NodeReference[*T], error) {
_, ln, vn := utils.FindKeyNodeFull(label, root.Content)
var n *T = new(T)
err := BuildModel(root, n)
if err != nil {
return low.NodeReference[*T]{}, err
}
return low.NodeReference[*T]{
Value: n,
KeyNode: ln,
ValueNode: vn,
}, nil
}
func ExtractArray[T low.Buildable[N], N any](label string, root *yaml.Node) ([]low.NodeReference[T], error) {
_, ln, vn := utils.FindKeyNodeFull(label, root.Content)
var items []low.NodeReference[T]
if vn != nil && ln != nil {
for _, node := range vn.Content {
var n T = new(N)
err := BuildModel(node, n)
if err != nil {
return []low.NodeReference[T]{}, err
}
berr := n.Build(node)
if berr != nil {
return nil, berr
}
items = append(items, low.NodeReference[T]{
Value: n,
ValueNode: vn,
KeyNode: ln,
})
}
}
return items, nil
}
func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[PT], error) {
_, labelNode, valueNode := utils.FindKeyNodeFull(label, root.Content)
if valueNode != nil {
@@ -37,6 +76,9 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[
currentLabelNode = en
continue
}
if strings.HasPrefix(strings.ToLower(currentLabelNode.Value), "x-") {
continue // yo, don't pay any attention to extensions, not here anyway.
}
var n PT = new(N)
err := BuildModel(valueNode, n)
if err != nil {
@@ -54,7 +96,6 @@ func ExtractMap[PT low.Buildable[N], N any](label string, root *yaml.Node) (map[
ValueNode: en,
}
}
resMap := make(map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[PT])
resMap[low.KeyReference[string]{
Value: labelNode.Value,

View File

@@ -14,6 +14,17 @@ type MediaType struct {
Extensions map[low.KeyReference[string]]low.ValueReference[any]
}
func (mt *MediaType) FindPropertyEncoding(eType string) *low.ValueReference[*Encoding] {
for _, c := range mt.Encoding {
for n, o := range c {
if n.Value == eType {
return &o
}
}
}
return nil
}
func (mt *MediaType) Build(root *yaml.Node) error {
// extract extensions

View File

@@ -2,7 +2,6 @@ package v3
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/utils"
"gopkg.in/yaml.v3"
)
@@ -34,42 +33,19 @@ func (o *Operation) Build(root *yaml.Node) error {
}
o.Extensions = extensionMap
// extract external docs
_, ln, exDocs := utils.FindKeyNodeFull(ExternalDocsLabel, root.Content)
if exDocs != nil {
var externalDoc ExternalDoc
err = BuildModel(exDocs, &externalDoc)
if err != nil {
return err
}
o.ExternalDocs = low.NodeReference[*ExternalDoc]{
Value: &externalDoc,
KeyNode: ln,
ValueNode: exDocs,
}
// extract externalDocs
extDocs, dErr := ExtractObject[ExternalDoc](ExternalDocsLabel, root)
if dErr != nil {
return dErr
}
o.ExternalDocs = extDocs
// build parameters
_, paramLabel, paramNode := utils.FindKeyNodeFull(ParametersLabel, root.Content)
if paramNode != nil && paramLabel != nil {
var params []low.NodeReference[*Parameter]
for _, pN := range paramNode.Content {
var param Parameter
err = BuildModel(pN, &param)
if err != nil {
return err
}
err = param.Build(pN)
if err != nil {
return err
}
params = append(params, low.NodeReference[*Parameter]{
Value: &param,
ValueNode: paramNode,
KeyNode: paramLabel,
})
// extract parameters
params, pErr := ExtractArray[*Parameter](ParametersLabel, root)
if pErr != nil {
return pErr
}
if params != nil {
o.Parameters = params
}

View File

@@ -28,7 +28,7 @@ type Parameter struct {
Extensions map[low.KeyReference[string]]low.ValueReference[any]
}
func (p *Parameter) GetContent(cType string) *low.ValueReference[*MediaType] {
func (p *Parameter) FindContent(cType string) *low.ValueReference[*MediaType] {
for _, c := range p.Content {
for n, o := range c {
if n.Value == cType {
@@ -61,6 +61,15 @@ func (p *Parameter) Build(root *yaml.Node) error {
}
p.Schema = *sch
// handle examples if set.
exps, eErr := ExtractMap[*Example](ExamplesLabel, root)
if eErr != nil {
return eErr
}
if exps != nil {
p.Examples = exps
}
// handle content, if set.
con, cErr := ExtractMap[*MediaType](ContentLabel, root)
if cErr != nil {

View File

@@ -24,7 +24,7 @@ type Paths struct {
Extensions map[low.KeyReference[string]]low.ValueReference[any]
}
func (p *Paths) GetPath(path string) *low.ValueReference[*PathItem] {
func (p *Paths) FindPath(path string) *low.ValueReference[*PathItem] {
for k, p := range p.PathItems {
if k.Value == path {
return &p
@@ -87,16 +87,16 @@ func (p *Paths) Build(root *yaml.Node) error {
type PathItem struct {
Description low.NodeReference[string]
Summary low.NodeReference[string]
Get *low.NodeReference[*Operation]
Put *low.NodeReference[*Operation]
Post *low.NodeReference[*Operation]
Delete *low.NodeReference[*Operation]
Options *low.NodeReference[*Operation]
Head *low.NodeReference[*Operation]
Patch *low.NodeReference[*Operation]
Trace *low.NodeReference[*Operation]
Servers []*low.NodeReference[*Server]
Parameters []*low.NodeReference[*Parameter]
Get low.NodeReference[*Operation]
Put low.NodeReference[*Operation]
Post low.NodeReference[*Operation]
Delete low.NodeReference[*Operation]
Options low.NodeReference[*Operation]
Head low.NodeReference[*Operation]
Patch low.NodeReference[*Operation]
Trace low.NodeReference[*Operation]
Servers []low.NodeReference[*Server]
Parameters []low.NodeReference[*Parameter]
Extensions map[low.KeyReference[string]]low.ValueReference[any]
}
@@ -143,21 +143,21 @@ func (p *PathItem) Build(root *yaml.Node) error {
switch currentNode.Value {
case GetLabel:
p.Get = &opRef
p.Get = opRef
case PostLabel:
p.Post = &opRef
p.Post = opRef
case PutLabel:
p.Put = &opRef
p.Put = opRef
case PatchLabel:
p.Patch = &opRef
p.Patch = opRef
case DeleteLabel:
p.Delete = &opRef
p.Delete = opRef
case HeadLabel:
p.Head = &opRef
p.Head = opRef
case OptionsLabel:
p.Options = &opRef
p.Options = opRef
case TraceLabel:
p.Trace = &opRef
p.Trace = opRef
}
}

View File

@@ -6,9 +6,29 @@ import (
)
type RequestBody struct {
Node *yaml.Node
Description low.NodeReference[string]
Content map[string]MediaType
Content map[low.KeyReference[string]]map[low.KeyReference[string]]low.ValueReference[*MediaType]
Required low.NodeReference[bool]
Extensions map[string]low.ObjectReference
Extensions map[low.KeyReference[string]]low.ValueReference[any]
}
func (rb *RequestBody) Build(root *yaml.Node) error {
// extract extensions
extensionMap, err := ExtractExtensions(root)
if err != nil {
return err
}
if extensionMap != nil {
rb.Extensions = extensionMap
}
// handle content, if set.
con, cErr := ExtractMap[*MediaType](ContentLabel, root)
if cErr != nil {
return cErr
}
if con != nil {
rb.Content = con
}
return nil
}

View File

@@ -2,7 +2,6 @@ package v3
import (
"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/utils"
"gopkg.in/yaml.v3"
)
@@ -26,17 +25,12 @@ func (t *Tag) Build(root *yaml.Node) error {
}
t.Extensions = extensionMap
_, ln, exDocs := utils.FindKeyNodeFull(ExternalDocsLabel, root.Content)
// extract external docs
var externalDoc ExternalDoc
err = BuildModel(exDocs, &externalDoc)
if err != nil {
return err
}
t.ExternalDocs = low.NodeReference[*ExternalDoc]{
Value: &externalDoc,
KeyNode: ln,
ValueNode: exDocs,
// extract externalDocs
extDocs, dErr := ExtractObject[ExternalDoc](ExternalDocsLabel, root)
if dErr != nil {
return dErr
}
t.ExternalDocs = extDocs
return nil
}

View File

@@ -110,7 +110,7 @@ func TestCreateDocument_Tags(t *testing.T) {
func TestCreateDocument_Paths(t *testing.T) {
assert.Len(t, doc.Paths.Value.PathItems, 6)
burgerId := doc.Paths.Value.GetPath("/burgers/{burgerId}")
burgerId := doc.Paths.Value.FindPath("/burgers/{burgerId}")
assert.NotNil(t, burgerId)
assert.Len(t, burgerId.Value.Get.Value.Parameters, 2)
param := burgerId.Value.Get.Value.Parameters[1]
@@ -120,7 +120,19 @@ func TestCreateDocument_Paths(t *testing.T) {
assert.Equal(t, "big-mac", param.Value.Example.Value)
// check content
pContent := param.Value.GetContent("application/json")
pContent := param.Value.FindContent("application/json")
assert.Equal(t, "somethingNice", pContent.Value.Example.Value)
encoding := pContent.Value.FindPropertyEncoding("burgerTheme")
assert.NotNil(t, encoding.Value)
assert.Len(t, encoding.Value.Headers, 1)
header := encoding.Value.FindHeader("someHeader")
assert.NotNil(t, header.Value)
assert.Equal(t, "this is a header", header.Value.Description.Value)
assert.Equal(t, "string", header.Value.Schema.Value.Type.Value)
// check request body on operation
//burgers:= doc.Paths.Value.FindPath("/burgers/{burgerId}")
}