mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-21 07:56:26 +01:00
5b7e8d1309
* lib/backup/s3remote: update AWS SDK to v2 * Update lib/backup/s3remote/s3.go Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com> * lib/backup/s3remote: refactor error handling Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
132 lines
2.8 KiB
Go
132 lines
2.8 KiB
Go
package awsutil
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
// Prettify returns the string representation of a value.
|
|
func Prettify(i interface{}) string {
|
|
var buf bytes.Buffer
|
|
prettify(reflect.ValueOf(i), 0, &buf)
|
|
return buf.String()
|
|
}
|
|
|
|
// prettify will recursively walk value v to build a textual
|
|
// representation of the value.
|
|
func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
|
|
isPtr := false
|
|
for v.Kind() == reflect.Ptr {
|
|
isPtr = true
|
|
v = v.Elem()
|
|
}
|
|
|
|
switch v.Kind() {
|
|
case reflect.Struct:
|
|
strtype := v.Type().String()
|
|
if strtype == "time.Time" {
|
|
fmt.Fprintf(buf, "%s", v.Interface())
|
|
break
|
|
} else if strings.HasPrefix(strtype, "io.") {
|
|
buf.WriteString("<buffer>")
|
|
break
|
|
}
|
|
|
|
if isPtr {
|
|
buf.WriteRune('&')
|
|
}
|
|
buf.WriteString("{\n")
|
|
|
|
names := []string{}
|
|
for i := 0; i < v.Type().NumField(); i++ {
|
|
name := v.Type().Field(i).Name
|
|
f := v.Field(i)
|
|
if name[0:1] == strings.ToLower(name[0:1]) {
|
|
continue // ignore unexported fields
|
|
}
|
|
if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() {
|
|
continue // ignore unset fields
|
|
}
|
|
names = append(names, name)
|
|
}
|
|
|
|
for i, n := range names {
|
|
val := v.FieldByName(n)
|
|
buf.WriteString(strings.Repeat(" ", indent+2))
|
|
buf.WriteString(n + ": ")
|
|
prettify(val, indent+2, buf)
|
|
|
|
if i < len(names)-1 {
|
|
buf.WriteString(",\n")
|
|
}
|
|
}
|
|
|
|
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
|
case reflect.Slice:
|
|
strtype := v.Type().String()
|
|
if strtype == "[]uint8" {
|
|
fmt.Fprintf(buf, "<binary> len %d", v.Len())
|
|
break
|
|
}
|
|
|
|
nl, id, id2 := "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
|
|
if isPtr {
|
|
buf.WriteRune('&')
|
|
}
|
|
buf.WriteString("[" + nl)
|
|
for i := 0; i < v.Len(); i++ {
|
|
buf.WriteString(id2)
|
|
prettify(v.Index(i), indent+2, buf)
|
|
|
|
if i < v.Len()-1 {
|
|
buf.WriteString("," + nl)
|
|
}
|
|
}
|
|
|
|
buf.WriteString(nl + id + "]")
|
|
case reflect.Map:
|
|
if isPtr {
|
|
buf.WriteRune('&')
|
|
}
|
|
buf.WriteString("{\n")
|
|
|
|
for i, k := range v.MapKeys() {
|
|
buf.WriteString(strings.Repeat(" ", indent+2))
|
|
buf.WriteString(k.String() + ": ")
|
|
prettify(v.MapIndex(k), indent+2, buf)
|
|
|
|
if i < v.Len()-1 {
|
|
buf.WriteString(",\n")
|
|
}
|
|
}
|
|
|
|
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
|
default:
|
|
if !v.IsValid() {
|
|
fmt.Fprint(buf, "<invalid value>")
|
|
return
|
|
}
|
|
|
|
for v.Kind() == reflect.Interface && !v.IsNil() {
|
|
v = v.Elem()
|
|
}
|
|
|
|
if v.Kind() == reflect.Ptr || v.Kind() == reflect.Struct || v.Kind() == reflect.Map || v.Kind() == reflect.Slice {
|
|
prettify(v, indent, buf)
|
|
return
|
|
}
|
|
|
|
format := "%v"
|
|
switch v.Interface().(type) {
|
|
case string:
|
|
format = "%q"
|
|
case io.ReadSeeker, io.Reader:
|
|
format = "buffer(%p)"
|
|
}
|
|
fmt.Fprintf(buf, format, v.Interface())
|
|
}
|
|
}
|