Working on building out models

a recursive approach? or a dfs approach? not sure yet. still playing with ideas.
This commit is contained in:
Dave Shanley
2022-07-29 09:44:37 -04:00
parent a906d46227
commit eda834f79f
9 changed files with 210 additions and 3 deletions

View File

@@ -1,6 +1,11 @@
package v3 package v3
import "github.com/pb33f/libopenapi/datamodel/low" import (
"fmt"
"github.com/pb33f/libopenapi/datamodel/low"
"gopkg.in/yaml.v3"
"reflect"
)
type Document struct { type Document struct {
Version string Version string
@@ -13,3 +18,31 @@ type Document struct {
ExternalDocs ExternalDoc ExternalDocs ExternalDoc
Extensions map[string]low.ObjectReference Extensions map[string]low.ObjectReference
} }
func (d Document) Build(node *yaml.Node) {
doc := Document{
Version: "",
Info: Info{},
Servers: nil,
Paths: Paths{},
Components: Components{},
Security: nil,
Tags: nil,
ExternalDocs: ExternalDoc{},
Extensions: nil,
}
var j interface{}
j = doc
t := reflect.TypeOf(j)
v := reflect.ValueOf(j)
k := t.Kind()
fmt.Println("Type ", t)
fmt.Println("Value ", v)
fmt.Println("Kind ", k)
for i := 0; i < v.NumField(); i++ {
fmt.Printf("Field:%d type:%T value:%v\n", i, v.Field(i), v.Field(i))
}
}

View File

@@ -6,6 +6,10 @@ type HasNode interface {
GetNode() *yaml.Node GetNode() *yaml.Node
} }
type Buildable interface {
Build(node *yaml.Node)
}
type NodeReference[T comparable] struct { type NodeReference[T comparable] struct {
Value T Value T
Node *yaml.Node Node *yaml.Node

1
go.mod
View File

@@ -11,5 +11,6 @@ require (
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect
github.com/iancoleman/strcase v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
) )

2
go.sum
View File

@@ -26,6 +26,8 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=

View File

@@ -0,0 +1,19 @@
package openapi
import (
"github.com/pb33f/libopenapi/datamodel"
v3 "github.com/pb33f/libopenapi/datamodel/low/3.0"
)
func CreateDocument(spec []byte) (*v3.Document, error) {
// extract details from spec
info, err := datamodel.ExtractSpecInfo(spec)
if err != nil {
return nil, err
}
doc := &v3.Document{}
doc.Build(info.RootNode.Content[0])
return doc, nil
}

View File

@@ -0,0 +1,22 @@
package openapi
import (
"github.com/stretchr/testify/assert"
"io/ioutil"
"testing"
)
func TestCreateDocument_NoData(t *testing.T) {
doc, err := CreateDocument(nil)
assert.Nil(t, doc)
assert.Error(t, err)
}
func TestCreateDocument(t *testing.T) {
data, aErr := ioutil.ReadFile("../test_specs/petstorev3.json")
assert.NoError(t, aErr)
doc, err := CreateDocument(data)
assert.NotNil(t, doc)
assert.NoError(t, err)
}

75
utils/model_builder.go Normal file
View File

@@ -0,0 +1,75 @@
package utils
import (
"fmt"
"github.com/iancoleman/strcase"
"gopkg.in/yaml.v3"
"reflect"
"strconv"
)
func BuildModel(node *yaml.Node, model interface{}) error {
v := reflect.ValueOf(model).Elem()
for i := 0; i < v.NumField(); i++ {
fName := v.Type().Field(i).Name
fieldName := strcase.ToLowerCamel(fName)
_, vn := FindKeyNode(fieldName, node.Content)
field := v.FieldByName(fName)
switch v.Field(i).Kind() {
case reflect.Int:
if vn != nil {
if IsNodeIntValue(vn) {
if field.CanSet() {
fv, _ := strconv.Atoi(vn.Value)
field.SetInt(int64(fv))
}
}
}
break
case reflect.String:
if vn != nil {
if IsNodeStringValue(vn) {
if field.CanSet() {
field.SetString(vn.Value)
}
}
}
break
case reflect.Bool:
if vn != nil {
if IsNodeBoolValue(vn) {
if field.CanSet() {
bv, _ := strconv.ParseBool(vn.Value)
field.SetBool(bv)
}
}
}
break
case reflect.Array:
// TODO
break
case reflect.Float32, reflect.Float64:
if vn != nil {
if IsNodeFloatValue(vn) {
if field.CanSet() {
fv, _ := strconv.ParseFloat(vn.Value, 64)
field.SetFloat(fv)
}
}
}
break
case reflect.Struct:
// TODO
break
default:
fmt.Printf("Unsupported type: %v", v.Field(i).Kind())
break
}
}
return nil
}

View File

@@ -0,0 +1,51 @@
package utils
import (
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
"testing"
)
type spank[t any] struct {
life t
}
type hotdog struct {
Name string
Beef bool
Fat int
Ketchup float32
Mustard float64
Grilled spank[bool]
NotGrilled spank[string]
}
func (h hotdog) Build(node *yaml.Node) {
}
func TestBuildModel(t *testing.T) {
yml := `name: yummy
beef: true
fat: 200
ketchup: 200.45
mustard: 324938249028.98234892374892374923874823974
grilled: false
notGrilled: false`
var rootNode yaml.Node
mErr := yaml.Unmarshal([]byte(yml), &rootNode)
assert.NoError(t, mErr)
hd := hotdog{}
cErr := BuildModel(&rootNode, &hd)
assert.Equal(t, 200, hd.Fat)
assert.Equal(t, true, hd.Beef)
assert.Equal(t, "yummy", hd.Name)
assert.Equal(t, float32(200.45), hd.Ketchup)
assert.Equal(t, 324938249028.98234892374892374923874823974, hd.Mustard)
assert.NoError(t, cErr)
}

View File

@@ -99,8 +99,8 @@ func ConvertInterfaceToStringArray(raw interface{}) []string {
if vals, ok := raw.(map[string]interface{}); ok { if vals, ok := raw.(map[string]interface{}); ok {
var s []string var s []string
for _, v := range vals { for _, v := range vals {
if v, ok := v.([]interface{}); ok { if g, y := v.([]interface{}); y {
for _, q := range v { for _, q := range g {
s = append(s, fmt.Sprint(q)) s = append(s, fmt.Sprint(q))
} }
} }