Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
84024f7713 | |||
5a554f9f0c | |||
9c33cbc8e2 | |||
848fe1c0d4 | |||
6cbf23fec5 |
@@ -47,12 +47,15 @@ var (
|
||||
)
|
||||
|
||||
type unwrap struct {
|
||||
val interface{}
|
||||
s fmt.State
|
||||
pointers map[uintptr]int
|
||||
opts *Options
|
||||
depth int
|
||||
ignoreNextType bool
|
||||
val interface{}
|
||||
s fmt.State
|
||||
pointers map[uintptr]int
|
||||
opts *Options
|
||||
depth int
|
||||
ignoreNextType bool
|
||||
takeAll bool
|
||||
protoWrapperType bool
|
||||
sqlWrapperType bool
|
||||
}
|
||||
|
||||
// Options struct
|
||||
@@ -242,9 +245,23 @@ func (f *unwrap) format(v reflect.Value) {
|
||||
}
|
||||
|
||||
// Handle pointers specially.
|
||||
if kind == reflect.Ptr {
|
||||
switch kind {
|
||||
case reflect.Ptr:
|
||||
if !v.IsZero() {
|
||||
if strings.HasPrefix(reflect.Indirect(v).Type().String(), "wrapperspb.") {
|
||||
f.protoWrapperType = true
|
||||
} else if strings.HasPrefix(reflect.Indirect(v).Type().String(), "sql.Null") {
|
||||
f.sqlWrapperType = true
|
||||
}
|
||||
}
|
||||
f.formatPtr(v)
|
||||
return
|
||||
case reflect.Struct:
|
||||
if !v.IsZero() {
|
||||
if strings.HasPrefix(reflect.Indirect(v).Type().String(), "sql.Null") {
|
||||
f.sqlWrapperType = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get type information unless already handled elsewhere.
|
||||
@@ -353,9 +370,19 @@ func (f *unwrap) format(v reflect.Value) {
|
||||
f.depth++
|
||||
vt := v.Type()
|
||||
prevSkip := false
|
||||
|
||||
for i := 0; i < numFields; i++ {
|
||||
f.takeAll = false
|
||||
if f.protoWrapperType && !vt.Field(i).IsExported() {
|
||||
prevSkip = true
|
||||
continue
|
||||
} else if f.sqlWrapperType && vt.Field(i).Name == "Valid" {
|
||||
prevSkip = true
|
||||
continue
|
||||
}
|
||||
sv, ok := vt.Field(i).Tag.Lookup("logger")
|
||||
if ok {
|
||||
switch {
|
||||
case ok:
|
||||
switch sv {
|
||||
case "omit":
|
||||
prevSkip = true
|
||||
@@ -363,23 +390,30 @@ func (f *unwrap) format(v reflect.Value) {
|
||||
case "take":
|
||||
break
|
||||
}
|
||||
} else if f.opts.Tagged {
|
||||
case f.takeAll:
|
||||
break
|
||||
case !ok && f.opts.Tagged:
|
||||
prevSkip = true
|
||||
continue
|
||||
}
|
||||
if i > 0 && !prevSkip {
|
||||
_, _ = f.s.Write(commaBytes)
|
||||
_, _ = f.s.Write(spaceBytes)
|
||||
}
|
||||
|
||||
if prevSkip {
|
||||
prevSkip = false
|
||||
}
|
||||
|
||||
if numWritten > 0 {
|
||||
_, _ = f.s.Write(commaBytes)
|
||||
_, _ = f.s.Write(spaceBytes)
|
||||
}
|
||||
|
||||
vtf := vt.Field(i)
|
||||
if f.s.Flag('+') || f.s.Flag('#') {
|
||||
_, _ = f.s.Write([]byte(vtf.Name))
|
||||
_, _ = f.s.Write(colonBytes)
|
||||
}
|
||||
f.format(f.unpackValue(v.Field(i)))
|
||||
unpackValue := f.unpackValue(v.Field(i))
|
||||
f.takeAll = f.checkTakeAll(unpackValue)
|
||||
f.format(unpackValue)
|
||||
numWritten++
|
||||
}
|
||||
f.depth--
|
||||
@@ -575,3 +609,31 @@ func (f *unwrap) constructOrigFormat(verb rune) (format string) {
|
||||
format = buf.String()
|
||||
return format
|
||||
}
|
||||
|
||||
func (f *unwrap) checkTakeAll(v reflect.Value) bool {
|
||||
takeAll := true
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.Struct:
|
||||
break
|
||||
case reflect.Ptr:
|
||||
v = v.Elem()
|
||||
if v.Kind() != reflect.Struct {
|
||||
return true
|
||||
}
|
||||
default:
|
||||
return true
|
||||
}
|
||||
|
||||
vt := v.Type()
|
||||
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
sv, ok := vt.Field(i).Tag.Lookup("logger")
|
||||
if ok && sv == "take" {
|
||||
return false
|
||||
}
|
||||
takeAll = f.checkTakeAll(v.Field(i))
|
||||
}
|
||||
|
||||
return takeAll
|
||||
}
|
||||
|
@@ -86,12 +86,12 @@ func TestTaggedNested(t *testing.T) {
|
||||
unk string
|
||||
}
|
||||
type str struct {
|
||||
val *val `logger:"take"`
|
||||
key string `logger:"omit"`
|
||||
val *val `logger:"take"`
|
||||
}
|
||||
|
||||
var iface interface{}
|
||||
v := &str{key: "omit", val: &val{key: "test", val: "omit", unk: "unk"}}
|
||||
v := &str{val: &val{key: "test", unk: "unk"}}
|
||||
iface = v
|
||||
buf := fmt.Sprintf("%#v", Unwrap(iface, Tagged(true)))
|
||||
if strings.Compare(buf, `&unwrap.str{val:(*unwrap.val){key:"test"}}`) != 0 {
|
||||
|
Reference in New Issue
Block a user