github.com/v2pro/plz@v0.0.0-20221028024117-e5f9aec5b631/dump/dumpvar.go (about) 1 package dump 2 3 import ( 4 "unsafe" 5 "github.com/v2pro/plz/msgfmt/jsonfmt" 6 "reflect" 7 "context" 8 "encoding/json" 9 ) 10 11 var addrMapKey = 2020020002 12 var dumper = jsonfmt.Config{ 13 IncludesUnexported: true, 14 Extensions: []jsonfmt.Extension{&dumpExtension{}}, 15 }.Froze() 16 17 var efaceType = reflect.TypeOf(eface{}) 18 var efaceEncoderInst = dumper.EncoderOf(reflect.TypeOf(eface{})) 19 var addrMapEncoderInst = jsonfmt.EncoderOf(reflect.TypeOf(map[string]json.RawMessage{})) 20 21 type Var struct { 22 Object interface{} 23 } 24 25 func (v Var) String() string { 26 addrMap := map[string]json.RawMessage{} 27 ctx := context.WithValue(context.Background(), addrMapKey, addrMap) 28 rootPtr := unsafe.Pointer(&v.Object) 29 output := efaceEncoderInst.Encode(ctx, nil, rootPtr) 30 addrMap["__root__"] = json.RawMessage(output) 31 output = addrMapEncoderInst.Encode(nil, nil, reflect2.PtrOf(addrMap)) 32 return string(output) 33 } 34 35 type VarSnapshot string 36 37 func Snapshot(obj interface{}) VarSnapshot { 38 return VarSnapshot(Var{Object: obj}.String()) 39 } 40 41 func (snapshot VarSnapshot) String() string { 42 return string(snapshot) 43 } 44 45 func ptrToStr(ptr uintptr) string { 46 return string(jsonfmt.WriteUint64(nil, uint64(ptr))) 47 } 48 49 type dumpExtension struct { 50 } 51 52 func (extension *dumpExtension) EncoderOf(prefix string, valType reflect.Type) jsonfmt.Encoder { 53 if valType == efaceType { 54 return &efaceEncoder{} 55 } 56 switch valType.Kind() { 57 case reflect.String: 58 return &stringEncoder{} 59 case reflect.Ptr: 60 return &pointerEncoder{ 61 elemEncoder: dumper.EncoderOf(valType.Elem()), 62 } 63 case reflect.Slice: 64 return &sliceEncoder{ 65 elemEncoder: dumper.EncoderOf(valType.Elem()), 66 elemSize: valType.Elem().Size(), 67 } 68 case reflect.Map: 69 return newMapEncoder(dumper, valType) 70 } 71 return nil 72 } 73 74 type iface struct { 75 itab unsafe.Pointer 76 data unsafe.Pointer 77 }