Merge pull request #180 from unistack-org/logger-wrapper
logger/unwrap: support sql and proto wrapper types
This commit was merged in pull request #180.
	This commit is contained in:
		| @@ -47,12 +47,15 @@ var ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type unwrap struct { | type unwrap struct { | ||||||
| 	val            interface{} | 	val              interface{} | ||||||
| 	s              fmt.State | 	s                fmt.State | ||||||
| 	pointers       map[uintptr]int | 	pointers         map[uintptr]int | ||||||
| 	opts           *Options | 	opts             *Options | ||||||
| 	depth          int | 	depth            int | ||||||
| 	ignoreNextType bool | 	ignoreNextType   bool | ||||||
|  | 	takeAll          bool | ||||||
|  | 	protoWrapperType bool | ||||||
|  | 	sqlWrapperType   bool | ||||||
| } | } | ||||||
|  |  | ||||||
| // Options struct | // Options struct | ||||||
| @@ -242,9 +245,23 @@ func (f *unwrap) format(v reflect.Value) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Handle pointers specially. | 	// 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) | 		f.formatPtr(v) | ||||||
| 		return | 		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. | 	// get type information unless already handled elsewhere. | ||||||
| @@ -355,8 +372,17 @@ func (f *unwrap) format(v reflect.Value) { | |||||||
| 		prevSkip := false | 		prevSkip := false | ||||||
|  |  | ||||||
| 		for i := 0; i < numFields; i++ { | 		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") | 			sv, ok := vt.Field(i).Tag.Lookup("logger") | ||||||
| 			if ok { | 			switch { | ||||||
|  | 			case ok: | ||||||
| 				switch sv { | 				switch sv { | ||||||
| 				case "omit": | 				case "omit": | ||||||
| 					prevSkip = true | 					prevSkip = true | ||||||
| @@ -364,7 +390,9 @@ func (f *unwrap) format(v reflect.Value) { | |||||||
| 				case "take": | 				case "take": | ||||||
| 					break | 					break | ||||||
| 				} | 				} | ||||||
| 			} else if f.opts.Tagged { | 			case f.takeAll: | ||||||
|  | 				break | ||||||
|  | 			case !ok && f.opts.Tagged: | ||||||
| 				prevSkip = true | 				prevSkip = true | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| @@ -383,7 +411,9 @@ func (f *unwrap) format(v reflect.Value) { | |||||||
| 				_, _ = f.s.Write([]byte(vtf.Name)) | 				_, _ = f.s.Write([]byte(vtf.Name)) | ||||||
| 				_, _ = f.s.Write(colonBytes) | 				_, _ = 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++ | 			numWritten++ | ||||||
| 		} | 		} | ||||||
| 		f.depth-- | 		f.depth-- | ||||||
| @@ -579,3 +609,31 @@ func (f *unwrap) constructOrigFormat(verb rune) (format string) { | |||||||
| 	format = buf.String() | 	format = buf.String() | ||||||
| 	return format | 	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 | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user