Adding jflect and converted to package for generate-structs
This commit is contained in:
		@@ -1,14 +1,12 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"deadbeef.codes/steven/go-itg/itglue"
 | 
						"deadbeef.codes/steven/go-itg/itglue"
 | 
				
			||||||
	"github.com/ChimeraCoder/gojson"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var itg *itglue.ITGAPI
 | 
					var itg *itglue.ITGAPI
 | 
				
			||||||
@@ -40,21 +38,6 @@ func main() {
 | 
				
			|||||||
			log.Fatalf("could get flexible asset with type ID %d: %s", id, err)
 | 
								log.Fatalf("could get flexible asset with type ID %d: %s", id, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		name := &fat.FlexibleAssetTypeData.Attributes.Name
 | 
							//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))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user