gogreen/strings.go

103 lines
2.0 KiB
Go
Raw Normal View History

2014-09-03 14:03:30 +00:00
package godo
import (
"bytes"
"fmt"
2016-12-21 00:00:17 +00:00
"io"
"reflect"
2018-09-27 17:33:57 +00:00
"strings"
2014-09-03 14:03:30 +00:00
)
var timestampType = reflect.TypeOf(Timestamp{})
2018-09-27 17:33:57 +00:00
type ResourceWithURN interface {
URN() string
}
// ToURN converts the resource type and ID to a valid DO API URN.
func ToURN(resourceType string, id interface{}) string {
return fmt.Sprintf("%s:%s:%v", "do", strings.ToLower(resourceType), id)
}
2015-09-18 13:10:59 +00:00
// Stringify attempts to create a string representation of DigitalOcean types
2014-09-03 14:03:30 +00:00
func Stringify(message interface{}) string {
var buf bytes.Buffer
v := reflect.ValueOf(message)
stringifyValue(&buf, v)
return buf.String()
}
// stringifyValue was graciously cargoculted from the goprotubuf library
2016-12-21 00:00:17 +00:00
func stringifyValue(w io.Writer, val reflect.Value) {
2014-09-03 14:03:30 +00:00
if val.Kind() == reflect.Ptr && val.IsNil() {
_, _ = w.Write([]byte("<nil>"))
2014-09-03 14:03:30 +00:00
return
}
v := reflect.Indirect(val)
switch v.Kind() {
case reflect.String:
fmt.Fprintf(w, `"%s"`, v)
case reflect.Slice:
2016-12-21 00:00:17 +00:00
stringifySlice(w, v)
2014-09-03 14:03:30 +00:00
return
case reflect.Struct:
2016-12-21 00:00:17 +00:00
stringifyStruct(w, v)
default:
if v.CanInterface() {
fmt.Fprint(w, v.Interface())
2014-09-03 14:03:30 +00:00
}
2016-12-21 00:00:17 +00:00
}
}
2014-09-03 14:03:30 +00:00
2016-12-21 00:00:17 +00:00
func stringifySlice(w io.Writer, v reflect.Value) {
_, _ = w.Write([]byte{'['})
for i := 0; i < v.Len(); i++ {
if i > 0 {
_, _ = w.Write([]byte{' '})
2014-09-03 14:03:30 +00:00
}
2016-12-21 00:00:17 +00:00
stringifyValue(w, v.Index(i))
}
_, _ = w.Write([]byte{']'})
}
func stringifyStruct(w io.Writer, v reflect.Value) {
if v.Type().Name() != "" {
_, _ = w.Write([]byte(v.Type().String()))
}
// special handling of Timestamp values
if v.Type() == timestampType {
fmt.Fprintf(w, "{%s}", v.Interface())
return
}
_, _ = w.Write([]byte{'{'})
var sep bool
for i := 0; i < v.NumField(); i++ {
fv := v.Field(i)
if fv.Kind() == reflect.Ptr && fv.IsNil() {
continue
}
if fv.Kind() == reflect.Slice && fv.IsNil() {
continue
2014-09-03 14:03:30 +00:00
}
2016-12-21 00:00:17 +00:00
if sep {
_, _ = w.Write([]byte(", "))
} else {
sep = true
2014-09-03 14:03:30 +00:00
}
2016-12-21 00:00:17 +00:00
_, _ = w.Write([]byte(v.Type().Field(i).Name))
_, _ = w.Write([]byte{':'})
stringifyValue(w, fv)
2014-09-03 14:03:30 +00:00
}
2016-12-21 00:00:17 +00:00
_, _ = w.Write([]byte{'}'})
2014-09-03 14:03:30 +00:00
}