Adding jflect and converted to package for generate-structs
This commit is contained in:
parent
9a9079e42d
commit
8fec1c86c7
@ -1,14 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"deadbeef.codes/steven/go-itg/itglue"
|
||||
"github.com/ChimeraCoder/gojson"
|
||||
)
|
||||
|
||||
var itg *itglue.ITGAPI
|
||||
@ -40,21 +38,6 @@ func main() {
|
||||
log.Fatalf("could get flexible asset with type ID %d: %s", id, err)
|
||||
}
|
||||
|
||||
name := &fat.FlexibleAssetTypeData.Attributes.Name
|
||||
pkg := "itglue"
|
||||
subStruct := false // try changing to true?
|
||||
tagList := make([]string, 0)
|
||||
tagList = append(tagList, "json")
|
||||
var convertFloats bool
|
||||
var parser gojson.Parser
|
||||
parser = gojson.ParseJson
|
||||
convertFloats = true
|
||||
|
||||
input := bytes.NewReader(fa)
|
||||
|
||||
output, err := gojson.Generate(input, parser, *name, pkg, tagList, subStruct, convertFloats)
|
||||
|
||||
fmt.Print(string(output))
|
||||
|
||||
//name := &fat.FlexibleAssetTypeData.Attributes.Name
|
||||
}
|
||||
}
|
||||
|
59
generate-structs/vendor/jflect/field.go
vendored
Normal file
59
generate-structs/vendor/jflect/field.go
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
package jflect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// Field data type
|
||||
type Field struct {
|
||||
name string
|
||||
gtype string
|
||||
tag string
|
||||
}
|
||||
|
||||
// Simplifies Field construction
|
||||
func NewField(name, gtype string, body ...byte) Field {
|
||||
if gtype == "struct" {
|
||||
gtype = fmt.Sprintf("%s {%s}", gtype, body)
|
||||
}
|
||||
return Field{goField(name), gtype, goTag(name)}
|
||||
}
|
||||
|
||||
// Provides Sorter interface so we can keep field order
|
||||
type FieldSort []Field
|
||||
|
||||
func (s FieldSort) Len() int { return len(s) }
|
||||
|
||||
func (s FieldSort) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
func (s FieldSort) Less(i, j int) bool {
|
||||
return s[i].name < s[j].name
|
||||
}
|
||||
|
||||
// Return lower_case json fields to camel case fields.
|
||||
func goField(jf string) string {
|
||||
mkUpper := true
|
||||
gf := ""
|
||||
for _, c := range jf {
|
||||
if mkUpper {
|
||||
c = unicode.ToUpper(c)
|
||||
mkUpper = false
|
||||
}
|
||||
if c == '_' {
|
||||
mkUpper = true
|
||||
continue
|
||||
}
|
||||
if c == '-' {
|
||||
mkUpper = true
|
||||
continue
|
||||
}
|
||||
gf += string(c)
|
||||
}
|
||||
return fmt.Sprintf("%s", gf)
|
||||
}
|
||||
|
||||
// Returns the json tag from a json field.
|
||||
func goTag(jf string) string {
|
||||
return fmt.Sprintf("`json:\"%s\"`", jf)
|
||||
}
|
132
generate-structs/vendor/jflect/main.go
vendored
Normal file
132
generate-structs/vendor/jflect/main.go
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
package jflect
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// TODO: write proper Usage and README
|
||||
var (
|
||||
ErrNotValidSyntax = errors.New("Json reflection is not valid Go syntax")
|
||||
)
|
||||
|
||||
//Read accepts a structName, json io.Reader and outputs a golang struct to an io.Writer
|
||||
func Read(structName string, r io.Reader, w io.Writer) error {
|
||||
var v interface{}
|
||||
err := json.NewDecoder(r).Decode(&v)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
// Open struct
|
||||
b, err := xreflect(v)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return err
|
||||
}
|
||||
field := NewField(structName, "struct", b...)
|
||||
fmt.Fprintf(buf, "type %s %s", field.name, field.gtype)
|
||||
|
||||
// Pass through gofmt for uniform formatting, and weak syntax check.
|
||||
b, err = format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
fmt.Println("Final Go Code")
|
||||
fmt.Println()
|
||||
os.Stderr.Write(buf.Bytes())
|
||||
fmt.Println()
|
||||
return ErrNotValidSyntax
|
||||
}
|
||||
w.Write(b)
|
||||
return nil
|
||||
}
|
||||
|
||||
func xreflect(v interface{}) ([]byte, error) {
|
||||
var (
|
||||
buf = new(bytes.Buffer)
|
||||
)
|
||||
fields := []Field{}
|
||||
switch root := v.(type) {
|
||||
case map[string]interface{}:
|
||||
for key, val := range root {
|
||||
switch j := val.(type) {
|
||||
case nil:
|
||||
// FIXME: sometimes json service will return nil even though the type is string.
|
||||
// go can not convert string to nil and vs versa. Can we assume its a string?
|
||||
continue
|
||||
case float64:
|
||||
fields = append(fields, NewField(key, "int"))
|
||||
case map[string]interface{}:
|
||||
// If type is map[string]interface{} then we have nested object, Recurse
|
||||
o, err := xreflect(j)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
fields = append(fields, NewField(key, "struct", o...))
|
||||
case []interface{}:
|
||||
gtype, err := sliceType(j)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return nil, err
|
||||
}
|
||||
fields = append(fields, NewField(key, gtype))
|
||||
default:
|
||||
fields = append(fields, NewField(key, fmt.Sprintf("%T", val)))
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("%T: unexpected type", root)
|
||||
}
|
||||
// Sort and write field buffer last to keep order and formatting.
|
||||
sort.Sort(FieldSort(fields))
|
||||
for _, f := range fields {
|
||||
fmt.Fprintf(buf, "%s %s %s\n", f.name, f.gtype, f.tag)
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// if all entries in j are the same type, return slice of that type
|
||||
func sliceType(j []interface{}) (string, error) {
|
||||
dft := "[]interface{}"
|
||||
if len(j) == 0 {
|
||||
return dft, nil
|
||||
}
|
||||
var t, t2 string
|
||||
for _, v := range j {
|
||||
switch v.(type) {
|
||||
case string:
|
||||
t2 = "[]string"
|
||||
case float64:
|
||||
t2 = "[]int"
|
||||
case map[string]interface{}:
|
||||
t2 = "[]struct"
|
||||
default:
|
||||
// something else, just return default
|
||||
return dft, nil
|
||||
}
|
||||
if t != "" && t != t2 {
|
||||
return dft, nil
|
||||
}
|
||||
t = t2
|
||||
}
|
||||
|
||||
if t == "[]struct" {
|
||||
o, err := xreflect(j[0])
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return "", err
|
||||
}
|
||||
f := NewField("", "struct", o...)
|
||||
t = "[]" + f.gtype
|
||||
}
|
||||
return t, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user