github.com/gogf/gf@v1.16.9/util/gutil/gutil_dump.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gutil 8 9 import ( 10 "bytes" 11 "fmt" 12 "github.com/gogf/gf/internal/json" 13 "github.com/gogf/gf/util/gconv" 14 "os" 15 "reflect" 16 ) 17 18 // apiVal is used for type assert api for Val(). 19 type apiVal interface { 20 Val() interface{} 21 } 22 23 // apiString is used for type assert api for String(). 24 type apiString interface { 25 String() string 26 } 27 28 // apiMapStrAny is the interface support for converting struct parameter to map. 29 type apiMapStrAny interface { 30 MapStrAny() map[string]interface{} 31 } 32 33 // Dump prints variables <i...> to stdout with more manually readable. 34 func Dump(i ...interface{}) { 35 s := Export(i...) 36 if s != "" { 37 fmt.Println(s) 38 } 39 } 40 41 // Export returns variables <i...> as a string with more manually readable. 42 func Export(i ...interface{}) string { 43 buffer := bytes.NewBuffer(nil) 44 for _, value := range i { 45 switch r := value.(type) { 46 case []byte: 47 buffer.Write(r) 48 case string: 49 buffer.WriteString(r) 50 default: 51 var ( 52 reflectValue = reflect.ValueOf(value) 53 reflectKind = reflectValue.Kind() 54 ) 55 for reflectKind == reflect.Ptr { 56 reflectValue = reflectValue.Elem() 57 reflectKind = reflectValue.Kind() 58 } 59 switch reflectKind { 60 case reflect.Slice, reflect.Array: 61 value = gconv.Interfaces(value) 62 case reflect.Map: 63 value = gconv.Map(value) 64 case reflect.Struct: 65 converted := false 66 if r, ok := value.(apiVal); ok { 67 if result := r.Val(); result != nil { 68 value = result 69 converted = true 70 } 71 } 72 if !converted { 73 if r, ok := value.(apiMapStrAny); ok { 74 if result := r.MapStrAny(); result != nil { 75 value = result 76 converted = true 77 } 78 } 79 } 80 if !converted { 81 if r, ok := value.(apiString); ok { 82 value = r.String() 83 } 84 } 85 } 86 encoder := json.NewEncoder(buffer) 87 encoder.SetEscapeHTML(false) 88 encoder.SetIndent("", "\t") 89 if err := encoder.Encode(value); err != nil { 90 fmt.Fprintln(os.Stderr, err.Error()) 91 } 92 } 93 } 94 return buffer.String() 95 }