Created
April 13, 2016 11:17
-
-
Save coyove/b82b6880288bb72c3f983e4a0fed1c41 to your computer and use it in GitHub Desktop.
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" | |
"log" | |
"unsafe" | |
) | |
type JsonHelper struct { | |
parents []*JsonHelper | |
Objects map[string]interface{} | |
ObjectsArray []interface{} | |
} | |
func (jo JsonHelper) New() *JsonHelper { | |
j := &JsonHelper{} | |
j.parents = make([]*JsonHelper, 0) | |
j.Objects = make(map[string]interface{}) | |
j.ObjectsArray = nil | |
return j | |
} | |
func (jo JsonHelper) FromStruct(s interface{}) *JsonHelper { | |
j := &JsonHelper{} | |
j.parents = make([]*JsonHelper, 0) | |
buf, _ := json.Marshal(s) | |
json.Unmarshal(buf, &j.Objects) | |
j.ObjectsArray = nil | |
return j | |
} | |
func (jo JsonHelper) NewArray() *JsonHelper { | |
j := &JsonHelper{} | |
j.parents = make([]*JsonHelper, 0) | |
j.Objects = nil | |
j.ObjectsArray = make([]interface{}, 0) | |
return j | |
} | |
func (jo *JsonHelper) Get(name interface{}) interface{} { | |
if jo.Objects != nil { | |
return jo.Objects[name.(string)] | |
} else { | |
return jo.ObjectsArray[name.(int)] | |
} | |
} | |
func (jo *JsonHelper) Set(name interface{}, values ...interface{}) *JsonHelper { | |
if jo.Objects != nil { | |
jo.ObjectsArray = nil | |
var x []interface{} | |
if len(values) > 1 { | |
jo.Objects[name.(string)] = make([]interface{}, len(values)) | |
x = jo.Objects[name.(string)].([]interface{}) | |
} | |
for i, v := range values { | |
var value interface{} | |
switch v.(type) { | |
case *JsonHelper: | |
if v.(*JsonHelper).Objects == nil { | |
value = v.(*JsonHelper).ObjectsArray | |
} else { | |
value = v.(*JsonHelper).Objects | |
} | |
default: | |
value = v | |
} | |
if len(values) == 1 { | |
jo.Objects[name.(string)] = value | |
} else { | |
x[i] = value | |
} | |
} | |
} else { | |
jo.Objects = nil | |
index := name.(int) | |
var x []interface{} | |
if len(values) > 1 { | |
jo.ObjectsArray[index] = make([]interface{}, len(values)) | |
x = jo.ObjectsArray[index].([]interface{}) | |
} | |
for i, v := range values { | |
var value interface{} | |
switch v.(type) { | |
case *JsonHelper: | |
if v.(*JsonHelper).Objects == nil { | |
value = v.(*JsonHelper).ObjectsArray | |
} else { | |
value = v.(*JsonHelper).Objects | |
} | |
default: | |
value = v | |
} | |
if len(values) == 1 { | |
jo.ObjectsArray[index] = value | |
} else { | |
x[i] = value | |
} | |
} | |
} | |
return jo | |
} | |
func (jo *JsonHelper) Push(values ...interface{}) *JsonHelper { | |
if jo.Objects == nil { | |
for _, v := range values { | |
switch v.(type) { | |
case *JsonHelper: | |
_v := v.(*JsonHelper) | |
if _v.Objects == nil { | |
jo.ObjectsArray = append(jo.ObjectsArray, v.(*JsonHelper).ObjectsArray) | |
} else { | |
jo.ObjectsArray = append(jo.ObjectsArray, v.(*JsonHelper).Objects) | |
} | |
default: | |
jo.ObjectsArray = append(jo.ObjectsArray, v) | |
} | |
} | |
} | |
return jo | |
} | |
func (jo *JsonHelper) Delete(name interface{}) *JsonHelper { | |
if jo.Objects != nil { | |
delete(jo.Objects, name.(string)) | |
} else { | |
index := name.(int) | |
if index < len(jo.ObjectsArray) { | |
jo.ObjectsArray = append(jo.ObjectsArray[:index], jo.ObjectsArray[index+1:]...) | |
type sliceDescriptor struct { | |
Elem uintptr | |
Len int | |
Cap int | |
} | |
var sd = (*sliceDescriptor)(unsafe.Pointer(&jo.ObjectsArray)) | |
log.Println(sd.Len) | |
} | |
} | |
return jo | |
} | |
func (jo *JsonHelper) End() *JsonHelper { | |
return jo.Leave() | |
} | |
func (jo *JsonHelper) Leave() *JsonHelper { | |
if len(jo.parents) == 0 { | |
log.Fatal("[JsonHelper] No more upstairs") | |
return jo | |
} | |
lp := jo.parents[len(jo.parents)-1] | |
np := jo.parents[:len(jo.parents)-1] | |
return &JsonHelper{np, lp.Objects, lp.ObjectsArray} | |
} | |
func (jo *JsonHelper) Begin(n interface{}) *JsonHelper { | |
return jo.Enter(n) | |
} | |
func (jo *JsonHelper) Enter(n interface{}) *JsonHelper { | |
if jo.Objects != nil { | |
name := n.(string) | |
if _, e := jo.Objects[name]; !e { | |
jo.Objects[name] = make(map[string]interface{}) | |
} | |
switch jo.Objects[name].(type) { | |
case map[string]interface{}: | |
return &JsonHelper{ | |
append(jo.parents, jo), | |
jo.Objects[name].(map[string]interface{}), | |
nil, | |
} | |
case []interface{}: | |
return &JsonHelper{ | |
append(jo.parents, jo), | |
nil, | |
jo.Objects[name].([]interface{}), | |
} | |
} | |
} else { | |
index := n.(int) | |
switch jo.ObjectsArray[index].(type) { | |
case map[string]interface{}: | |
return &JsonHelper{ | |
append(jo.parents, jo), | |
jo.ObjectsArray[index].(map[string]interface{}), | |
nil, | |
} | |
case []interface{}: | |
return &JsonHelper{ | |
append(jo.parents, jo), | |
nil, | |
jo.ObjectsArray[index].([]interface{}), | |
} | |
} | |
} | |
return nil | |
} | |
func (jo *JsonHelper) Dive(name ...string) *JsonHelper { | |
p := jo | |
for _, v := range name { | |
p = p.Enter(v) | |
} | |
return p | |
} | |
func (jo *JsonHelper) Marshal() string { | |
if jo.ObjectsArray == nil { | |
buf, _ := json.Marshal(jo.Objects) | |
return string(buf) | |
} else { | |
buf, _ := json.Marshal(jo.ObjectsArray) | |
return string(buf) | |
} | |
} | |
func (jo *JsonHelper) MarshalPretty() string { | |
if jo.ObjectsArray == nil { | |
buf, _ := json.MarshalIndent(jo.Objects, "", " ") | |
return string(buf) | |
} else { | |
buf, _ := json.MarshalIndent(jo.ObjectsArray, "", " ") | |
return string(buf) | |
} | |
} | |
type Foo struct { | |
Name string | |
Age int | |
Address string | |
} | |
func main() { | |
foo := Foo{"zzz", 25, "china"} | |
tmp := JsonHelper{}.FromStruct(foo) | |
tmp. | |
Begin("family"). | |
/* */ Set("father", "zzz_father"). | |
/* */ Set("mother", "zzz_mother"). | |
/* */ Set("brothers", JsonHelper{}.NewArray().Push( | |
/* */ /* */ "brother_1", | |
/* */ /* */ "brother_2", | |
/* */ /* */ "brother_3")). | |
End() | |
tmp.Enter("family").Set("sisters", "sister_1", "sister_2", "sister_3") | |
tmp.Enter("family").Enter("brothers").Set(2, JsonHelper{}.NewArray().Push("cousin_1")) | |
fmt.Println("#1", tmp.MarshalPretty()) | |
tmp.Delete("Address") | |
tmp.Enter("family").Delete("sisters") | |
fmt.Println("#2", tmp.MarshalPretty()) | |
tmp.Enter("family").Enter("brothers").Delete(1) | |
fmt.Println("#3", tmp.MarshalPretty()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment