mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 04:20:11 +00:00
Working on building out models
a recursive approach? or a dfs approach? not sure yet. still playing with ideas.
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
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 {
|
||||
Version string
|
||||
@@ -13,3 +18,31 @@ type Document struct {
|
||||
ExternalDocs ExternalDoc
|
||||
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))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ type HasNode interface {
|
||||
GetNode() *yaml.Node
|
||||
}
|
||||
|
||||
type Buildable interface {
|
||||
Build(node *yaml.Node)
|
||||
}
|
||||
|
||||
type NodeReference[T comparable] struct {
|
||||
Value T
|
||||
Node *yaml.Node
|
||||
|
||||
1
go.mod
1
go.mod
@@ -11,5 +11,6 @@ require (
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // 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
|
||||
)
|
||||
|
||||
2
go.sum
2
go.sum
@@ -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/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
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/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
|
||||
19
openapi/create_document.go
Normal file
19
openapi/create_document.go
Normal 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
|
||||
}
|
||||
22
openapi/create_document_test.go
Normal file
22
openapi/create_document_test.go
Normal 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
75
utils/model_builder.go
Normal 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
|
||||
}
|
||||
51
utils/model_builder_test.go
Normal file
51
utils/model_builder_test.go
Normal 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)
|
||||
|
||||
}
|
||||
@@ -99,8 +99,8 @@ func ConvertInterfaceToStringArray(raw interface{}) []string {
|
||||
if vals, ok := raw.(map[string]interface{}); ok {
|
||||
var s []string
|
||||
for _, v := range vals {
|
||||
if v, ok := v.([]interface{}); ok {
|
||||
for _, q := range v {
|
||||
if g, y := v.([]interface{}); y {
|
||||
for _, q := range g {
|
||||
s = append(s, fmt.Sprint(q))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user