1
2
3
4
5 package main
6
7 import (
8 "fmt"
9 "reflect"
10 "strconv"
11 )
12
13 func pprints(v any) string {
14 var pp pprinter
15 pp.val(reflect.ValueOf(v), 0)
16 return string(pp.buf)
17 }
18
19 type pprinter struct {
20 buf []byte
21 }
22
23 func (p *pprinter) indent(by int) {
24 for range by {
25 p.buf = append(p.buf, '\t')
26 }
27 }
28
29 func (p *pprinter) val(v reflect.Value, indent int) {
30 switch v.Kind() {
31 default:
32 p.buf = fmt.Appendf(p.buf, "unsupported kind %v", v.Kind())
33
34 case reflect.Bool:
35 p.buf = strconv.AppendBool(p.buf, v.Bool())
36
37 case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64:
38 p.buf = strconv.AppendInt(p.buf, v.Int(), 10)
39
40 case reflect.String:
41 p.buf = strconv.AppendQuote(p.buf, v.String())
42
43 case reflect.Pointer:
44 if v.IsNil() {
45 p.buf = append(p.buf, "nil"...)
46 } else {
47 p.buf = append(p.buf, "&"...)
48 p.val(v.Elem(), indent)
49 }
50
51 case reflect.Slice, reflect.Array:
52 p.buf = append(p.buf, "[\n"...)
53 for i := range v.Len() {
54 p.indent(indent + 1)
55 p.val(v.Index(i), indent+1)
56 p.buf = append(p.buf, ",\n"...)
57 }
58 p.indent(indent)
59 p.buf = append(p.buf, ']')
60
61 case reflect.Struct:
62 vt := v.Type()
63 p.buf = append(append(p.buf, vt.String()...), "{\n"...)
64 for f := range v.NumField() {
65 p.indent(indent + 1)
66 p.buf = append(append(p.buf, vt.Field(f).Name...), ": "...)
67 p.val(v.Field(f), indent+1)
68 p.buf = append(p.buf, ",\n"...)
69 }
70 p.indent(indent)
71 p.buf = append(p.buf, '}')
72 }
73 }
74
View as plain text