Skip to content

Instantly share code, notes, and snippets.

@perbu
Last active December 17, 2021 13:13
Show Gist options
  • Save perbu/a2ddcf3b1e8b68c6bf4ee33b799b9cab to your computer and use it in GitHub Desktop.
Save perbu/a2ddcf3b1e8b68c6bf4ee33b799b9cab to your computer and use it in GitHub Desktop.
func stringIt(value interface{}) string {
switch v := value.(type) {
case nil:
return "<nil>"
case string:
return value.(string)
case []byte:
return string(value.([]byte))
case encoding.TextMarshaler:
return safeMarshal(value.(encoding.TextMarshaler))
case error:
return value.(error).Error()
case fmt.Stringer:
return safeString(v.(fmt.Stringer))
default: // use reflection to figure out what it is.
rvalue := reflect.ValueOf(value)
switch rvalue.Kind() {
case reflect.Array, reflect.Chan, reflect.Func, reflect.Map, reflect.Slice, reflect.Struct:
return fmt.Sprintf("[COMPOSITE TYPE: %s]", rvalue.Kind().String())
case reflect.Ptr:
if rvalue.IsNil() {
return "<nil ptr>"
}
return rvalue.String()
}
return fmt.Sprint(v) // falls through to Sprint,
}
}
func safeMarshal(tm encoding.TextMarshaler) (ret string) {
defer func() {
if panicVal := recover(); panicVal != nil {
if v := reflect.ValueOf(tm); v.Kind() == reflect.Ptr && v.IsNil() {
ret = "[ERROR]"
} else {
ret = "[PANIC RECOVERED]"
}
}
}()
retBytes, err := tm.MarshalText()
ret = string(retBytes)
if err != nil {
return "[ERROR]"
}
return ret
}
func safeString(str fmt.Stringer) (s string) {
defer func() {
if panicVal := recover(); panicVal != nil {
if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() {
s = "null"
} else {
fmt.Sprintf("PANIC:%v", panicVal)
}
}
}()
s = str.String()
return s
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment