aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/serializer/serializer.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/serializer/serializer.go')
-rw-r--r--pkg/serializer/serializer.go30
1 files changed, 25 insertions, 5 deletions
diff --git a/pkg/serializer/serializer.go b/pkg/serializer/serializer.go
index 4de4dc093..05c00a3bd 100644
--- a/pkg/serializer/serializer.go
+++ b/pkg/serializer/serializer.go
@@ -5,6 +5,7 @@ package serializer
import (
"reflect"
+ "strings"
"fmt"
"io"
@@ -35,11 +36,7 @@ func (w *writer) do(v reflect.Value, sliceElem bool) {
case reflect.Ptr:
w.doPtr(v, sliceElem)
case reflect.Interface:
- if v.IsNil() {
- w.string("nil")
- } else {
- w.do(v.Elem(), false)
- }
+ w.doInterface(v)
case reflect.Slice:
w.doSlice(v)
case reflect.Struct:
@@ -81,6 +78,29 @@ func (w *writer) doPtr(v reflect.Value, sliceElem bool) {
w.do(v.Elem(), sliceElem)
}
+func (w *writer) doInterface(v reflect.Value) {
+ if v.IsNil() {
+ w.string("nil")
+ return
+ }
+ elem := v.Elem()
+ // Handling of user types that has underlying primitive types. Consider:
+ // type T int
+ // var obj interface{} = T(42)
+ // T has kind reflect.Int. But if we serialize obj as just "42", it will be turned into plain int.
+ // Detect this case and serialize obj as "T(42)".
+ if (elem.Kind() == reflect.Bool || elem.Kind() == reflect.String ||
+ elem.Type().ConvertibleTo(reflect.TypeOf(0))) &&
+ strings.Contains(elem.Type().String(), ".") {
+ w.string(elem.Type().Name())
+ w.byte('(')
+ w.do(elem, false)
+ w.byte(')')
+ return
+ }
+ w.do(elem, false)
+}
+
func (w *writer) doSlice(v reflect.Value) {
if v.IsNil() || v.Len() == 0 {
w.string("nil")