Prevent formatter from panic'ing with unexported fields
This is not by any means a fix, but a real fix would require
cloning much of print.go from fmt.
diff --git a/formatter.go b/formatter.go
index a1f4a0a..aa334b9 100644
--- a/formatter.go
+++ b/formatter.go
@@ -24,7 +24,6 @@
omit bool
}
-
// Formatter makes a wrapper, f, that will format x as go source with line
// breaks and tabs. Object f responds to the "%v" formatting verb when both the
// "#" and " " (space) flags are set, for example:
@@ -38,12 +37,10 @@
return formatter{x: x}
}
-
func (fo formatter) String() string {
return fmt.Sprint(fo.x) // unwrap it
}
-
func (fo formatter) passThrough(f fmt.State, c rune) {
s := "%"
for i := 0; i < 128; i++ {
@@ -61,7 +58,6 @@
fmt.Fprintf(f, s, fo.x)
}
-
func (fo formatter) Format(f fmt.State, c rune) {
if c == 'v' && f.Flag('#') && f.Flag(' ') {
fo.format(f)
@@ -70,7 +66,6 @@
fo.passThrough(f, c)
}
-
func (fo formatter) format(w io.Writer) {
v := reflect.ValueOf(fo.x)
switch v.Kind() {
@@ -103,7 +98,11 @@
fmt.Fprintf(w, "%#v", fo.x)
} else {
writeByte(w, '&')
- fmt.Fprintf(w, "%# v", formatter{d: fo.d, x: e.Interface()})
+ if e.CanInterface() {
+ fmt.Fprintf(w, "%# v", formatter{d: fo.d, x: e.Interface()})
+ } else {
+ fmt.Fprint(w, e.String())
+ }
}
case reflect.Slice:
s := fmt.Sprintf("%#v", fo.x)
@@ -120,8 +119,12 @@
for j := 0; j < fo.d+1; j++ {
writeByte(w, '\t')
}
- inner := formatter{d: fo.d + 1, x: v.Index(i).Interface(), omit: t.Elem().Kind() != reflect.Interface}
- fmt.Fprintf(w, "%# v", inner)
+ if v.Index(i).CanInterface() {
+ inner := formatter{d: fo.d + 1, x: v.Index(i).Interface(), omit: t.Elem().Kind() != reflect.Interface}
+ fmt.Fprintf(w, "%# v", inner)
+ } else {
+ fmt.Fprint(w, v.Index(i).String())
+ }
w.Write(commaLFBytes)
}
for j := 0; j < fo.d; j++ {
@@ -169,8 +172,12 @@
for j := len(f.Name) + 1; j < max; j++ {
writeByte(w, ' ')
}
- inner := formatter{d: fo.d + 1, x: v.Field(i).Interface()}
- io.WriteString(w, fmt.Sprintf("%# v", inner))
+ if v.Field(i).CanInterface() {
+ inner := formatter{d: fo.d + 1, x: v.Field(i).Interface()}
+ fmt.Fprintf(w, "%# v", inner)
+ } else {
+ io.WriteString(w, v.Field(i).String())
+ }
w.Write(commaLFBytes)
}
}