Created
May 17, 2019 05:45
-
-
Save mjarkk/0e1d3f1a1729dd9f1eb34cde0bd5d3db to your computer and use it in GitHub Desktop.
Confert a golang struct into usable type data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"reflect" | |
) | |
type Test2 struct { | |
B string | |
} | |
type Test1 struct { | |
A string `json:"A-test-A"` | |
AA []string | |
Aa int | |
Ab int8 | |
Ac int16 | |
Ad int32 | |
Ae int64 | |
Af uint | |
Ag uint8 | |
Ah uint16 | |
Ai uint32 | |
Aj uint64 | |
Ak bool | |
Al *bool | |
C [][][]Test2 | |
D struct { | |
A int | |
} | |
E map[string]string | |
F Test2 | |
} | |
func main() { | |
out, err := GetTypeMap(Test1{}, true) | |
if err != nil { | |
panic(err) | |
} | |
b, err := json.Marshal(out) | |
if err != nil { | |
panic(err) | |
} | |
fmt.Println(string(b)) | |
} | |
// GetTypeMap returns a map with the outline of a struct | |
func GetTypeMap(val interface{}, useJSONTags bool) (map[string]TypeField, error) { | |
v := reflect.ValueOf(val) | |
if v.Kind() == reflect.Struct { | |
return parseStruct(v.Type(), useJSONTags), nil | |
} | |
return map[string]TypeField{}, fmt.Errorf("val must be a struct") | |
} | |
// TypeField describes a struct's value | |
type TypeField struct { | |
Type string `json:"type"` | |
NestedOptions []string `json:"nestedOptions"` | |
StructDetials map[string]TypeField `json:"structDetials"` | |
} | |
func parseStruct(t reflect.Type, useJSONTags bool) map[string]TypeField { | |
toReturn := map[string]TypeField{} | |
for i := 0; i < t.NumField(); i++ { | |
name := t.Field(i).Name | |
jsonName := t.Field(i).Tag.Get("json") | |
if useJSONTags && jsonName != "" { | |
name = jsonName | |
} | |
ft := t.Field(i).Type | |
kind := ft.Kind() | |
toAdd := TypeField{} | |
// Deal with the pointers, maps, arrays | |
looper: | |
for { | |
switch kind { | |
case reflect.Slice: | |
toAdd.NestedOptions = append(toAdd.NestedOptions, "slice") | |
ft = ft.Elem() | |
kind = ft.Kind() | |
case reflect.Map: | |
toAdd.NestedOptions = append(toAdd.NestedOptions, ft.Key().Name()) | |
ft = ft.Elem() | |
kind = ft.Kind() | |
case reflect.Ptr: | |
toAdd.NestedOptions = append(toAdd.NestedOptions, "ptr") | |
ft = ft.Elem() | |
kind = ft.Kind() | |
default: | |
break looper | |
} | |
} | |
switch kind { | |
case reflect.Struct: | |
toAdd.Type = kind.String() | |
toAdd.StructDetials = parseStruct(ft, useJSONTags) | |
case reflect.Bool, reflect.String, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | |
toAdd.Type = kind.String() | |
default: | |
fmt.Println(name+", Unkown kind:", ft.String(), ft.Kind()) | |
continue | |
} | |
toReturn[name] = toAdd | |
} | |
return toReturn | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"A-test-A": { | |
"type": "string", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"AA": { | |
"type": "string", | |
"nestedOptions": [ | |
"slice" | |
], | |
"structDetials": null | |
}, | |
"Aa": { | |
"type": "int", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Ab": { | |
"type": "int8", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Ac": { | |
"type": "int16", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Ad": { | |
"type": "int32", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Ae": { | |
"type": "int64", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Af": { | |
"type": "uint", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Ag": { | |
"type": "uint8", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Ah": { | |
"type": "uint16", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Ai": { | |
"type": "uint32", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Aj": { | |
"type": "uint64", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Ak": { | |
"type": "bool", | |
"nestedOptions": null, | |
"structDetials": null | |
}, | |
"Al": { | |
"type": "bool", | |
"nestedOptions": [ | |
"ptr" | |
], | |
"structDetials": null | |
}, | |
"C": { | |
"type": "struct", | |
"nestedOptions": [ | |
"slice", | |
"slice", | |
"slice" | |
], | |
"structDetials": { | |
"B": { | |
"type": "string", | |
"nestedOptions": null, | |
"structDetials": null | |
} | |
} | |
}, | |
"D": { | |
"type": "struct", | |
"nestedOptions": null, | |
"structDetials": { | |
"A": { | |
"type": "int", | |
"nestedOptions": null, | |
"structDetials": null | |
} | |
} | |
}, | |
"E": { | |
"type": "string", | |
"nestedOptions": [ | |
"string" | |
], | |
"structDetials": null | |
}, | |
"F": { | |
"type": "struct", | |
"nestedOptions": null, | |
"structDetials": { | |
"B": { | |
"type": "string", | |
"nestedOptions": null, | |
"structDetials": null | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment