| // Copyright 2025 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package main |
| |
| import ( |
| "fmt" |
| "reflect" |
| "strconv" |
| ) |
| |
| func pprints(v any) string { |
| var pp pprinter |
| pp.val(reflect.ValueOf(v), 0) |
| return string(pp.buf) |
| } |
| |
| type pprinter struct { |
| buf []byte |
| } |
| |
| func (p *pprinter) indent(by int) { |
| for range by { |
| p.buf = append(p.buf, '\t') |
| } |
| } |
| |
| func (p *pprinter) val(v reflect.Value, indent int) { |
| switch v.Kind() { |
| default: |
| p.buf = fmt.Appendf(p.buf, "unsupported kind %v", v.Kind()) |
| |
| case reflect.Bool: |
| p.buf = strconv.AppendBool(p.buf, v.Bool()) |
| |
| case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64: |
| p.buf = strconv.AppendInt(p.buf, v.Int(), 10) |
| |
| case reflect.String: |
| p.buf = strconv.AppendQuote(p.buf, v.String()) |
| |
| case reflect.Pointer: |
| if v.IsNil() { |
| p.buf = append(p.buf, "nil"...) |
| } else { |
| p.buf = append(p.buf, "&"...) |
| p.val(v.Elem(), indent) |
| } |
| |
| case reflect.Slice, reflect.Array: |
| p.buf = append(p.buf, "[\n"...) |
| for i := range v.Len() { |
| p.indent(indent + 1) |
| p.val(v.Index(i), indent+1) |
| p.buf = append(p.buf, ",\n"...) |
| } |
| p.indent(indent) |
| p.buf = append(p.buf, ']') |
| |
| case reflect.Struct: |
| vt := v.Type() |
| p.buf = append(append(p.buf, vt.String()...), "{\n"...) |
| for f := range v.NumField() { |
| p.indent(indent + 1) |
| p.buf = append(append(p.buf, vt.Field(f).Name...), ": "...) |
| p.val(v.Field(f), indent+1) |
| p.buf = append(p.buf, ",\n"...) |
| } |
| p.indent(indent) |
| p.buf = append(p.buf, '}') |
| } |
| } |