diff --git a/datamodel/low/3.0/document.go b/datamodel/low/3.0/document.go index 46f7cf4..518eb25 100644 --- a/datamodel/low/3.0/document.go +++ b/datamodel/low/3.0/document.go @@ -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)) + } + +} diff --git a/datamodel/low/reference.go b/datamodel/low/reference.go index f7539d5..3c882a9 100644 --- a/datamodel/low/reference.go +++ b/datamodel/low/reference.go @@ -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 diff --git a/go.mod b/go.mod index 6addddc..d522fd3 100644 --- a/go.mod +++ b/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 ) diff --git a/go.sum b/go.sum index 5a58cfc..f91b384 100644 --- a/go.sum +++ b/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= diff --git a/openapi/create_document.go b/openapi/create_document.go new file mode 100644 index 0000000..861d653 --- /dev/null +++ b/openapi/create_document.go @@ -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 +} diff --git a/openapi/create_document_test.go b/openapi/create_document_test.go new file mode 100644 index 0000000..94c1f91 --- /dev/null +++ b/openapi/create_document_test.go @@ -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) +} diff --git a/utils/model_builder.go b/utils/model_builder.go new file mode 100644 index 0000000..605378e --- /dev/null +++ b/utils/model_builder.go @@ -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 +} diff --git a/utils/model_builder_test.go b/utils/model_builder_test.go new file mode 100644 index 0000000..839a052 --- /dev/null +++ b/utils/model_builder_test.go @@ -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) + +} diff --git a/utils/utils.go b/utils/utils.go index 04e93a1..c95db18 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -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)) } }