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
|
// It handles panics in any called methods by catching and displaying the error
|
||||||
// as the formatted value.
|
// 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
|
// We need an interface to check if the type implements the error or
|
||||||
// Stringer interface. However, the reflect package won't give us an
|
// Stringer interface. However, the reflect package won't give us an
|
||||||
// an interface on certain things like unexported struct fields in order
|
// 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
|
// Stringer interface with a pointer receiver should not be mutating their
|
||||||
// state inside these interface methods.
|
// state inside these interface methods.
|
||||||
var viface interface{}
|
var viface interface{}
|
||||||
if !Config.DisablePointerMethods {
|
if !cs.DisablePointerMethods {
|
||||||
if !v.CanAddr() {
|
if !v.CanAddr() {
|
||||||
v = unsafeReflectValue(v)
|
v = unsafeReflectValue(v)
|
||||||
}
|
}
|
||||||
|
|
17
spew/dump.go
17
spew/dump.go
|
@ -32,16 +32,17 @@ type dumpState struct {
|
||||||
pointers map[uintptr]int
|
pointers map[uintptr]int
|
||||||
ignoreNextType bool
|
ignoreNextType bool
|
||||||
ignoreNextPad 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.
|
// option.
|
||||||
func (d *dumpState) pad() {
|
func (d *dumpState) pad() {
|
||||||
if d.ignoreNextPad {
|
if d.ignoreNextPad {
|
||||||
d.ignoreNextPad = false
|
d.ignoreNextPad = false
|
||||||
return
|
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.
|
// 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
|
// Call error/Stringer interfaces if they exist and the handle methods flag
|
||||||
// is enabled
|
// is enabled
|
||||||
if !Config.DisableMethods {
|
if !d.cs.DisableMethods {
|
||||||
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
||||||
if handled := handleMethods(d.w, v); handled {
|
if handled := handleMethods(d.cs, d.w, v); handled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,7 +183,7 @@ func (d *dumpState) dump(v reflect.Value) {
|
||||||
case reflect.Array, reflect.Slice:
|
case reflect.Array, reflect.Slice:
|
||||||
d.w.Write(openBraceNewlineBytes)
|
d.w.Write(openBraceNewlineBytes)
|
||||||
d.depth++
|
d.depth++
|
||||||
if (Config.MaxDepth != 0) && (d.depth > Config.MaxDepth) {
|
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||||
d.pad()
|
d.pad()
|
||||||
d.w.Write(maxNewlineBytes)
|
d.w.Write(maxNewlineBytes)
|
||||||
} else {
|
} else {
|
||||||
|
@ -213,7 +214,7 @@ func (d *dumpState) dump(v reflect.Value) {
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
d.w.Write(openBraceNewlineBytes)
|
d.w.Write(openBraceNewlineBytes)
|
||||||
d.depth++
|
d.depth++
|
||||||
if (Config.MaxDepth != 0) && (d.depth > Config.MaxDepth) {
|
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||||
d.pad()
|
d.pad()
|
||||||
d.w.Write(maxNewlineBytes)
|
d.w.Write(maxNewlineBytes)
|
||||||
} else {
|
} else {
|
||||||
|
@ -238,7 +239,7 @@ func (d *dumpState) dump(v reflect.Value) {
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
d.w.Write(openBraceNewlineBytes)
|
d.w.Write(openBraceNewlineBytes)
|
||||||
d.depth++
|
d.depth++
|
||||||
if (Config.MaxDepth != 0) && (d.depth > Config.MaxDepth) {
|
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||||
d.pad()
|
d.pad()
|
||||||
d.w.Write(maxNewlineBytes)
|
d.w.Write(maxNewlineBytes)
|
||||||
} else {
|
} else {
|
||||||
|
@ -291,7 +292,7 @@ func Fdump(w io.Writer, a ...interface{}) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
d := dumpState{w: w}
|
d := dumpState{w: w, cs: &Config}
|
||||||
d.pointers = make(map[uintptr]int)
|
d.pointers = make(map[uintptr]int)
|
||||||
d.dump(reflect.ValueOf(arg))
|
d.dump(reflect.ValueOf(arg))
|
||||||
d.w.Write(newlineBytes)
|
d.w.Write(newlineBytes)
|
||||||
|
|
|
@ -37,6 +37,7 @@ type formatState struct {
|
||||||
depth int
|
depth int
|
||||||
pointers map[uintptr]int // Holds map of points and depth they were seen at
|
pointers map[uintptr]int // Holds map of points and depth they were seen at
|
||||||
fs fmt.State
|
fs fmt.State
|
||||||
|
cs *ConfigState
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildDefaultFormat recreates the original format string without precision
|
// 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
|
// Call error/Stringer interfaces if they exist and the handle methods
|
||||||
// flag is enabled.
|
// flag is enabled.
|
||||||
kind := v.Kind()
|
kind := v.Kind()
|
||||||
if !Config.DisableMethods {
|
if !f.cs.DisableMethods {
|
||||||
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
||||||
if handled := handleMethods(&f.buffer, v); handled {
|
if handled := handleMethods(f.cs, &f.buffer, v); handled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +212,7 @@ func (f *formatState) format(v reflect.Value) {
|
||||||
case reflect.Array, reflect.Slice:
|
case reflect.Array, reflect.Slice:
|
||||||
f.buffer.WriteRune('[')
|
f.buffer.WriteRune('[')
|
||||||
f.depth++
|
f.depth++
|
||||||
if (Config.MaxDepth != 0) && (f.depth > Config.MaxDepth) {
|
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||||
f.buffer.Write(maxShortBytes)
|
f.buffer.Write(maxShortBytes)
|
||||||
} else {
|
} else {
|
||||||
numEntries := v.Len()
|
numEntries := v.Len()
|
||||||
|
@ -234,7 +235,7 @@ func (f *formatState) format(v reflect.Value) {
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
f.buffer.Write(openMapBytes)
|
f.buffer.Write(openMapBytes)
|
||||||
f.depth++
|
f.depth++
|
||||||
if (Config.MaxDepth != 0) && (f.depth > Config.MaxDepth) {
|
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||||
f.buffer.Write(maxShortBytes)
|
f.buffer.Write(maxShortBytes)
|
||||||
} else {
|
} else {
|
||||||
keys := v.MapKeys()
|
keys := v.MapKeys()
|
||||||
|
@ -257,7 +258,7 @@ func (f *formatState) format(v reflect.Value) {
|
||||||
numFields := v.NumField()
|
numFields := v.NumField()
|
||||||
f.buffer.WriteRune('{')
|
f.buffer.WriteRune('{')
|
||||||
f.depth++
|
f.depth++
|
||||||
if (Config.MaxDepth != 0) && (f.depth > Config.MaxDepth) {
|
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||||
f.buffer.Write(maxShortBytes)
|
f.buffer.Write(maxShortBytes)
|
||||||
} else {
|
} else {
|
||||||
vt := v.Type()
|
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
|
use of the custom formatter by calling one of the convenience functions such as
|
||||||
Printf, Println, or Printf.
|
Printf, Println, or Printf.
|
||||||
*/
|
*/
|
||||||
func NewFormatter(v interface{}) (f fmt.Formatter) {
|
func NewFormatter(v interface{}) fmt.Formatter {
|
||||||
fs := &formatState{value: v}
|
fs := &formatState{value: v, cs: &Config}
|
||||||
fs.pointers = make(map[uintptr]int)
|
fs.pointers = make(map[uintptr]int)
|
||||||
return fs
|
return fs
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue