Skip to content

Instantly share code, notes, and snippets.

@wtnb75
Created December 10, 2014 15:08
Show Gist options
  • Save wtnb75/f7de04970736de4eb0ff to your computer and use it in GitHub Desktop.
Save wtnb75/f7de04970736de4eb0ff to your computer and use it in GitHub Desktop.
go run json2go.go < input.json > test.go ; go run test.go < input.json
package main
import (
"encoding/json"
"io"
"log"
"os"
"reflect"
"strings"
"unicode"
"unicode/utf8"
)
func dumpelement(typ reflect.Type, val reflect.Value, ofp io.Writer) {
io.WriteString(ofp, typ.String())
}
func dumpinterface(typ reflect.Type, val reflect.Value, ofp io.Writer) {
intf := val.Interface()
switch t := intf.(type) {
case bool:
// io.WriteString(ofp, "bool")
case int64, int, uint64, uint, float64, float32:
// io.WriteString(ofp, "int64")
case string:
// io.WriteString(ofp, "string")
case map[string]interface{}:
// io.WriteString(ofp, "")
case []interface{}:
io.WriteString(ofp, "[]")
dump0(t[0], ofp)
return
default:
log.Printf("unknown type: %T, %v %v %v", t, val, typ, intf)
}
dump0(intf, ofp)
}
func dumparray(typ reflect.Type, val reflect.Value, ofp io.Writer) {
io.WriteString(ofp, "[]")
v2 := val.Index(0)
t2 := v2.Type()
dump1(t2, v2, ofp)
}
func dumpmap(typ reflect.Type, val reflect.Value, ofp io.Writer) {
io.WriteString(ofp, " struct {\n")
ktyp := typ.Key()
if ktyp.Kind() != reflect.String {
log.Fatal("key type is not string.", typ, val)
}
for _, k2 := range val.MapKeys() {
name := k2.String()
rune, _ := utf8.DecodeRuneInString(name)
if !unicode.IsUpper(rune) {
name = strings.Title(name)
}
io.WriteString(ofp, name+" ")
v2 := val.MapIndex(k2)
t2 := v2.Type()
dump1(t2, v2, ofp)
tag := "`json:\",omitempty\"`"
if name != k2.String() {
tag = "`json:\"" + k2.String() + ",omitempty\"`"
}
io.WriteString(ofp, " "+tag+"\n")
}
io.WriteString(ofp, "}")
}
func dump1(typ reflect.Type, val reflect.Value, ofp io.Writer) {
switch typ.Kind() {
case reflect.Array:
dumparray(typ, val, ofp)
case reflect.Map:
dumpmap(typ, val, ofp)
case reflect.Interface:
dumpinterface(typ, val, ofp)
default:
dumpelement(typ, val, ofp)
}
}
func dump0(v interface{}, ofp io.Writer) {
typ := reflect.TypeOf(v)
val := reflect.ValueOf(v)
dump1(typ, val, ofp)
}
var TestMain = true
func main() {
ifp := os.Stdin
ofp := os.Stdout
dec := json.NewDecoder(ifp)
var data interface{}
err := dec.Decode(&data)
if err != nil {
log.Println("err", err)
}
log.Println("decoded", data)
if TestMain {
io.WriteString(ofp, "package main\n")
io.WriteString(ofp, `
import (
"os"
"log"
"encoding/json"
)
`)
} else {
io.WriteString(ofp, "package fromjson\n")
}
io.WriteString(ofp, "type FromJson ")
dump0(data, ofp)
io.WriteString(ofp, "\n")
if TestMain {
io.WriteString(ofp, `
func main(){
var data FromJson
dec := json.NewDecoder(os.Stdin)
if err := dec.Decode(&data); err!=nil{
log.Println("error", err)
}else{
log.Printf("decoded: %+v\n", data)
}
}
`)
}
return
}
@wtnb75
Copy link
Author

wtnb75 commented Dec 10, 2014

Basic Usage

test.json

{
  "test": 1,
  "test2":[
  { "a":"b", "c":10 }, 
  { "a":"e", "c":100 }
  ],
  "Test3":"value"
}
  • go run json2go.go < test.json > test.go
    • decoded map[test:1 test2:[map[c:10 a:b] map[a:e c:100]] Test3:value]
  • (go fmt test.go)
  • go run test.go < test.json
    • decoded: {Test:1 Test2:[{A:b C:10} {A:e C:100}] Test3:value}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment