mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-06 12:37:49 +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
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
1
go.mod
@@ -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
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/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=
|
||||||
|
|||||||
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 {
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user