|
@@ -1,8 +1,12 @@
|
|
|
package autostruct
|
|
|
|
|
|
import (
|
|
|
+ "encoding/json"
|
|
|
"fmt"
|
|
|
+ "log"
|
|
|
"os"
|
|
|
+ "reflect"
|
|
|
+ "strings"
|
|
|
)
|
|
|
|
|
|
// Generates structures given json
|
|
@@ -15,19 +19,20 @@ type AutoStruct struct {
|
|
|
File *os.File // Access to the new go file (writer)
|
|
|
}
|
|
|
|
|
|
+// Sets up the AutoStruct to build a go file containing structures
|
|
|
//
|
|
|
+// Structname is a prefix to add to all structures, if no prefix desired leave an empty string in place
|
|
|
func (a *AutoStruct) Init(fname, packname, structname string) error {
|
|
|
a.StructName = structname
|
|
|
a.FileName = fname
|
|
|
a.PackageName = packname
|
|
|
- if !FileExists(a.FileName + ".go") {
|
|
|
- var err error
|
|
|
- a.File, err = os.Create(a.FileName + ".go")
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- } else {
|
|
|
- return fmt.Errorf("file already exists, update mode is not yet implemented")
|
|
|
+ var err error
|
|
|
+ if FileExists(a.FileName + ".go") {
|
|
|
+ log.Printf("AutoStruct.Init('%s', '%s', '%s') => Warning, file exists, this is an experimental feature.", fname, packname, structname)
|
|
|
+ }
|
|
|
+ a.File, err = os.OpenFile(a.FileName+".go", os.O_CREATE|os.O_RDWR, 0666)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
@@ -145,3 +150,57 @@ func (a *AutoStruct) Comment(comment string) {
|
|
|
func (a *AutoStruct) Close() {
|
|
|
a.File.Close()
|
|
|
}
|
|
|
+
|
|
|
+// Forms needed structures and a master structure
|
|
|
+//
|
|
|
+// TODO: Change it so it actually forms a map[string]string key=fieldname value=fieldtype
|
|
|
+// This will allow us to then form other structures we need as we iterate the data
|
|
|
+func (a *AutoStruct) LoadJson(filename, structname string) (int, error) {
|
|
|
+ var structsMade int
|
|
|
+ var err error
|
|
|
+ var file []byte
|
|
|
+ file, err = os.ReadFile(filename + ".json")
|
|
|
+ if err != nil {
|
|
|
+ return structsMade, err
|
|
|
+ }
|
|
|
+ var data map[string]interface{}
|
|
|
+ err = json.Unmarshal(file, &data)
|
|
|
+ if err != nil {
|
|
|
+ return structsMade, err
|
|
|
+ }
|
|
|
+ fmt.Printf("%#v\n", data)
|
|
|
+ // Wrong, we actually want to store this then make any substructures then make the base struct
|
|
|
+ a.StartStruct(structname)
|
|
|
+ for k, v := range data {
|
|
|
+ k = strings.ReplaceAll(k, "-", "_") // Replace '-' with '_'
|
|
|
+ k = strings.ReplaceAll(k, " ", "") // Remove ' '
|
|
|
+ switch reflect.TypeOf(v).Kind() {
|
|
|
+ case reflect.Array, reflect.Slice:
|
|
|
+ // Array or slice []
|
|
|
+ // Check all types are the same (else need new struct)
|
|
|
+ // Iterate over nested array/slice and maps
|
|
|
+
|
|
|
+ // Assuming all types are same
|
|
|
+ var array []interface{} = v.([]interface{})
|
|
|
+ a.AddField(k, "[]"+reflect.TypeOf(array[0]).String())
|
|
|
+ case reflect.Map:
|
|
|
+ // Map key, val
|
|
|
+ // Check all types are the same (else need new struct)
|
|
|
+ // Iterate over nested array/slice and maps
|
|
|
+
|
|
|
+ // Assuming all types are same
|
|
|
+ var mp map[string]interface{} = v.(map[string]interface{})
|
|
|
+ var keys []string = make([]string, 0, len(mp))
|
|
|
+ for k2 := range mp {
|
|
|
+ keys = append(keys, k2)
|
|
|
+ }
|
|
|
+ a.AddField(k, "map[string]"+reflect.TypeOf(mp[keys[0]]).String())
|
|
|
+ default:
|
|
|
+ // Fallback
|
|
|
+ a.AddField(k, reflect.TypeOf(v).String())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ structsMade += 1
|
|
|
+ a.EndStruct()
|
|
|
+ return structsMade, nil
|
|
|
+}
|