Skip to content

Commit

Permalink
chore: update to use iterators on orderedmaps
Browse files Browse the repository at this point in the history
  • Loading branch information
TristanSpeakEasy committed Aug 14, 2024
1 parent c3eb16d commit 059078e
Show file tree
Hide file tree
Showing 73 changed files with 690 additions and 550 deletions.
19 changes: 8 additions & 11 deletions datamodel/high/base/discriminator.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
package base

import (
low2 "github.com/pb33f/libopenapi/datamodel/high"
low "github.com/pb33f/libopenapi/datamodel/low/base"
"github.com/pb33f/libopenapi/datamodel/high"
"github.com/pb33f/libopenapi/datamodel/low"
lowBase "github.com/pb33f/libopenapi/datamodel/low/base"
"github.com/pb33f/libopenapi/orderedmap"
"gopkg.in/yaml.v3"
)
Expand All @@ -22,24 +23,20 @@ import (
type Discriminator struct {
PropertyName string `json:"propertyName,omitempty" yaml:"propertyName,omitempty"`
Mapping *orderedmap.Map[string, string] `json:"mapping,omitempty" yaml:"mapping,omitempty"`
low *low.Discriminator
low *lowBase.Discriminator
}

// NewDiscriminator will create a new high-level Discriminator from a low-level one.
func NewDiscriminator(disc *low.Discriminator) *Discriminator {
func NewDiscriminator(disc *lowBase.Discriminator) *Discriminator {
d := new(Discriminator)
d.low = disc
d.PropertyName = disc.PropertyName.Value
mapping := orderedmap.New[string, string]()
for pair := orderedmap.First(disc.Mapping.Value); pair != nil; pair = pair.Next() {
mapping.Set(pair.Key().Value, pair.Value().Value)
}
d.Mapping = mapping
d.Mapping = low.FromReferenceMap(disc.Mapping.Value)
return d
}

// GoLow returns the low-level Discriminator used to build the high-level one.
func (d *Discriminator) GoLow() *low.Discriminator {
func (d *Discriminator) GoLow() *lowBase.Discriminator {
return d.low
}

Expand All @@ -55,6 +52,6 @@ func (d *Discriminator) Render() ([]byte, error) {

// MarshalYAML will create a ready to render YAML representation of the Discriminator object.
func (d *Discriminator) MarshalYAML() (interface{}, error) {
nb := low2.NewNodeBuilder(d, d.low)
nb := high.NewNodeBuilder(d, d.low)
return nb.Render(), nil
}
19 changes: 8 additions & 11 deletions datamodel/high/base/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ package base

import (
"encoding/json"

"github.com/pb33f/libopenapi/datamodel/high"
lowmodel "github.com/pb33f/libopenapi/datamodel/low"
low "github.com/pb33f/libopenapi/datamodel/low/base"
"github.com/pb33f/libopenapi/datamodel/low"
lowBase "github.com/pb33f/libopenapi/datamodel/low/base"
"github.com/pb33f/libopenapi/orderedmap"
"gopkg.in/yaml.v3"
)
Expand All @@ -21,11 +22,11 @@ type Example struct {
Value *yaml.Node `json:"value,omitempty" yaml:"value,omitempty"`
ExternalValue string `json:"externalValue,omitempty" yaml:"externalValue,omitempty"`
Extensions *orderedmap.Map[string, *yaml.Node] `json:"-" yaml:"-"`
low *low.Example
low *lowBase.Example
}

// NewExample will create a new instance of an Example, using a low-level Example.
func NewExample(example *low.Example) *Example {
func NewExample(example *lowBase.Example) *Example {
e := new(Example)
e.low = example
e.Summary = example.Summary.Value
Expand All @@ -37,7 +38,7 @@ func NewExample(example *low.Example) *Example {
}

// GoLow will return the low-level Example used to build the high level one.
func (e *Example) GoLow() *low.Example {
func (e *Example) GoLow() *lowBase.Example {
return e.low
}

Expand Down Expand Up @@ -68,10 +69,6 @@ func (e *Example) MarshalJSON() ([]byte, error) {

// ExtractExamples will convert a low-level example map, into a high level one that is simple to navigate.
// no fidelity is lost, everything is still available via GoLow()
func ExtractExamples(elements *orderedmap.Map[lowmodel.KeyReference[string], lowmodel.ValueReference[*low.Example]]) *orderedmap.Map[string, *Example] {
extracted := orderedmap.New[string, *Example]()
for pair := orderedmap.First(elements); pair != nil; pair = pair.Next() {
extracted.Set(pair.Key().Value, NewExample(pair.Value().Value))
}
return extracted
func ExtractExamples(elements *orderedmap.Map[low.KeyReference[string], low.ValueReference[*lowBase.Example]]) *orderedmap.Map[string, *Example] {
return low.FromReferenceMapWithFunc(elements, NewExample)
}
14 changes: 8 additions & 6 deletions datamodel/high/base/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package base

import (
"encoding/json"

"github.com/pb33f/libopenapi/datamodel/high"
lowmodel "github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/datamodel/low/base"
Expand Down Expand Up @@ -376,17 +377,18 @@ func NewSchema(schema *base.Schema) *Schema {
}

props := orderedmap.New[string, *SchemaProxy]()
for pair := orderedmap.First(schema.Properties.Value); pair != nil; pair = pair.Next() {
buildProps(pair.Key(), pair.Value(), props, 0)
for name, schemaProxy := range schema.Properties.Value.FromOldest() {
buildProps(name, schemaProxy, props, 0)
}

dependents := orderedmap.New[string, *SchemaProxy]()
for pair := orderedmap.First(schema.DependentSchemas.Value); pair != nil; pair = pair.Next() {
buildProps(pair.Key(), pair.Value(), dependents, 1)
for name, schemaProxy := range schema.DependentSchemas.Value.FromOldest() {
buildProps(name, schemaProxy, dependents, 1)
}

patternProps := orderedmap.New[string, *SchemaProxy]()
for pair := orderedmap.First(schema.PatternProperties.Value); pair != nil; pair = pair.Next() {
buildProps(pair.Key(), pair.Value(), patternProps, 2)
for name, schemaProxy := range schema.PatternProperties.Value.FromOldest() {
buildProps(name, schemaProxy, patternProps, 2)
}

var allOf []*SchemaProxy
Expand Down
18 changes: 9 additions & 9 deletions datamodel/high/base/security_requirement.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import (
// The name used for each property MUST correspond to a security scheme declared in the Security Definitions
// - https://swagger.io/specification/v2/#securityDefinitionsObject
type SecurityRequirement struct {
Requirements *orderedmap.Map[string, []string] `json:"-" yaml:"-"`
ContainsEmptyRequirement bool // if a requirement is empty (this means it's optional)
low *base.SecurityRequirement
Requirements *orderedmap.Map[string, []string] `json:"-" yaml:"-"`
ContainsEmptyRequirement bool // if a requirement is empty (this means it's optional)
low *base.SecurityRequirement
}

// NewSecurityRequirement creates a new high-level SecurityRequirement from a low-level one.
Expand All @@ -32,12 +32,12 @@ func NewSecurityRequirement(req *base.SecurityRequirement) *SecurityRequirement
r.low = req
values := orderedmap.New[string, []string]()
// to keep things fast, avoiding copying anything - makes it a little hard to read.
for pair := orderedmap.First(req.Requirements.Value); pair != nil; pair = pair.Next() {
for name, val := range req.Requirements.Value.FromOldest() {
var vals []string
for valK := range pair.Value().Value {
vals = append(vals, pair.Value().Value[valK].Value)
for valK := range val.Value {
vals = append(vals, val.Value[valK].Value)
}
values.Set(pair.Key().Value, vals)
values.Set(name.Value, vals)
}
r.Requirements = values
r.ContainsEmptyRequirement = req.ContainsEmptyRequirement
Expand Down Expand Up @@ -74,8 +74,8 @@ func (s *SecurityRequirement) MarshalYAML() (interface{}, error) {

i := 0

for pair := orderedmap.First(s.Requirements); pair != nil; pair = pair.Next() {
keys[i] = &req{key: pair.Key(), val: pair.Value()}
for name, vals := range s.Requirements.FromOldest() {
keys[i] = &req{key: name, val: vals}
i++
}
i = 0
Expand Down
12 changes: 6 additions & 6 deletions datamodel/high/node_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,18 @@ func (n *NodeBuilder) add(key string, i int) {
j := 0
if lowExtensions != nil {
// If we have low extensions get the original lowest line number so we end up in the same place
for pair := orderedmap.First(lowExtensions); pair != nil; pair = pair.Next() {
if j == 0 || pair.Key().KeyNode.Line < j {
j = pair.Key().KeyNode.Line
for ext := range lowExtensions.KeysFromOldest() {
if j == 0 || ext.KeyNode.Line < j {
j = ext.KeyNode.Line
}
}
}

for pair := orderedmap.First(extensions); pair != nil; pair = pair.Next() {
nodeEntry := &nodes.NodeEntry{Tag: pair.Key(), Key: pair.Key(), Value: pair.Value(), Line: j}
for ext, node := range extensions.FromOldest() {
nodeEntry := &nodes.NodeEntry{Tag: ext, Key: ext, Value: node, Line: j}

if lowExtensions != nil {
lowItem := low.FindItemInOrderedMap(pair.Key(), lowExtensions)
lowItem := low.FindItemInOrderedMap(ext, lowExtensions)
nodeEntry.LowValue = lowItem
}
n.Nodes = append(n.Nodes, nodeEntry)
Expand Down
11 changes: 5 additions & 6 deletions datamodel/high/node_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,16 @@ func (te *test1) GetExtensions() *orderedmap.Map[low.KeyReference[string], low.V
g := orderedmap.New[low.KeyReference[string], low.ValueReference[*yaml.Node]]()

i := 0
for pair := orderedmap.First(te.Extensions); pair != nil; pair = pair.Next() {
kn := utils.CreateStringNode(pair.Key())
for ext, node := range te.Extensions.FromOldest() {
kn := utils.CreateStringNode(ext)
kn.Line = 999999 + i // weighted to the bottom.

g.Set(low.KeyReference[string]{
Value: pair.Key(),
Value: ext,
KeyNode: kn,
}, low.ValueReference[*yaml.Node]{
ValueNode: pair.Value(),
Value: pair.Value(),
ValueNode: node,
Value: node,
})
i++
}
Expand Down Expand Up @@ -175,7 +175,6 @@ func (t test2) GetReference() string {
}

func (t test2) SetReference(ref string, _ *yaml.Node) {

}

func (t test2) GetReferenceNode() *yaml.Node {
Expand Down
13 changes: 4 additions & 9 deletions datamodel/high/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ type GoesLowUntyped interface {
// ExtractExtensions is a convenience method for converting low-level extension definitions, to a high level *orderedmap.Map[string, *yaml.Node]
// definition that is easier to consume in applications.
func ExtractExtensions(extensions *orderedmap.Map[low.KeyReference[string], low.ValueReference[*yaml.Node]]) *orderedmap.Map[string, *yaml.Node] {
extracted := orderedmap.New[string, *yaml.Node]()
for pair := orderedmap.First(extensions); pair != nil; pair = pair.Next() {
extracted.Set(pair.Key().Value, pair.Value().Value)
}
return extracted
return low.FromReferenceMap(extensions)
}

// UnpackExtensions is a convenience function that makes it easy and simple to unpack an objects extensions
Expand All @@ -64,15 +60,14 @@ func ExtractExtensions(extensions *orderedmap.Map[low.KeyReference[string], low.
func UnpackExtensions[T any, R low.HasExtensions[T]](low GoesLow[R]) (*orderedmap.Map[string, *T], error) {
m := orderedmap.New[string, *T]()
ext := low.GoLow().GetExtensions()
for pair := orderedmap.First(ext); pair != nil; pair = pair.Next() {
key := pair.Key().Value
for ext, value := range ext.FromOldest() {
g := new(T)
valueNode := pair.Value().ValueNode
valueNode := value.ValueNode
err := valueNode.Decode(g)
if err != nil {
return nil, err
}
m.Set(key, g)
m.Set(ext.Value, g)
}
return m, nil
}
15 changes: 6 additions & 9 deletions datamodel/high/v2/examples.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
package v2

import (
low "github.com/pb33f/libopenapi/datamodel/low/v2"
"github.com/pb33f/libopenapi/datamodel/low"
lowv2 "github.com/pb33f/libopenapi/datamodel/low/v2"
"github.com/pb33f/libopenapi/orderedmap"
"gopkg.in/yaml.v3"
)
Expand All @@ -14,24 +15,20 @@ import (
// - https://swagger.io/specification/v2/#exampleObject
type Example struct {
Values *orderedmap.Map[string, *yaml.Node]
low *low.Examples
low *lowv2.Examples
}

// NewExample creates a new high-level Example instance from a low-level one.
func NewExample(examples *low.Examples) *Example {
func NewExample(examples *lowv2.Examples) *Example {
e := new(Example)
e.low = examples
if orderedmap.Len(examples.Values) > 0 {
values := orderedmap.New[string, *yaml.Node]()
for pair := orderedmap.First(examples.Values); pair != nil; pair = pair.Next() {
values.Set(pair.Key().Value, pair.Value().Value)
}
e.Values = values
e.Values = low.FromReferenceMap(examples.Values)
}
return e
}

// GoLow returns the low-level Example used to create the high-level one.
func (e *Example) GoLow() *low.Examples {
func (e *Example) GoLow() *lowv2.Examples {
return e.low
}
8 changes: 4 additions & 4 deletions datamodel/high/v2/path_item_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ func TestPathItem_GetOperations_NoLow(t *testing.T) {
expectedOrderOfOps := []string{"get", "post", "delete"}
actualOrder := []string{}

for pair := orderedmap.First(ops); pair != nil; pair = pair.Next() {
actualOrder = append(actualOrder, pair.Key())
for op := range ops.KeysFromOldest() {
actualOrder = append(actualOrder, op)
}

assert.Equal(t, expectedOrderOfOps, actualOrder)
Expand All @@ -75,8 +75,8 @@ func TestPathItem_GetOperations_LowWithUnsetOperations(t *testing.T) {
expectedOrderOfOps := []string{"get", "post", "delete"}
actualOrder := []string{}

for pair := orderedmap.First(ops); pair != nil; pair = pair.Next() {
actualOrder = append(actualOrder, pair.Key())
for op := range ops.KeysFromOldest() {
actualOrder = append(actualOrder, op)
}

assert.Equal(t, expectedOrderOfOps, actualOrder)
Expand Down
15 changes: 6 additions & 9 deletions datamodel/high/v2/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ package v2
import (
"github.com/pb33f/libopenapi/datamodel/high"
"github.com/pb33f/libopenapi/datamodel/high/base"
low "github.com/pb33f/libopenapi/datamodel/low/v2"
"github.com/pb33f/libopenapi/datamodel/low"
lowv2 "github.com/pb33f/libopenapi/datamodel/low/v2"
"github.com/pb33f/libopenapi/orderedmap"
"gopkg.in/yaml.v3"
)
Expand All @@ -20,11 +21,11 @@ type Response struct {
Headers *orderedmap.Map[string, *Header]
Examples *Example
Extensions *orderedmap.Map[string, *yaml.Node]
low *low.Response
low *lowv2.Response
}

// NewResponse creates a new high-level instance of Response from a low level one.
func NewResponse(response *low.Response) *Response {
func NewResponse(response *lowv2.Response) *Response {
r := new(Response)
r.low = response
r.Extensions = high.ExtractExtensions(response.Extensions)
Expand All @@ -35,11 +36,7 @@ func NewResponse(response *low.Response) *Response {
r.Schema = base.NewSchemaProxy(&response.Schema)
}
if !response.Headers.IsEmpty() {
headers := orderedmap.New[string, *Header]()
for pair := orderedmap.First(response.Headers.Value); pair != nil; pair = pair.Next() {
headers.Set(pair.Key().Value, NewHeader(pair.Value().Value))
}
r.Headers = headers
r.Headers = low.FromReferenceMapWithFunc(response.Headers.Value, NewHeader)
}
if !response.Examples.IsEmpty() {
r.Examples = NewExample(response.Examples.Value)
Expand All @@ -48,6 +45,6 @@ func NewResponse(response *low.Response) *Response {
}

// GoLow will return the low-level Response instance used to create the high level one.
func (r *Response) GoLow() *low.Response {
func (r *Response) GoLow() *lowv2.Response {
return r.low
}
Loading

0 comments on commit 059078e

Please sign in to comment.