Add config pointers to format and dump states.
This paves the way to support individual configuration options through a separate type while still providing the simple global config and package level methods.
This commit is contained in:
parent
04998fcda3
commit
184d118062
|
@ -125,7 +125,7 @@ func catchPanic(w io.Writer, v reflect.Value) {
|
|||
//
|
||||
// It handles panics in any called methods by catching and displaying the error
|
||||
// as the formatted value.
|
||||
func handleMethods(w io.Writer, v reflect.Value) (handled bool) {
|
||||
func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
|
||||
// We need an interface to check if the type implements the error or
|
||||
// Stringer interface. However, the reflect package won't give us an
|
||||
// an interface on certain things like unexported struct fields in order
|
||||
|
@ -142,7 +142,7 @@ func handleMethods(w io.Writer, v reflect.Value) (handled bool) {
|
|||
// Stringer interface with a pointer receiver should not be mutating their
|
||||
// state inside these interface methods.
|
||||
var viface interface{}
|
||||
if !Config.DisablePointerMethods {
|
||||
if !cs.DisablePointerMethods {
|
||||
if !v.CanAddr() {
|
||||
v = unsafeReflectValue(v)
|
||||
}
|
||||
|
|
17
spew/dump.go
17
spew/dump.go
|
@ -32,16 +32,17 @@ type dumpState struct {
|
|||
pointers map[uintptr]int
|
||||
ignoreNextType bool
|
||||
ignoreNextPad bool
|
||||
cs *ConfigState
|
||||
}
|
||||
|
||||
// pad performs indentation according to the depth level and Config.Indent
|
||||
// pad performs indentation according to the depth level and cs.Indent
|
||||
// option.
|
||||
func (d *dumpState) pad() {
|
||||
if d.ignoreNextPad {
|
||||
d.ignoreNextPad = false
|
||||
return
|
||||
}
|
||||
d.w.Write(bytes.Repeat([]byte(Config.Indent), d.depth))
|
||||
d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
|
||||
}
|
||||
|
||||
// dumpPtr handles formatting of pointers by indirecting them as necessary.
|
||||
|
@ -146,9 +147,9 @@ func (d *dumpState) dump(v reflect.Value) {
|
|||
|
||||
// Call error/Stringer interfaces if they exist and the handle methods flag
|
||||
// is enabled
|
||||
if !Config.DisableMethods {
|
||||
if !d.cs.DisableMethods {
|
||||
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
||||
if handled := handleMethods(d.w, v); handled {
|
||||
if handled := handleMethods(d.cs, d.w, v); handled {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +183,7 @@ func (d *dumpState) dump(v reflect.Value) {
|
|||
case reflect.Array, reflect.Slice:
|
||||
d.w.Write(openBraceNewlineBytes)
|
||||
d.depth++
|
||||
if (Config.MaxDepth != 0) && (d.depth > Config.MaxDepth) {
|
||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||
d.pad()
|
||||
d.w.Write(maxNewlineBytes)
|
||||
} else {
|
||||
|
@ -213,7 +214,7 @@ func (d *dumpState) dump(v reflect.Value) {
|
|||
case reflect.Map:
|
||||
d.w.Write(openBraceNewlineBytes)
|
||||
d.depth++
|
||||
if (Config.MaxDepth != 0) && (d.depth > Config.MaxDepth) {
|
||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||
d.pad()
|
||||
d.w.Write(maxNewlineBytes)
|
||||
} else {
|
||||
|
@ -238,7 +239,7 @@ func (d *dumpState) dump(v reflect.Value) {
|
|||
case reflect.Struct:
|
||||
d.w.Write(openBraceNewlineBytes)
|
||||
d.depth++
|
||||
if (Config.MaxDepth != 0) && (d.depth > Config.MaxDepth) {
|
||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||
d.pad()
|
||||
d.w.Write(maxNewlineBytes)
|
||||
} else {
|
||||
|
@ -291,7 +292,7 @@ func Fdump(w io.Writer, a ...interface{}) {
|
|||
continue
|
||||
}
|
||||
|
||||
d := dumpState{w: w}
|
||||
d := dumpState{w: w, cs: &Config}
|
||||
d.pointers = make(map[uintptr]int)
|
||||
d.dump(reflect.ValueOf(arg))
|
||||
d.w.Write(newlineBytes)
|
||||
|
|
|
@ -37,6 +37,7 @@ type formatState struct {
|
|||
depth int
|
||||
pointers map[uintptr]int // Holds map of points and depth they were seen at
|
||||
fs fmt.State
|
||||
cs *ConfigState
|
||||
}
|
||||
|
||||
// buildDefaultFormat recreates the original format string without precision
|
||||
|
@ -175,9 +176,9 @@ func (f *formatState) format(v reflect.Value) {
|
|||
// Call error/Stringer interfaces if they exist and the handle methods
|
||||
// flag is enabled.
|
||||
kind := v.Kind()
|
||||
if !Config.DisableMethods {
|
||||
if !f.cs.DisableMethods {
|
||||
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
||||
if handled := handleMethods(&f.buffer, v); handled {
|
||||
if handled := handleMethods(f.cs, &f.buffer, v); handled {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +212,7 @@ func (f *formatState) format(v reflect.Value) {
|
|||
case reflect.Array, reflect.Slice:
|
||||
f.buffer.WriteRune('[')
|
||||
f.depth++
|
||||
if (Config.MaxDepth != 0) && (f.depth > Config.MaxDepth) {
|
||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||
f.buffer.Write(maxShortBytes)
|
||||
} else {
|
||||
numEntries := v.Len()
|
||||
|
@ -234,7 +235,7 @@ func (f *formatState) format(v reflect.Value) {
|
|||
case reflect.Map:
|
||||
f.buffer.Write(openMapBytes)
|
||||
f.depth++
|
||||
if (Config.MaxDepth != 0) && (f.depth > Config.MaxDepth) {
|
||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||
f.buffer.Write(maxShortBytes)
|
||||
} else {
|
||||
keys := v.MapKeys()
|
||||
|
@ -257,7 +258,7 @@ func (f *formatState) format(v reflect.Value) {
|
|||
numFields := v.NumField()
|
||||
f.buffer.WriteRune('{')
|
||||
f.depth++
|
||||
if (Config.MaxDepth != 0) && (f.depth > Config.MaxDepth) {
|
||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||
f.buffer.Write(maxShortBytes)
|
||||
} else {
|
||||
vt := v.Type()
|
||||
|
@ -331,8 +332,8 @@ Typically this function shouldn't be called directly. It is much easier to make
|
|||
use of the custom formatter by calling one of the convenience functions such as
|
||||
Printf, Println, or Printf.
|
||||
*/
|
||||
func NewFormatter(v interface{}) (f fmt.Formatter) {
|
||||
fs := &formatState{value: v}
|
||||
func NewFormatter(v interface{}) fmt.Formatter {
|
||||
fs := &formatState{value: v, cs: &Config}
|
||||
fs.pointers = make(map[uintptr]int)
|
||||
return fs
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue