Skip to content

Commit b0a1d0a

Browse files
committed
encoder func return error
1 parent 3b438a0 commit b0a1d0a

File tree

4 files changed

+105
-67
lines changed

4 files changed

+105
-67
lines changed

encoding/encoder.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"sync"
1010
)
1111

12-
type encoderFunc func(v reflect.Value) interface{}
12+
type encoderFunc func(v reflect.Value) (interface{}, error)
1313

1414
// Encode returns the encoded value of v.
1515
//
@@ -30,10 +30,10 @@ func Encode(v interface{}) (ev interface{}, err error) {
3030
}
3131
}()
3232

33-
return encode(reflect.ValueOf(v)), nil
33+
return encode(reflect.ValueOf(v))
3434
}
3535

36-
func encode(v reflect.Value) interface{} {
36+
func encode(v reflect.Value) (interface{}, error) {
3737
return valueEncoder(v)(v)
3838
}
3939

@@ -65,7 +65,7 @@ func typeEncoder(t reflect.Type) encoderFunc {
6565
encoderCache.Lock()
6666
var wg sync.WaitGroup
6767
wg.Add(1)
68-
encoderCache.m[t] = func(v reflect.Value) interface{} {
68+
encoderCache.m[t] = func(v reflect.Value) (interface{}, error) {
6969
wg.Wait()
7070
return f(v)
7171
}

encoding/encoder_test.go

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package encoding
22

33
import (
4+
"errors"
45
"image"
56
"reflect"
67
"testing"
@@ -436,8 +437,8 @@ func TestEncodeCustomTypeEncodingValue(t *testing.T) {
436437
}
437438

438439
SetTypeEncoding(reflect.TypeOf(innerType{}),
439-
func(v interface{}) interface{} {
440-
return map[string]interface{}{"someval": v.(innerType).Val}
440+
func(v interface{}) (interface{}, error) {
441+
return map[string]interface{}{"someval": v.(innerType).Val}, nil
441442
}, nil)
442443

443444
out, err := Encode(outer)
@@ -464,8 +465,8 @@ func TestEncodeCustomTypeEncodingPointer(t *testing.T) {
464465
}
465466

466467
SetTypeEncoding(reflect.TypeOf((*innerType)(nil)),
467-
func(v interface{}) interface{} {
468-
return map[string]interface{}{"someval": v.(*innerType).Val}
468+
func(v interface{}) (interface{}, error) {
469+
return map[string]interface{}{"someval": v.(*innerType).Val}, nil
469470
}, nil)
470471

471472
out, err := Encode(outer)
@@ -488,8 +489,8 @@ func TestEncodeCustomRootTypeEncodingValue(t *testing.T) {
488489
}
489490

490491
SetTypeEncoding(reflect.TypeOf(cType{}),
491-
func(v interface{}) interface{} {
492-
return map[string]interface{}{"someval": v.(cType).Val}
492+
func(v interface{}) (interface{}, error) {
493+
return map[string]interface{}{"someval": v.(cType).Val}, nil
493494
}, nil)
494495

495496
out, err := Encode(in)
@@ -512,8 +513,8 @@ func TestEncodeCustomRootTypeEncodingPointer(t *testing.T) {
512513
}
513514

514515
SetTypeEncoding(reflect.TypeOf((*cType)(nil)),
515-
func(v interface{}) interface{} {
516-
return map[string]interface{}{"someval": v.(*cType).Val}
516+
func(v interface{}) (interface{}, error) {
517+
return map[string]interface{}{"someval": v.(*cType).Val}, nil
517518
}, nil)
518519

519520
out, err := Encode(&in)
@@ -524,3 +525,25 @@ func TestEncodeCustomRootTypeEncodingPointer(t *testing.T) {
524525
t.Errorf("got %q, want %q", out, want)
525526
}
526527
}
528+
529+
func TestEncodeCustomRootTypeEncodingError(t *testing.T) {
530+
type cType struct {
531+
Val int
532+
}
533+
in := cType{Val: 5}
534+
535+
cerr := errors.New("encode error")
536+
537+
SetTypeEncoding(reflect.TypeOf((*cType)(nil)),
538+
func(v interface{}) (interface{}, error) {
539+
return nil, cerr
540+
}, nil)
541+
542+
_, err := Encode(&in)
543+
if err == nil {
544+
t.Errorf("got nil error, expected %v", cerr)
545+
}
546+
if err != cerr {
547+
t.Errorf("got %q, want %q", err, cerr)
548+
}
549+
}

encoding/encoder_types.go

Lines changed: 68 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -60,101 +60,104 @@ func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
6060
}
6161
}
6262

63-
func invalidValueEncoder(v reflect.Value) interface{} {
64-
return nil
63+
func invalidValueEncoder(v reflect.Value) (interface{}, error) {
64+
return nil, nil
6565
}
6666

67-
func doNothingEncoder(v reflect.Value) interface{} {
68-
return v.Interface()
67+
func doNothingEncoder(v reflect.Value) (interface{}, error) {
68+
return v.Interface(), nil
6969
}
7070

71-
func marshalerEncoder(v reflect.Value) interface{} {
71+
func marshalerEncoder(v reflect.Value) (interface{}, error) {
7272
if v.Kind() == reflect.Ptr && v.IsNil() {
73-
return nil
73+
return nil, nil
7474
}
7575
m := v.Interface().(Marshaler)
7676
ev, err := m.MarshalRQL()
7777
if err != nil {
78-
panic(&MarshalerError{v.Type(), err})
78+
return nil, &MarshalerError{v.Type(), err}
7979
}
8080

81-
return ev
81+
return ev, nil
8282
}
8383

84-
func addrMarshalerEncoder(v reflect.Value) interface{} {
84+
func addrMarshalerEncoder(v reflect.Value) (interface{}, error) {
8585
va := v.Addr()
8686
if va.IsNil() {
87-
return nil
87+
return nil, nil
8888
}
8989
m := va.Interface().(Marshaler)
9090
ev, err := m.MarshalRQL()
9191
if err != nil {
92-
panic(&MarshalerError{v.Type(), err})
92+
return nil, &MarshalerError{v.Type(), err}
9393
}
9494

95-
return ev
95+
return ev, nil
9696
}
9797

98-
func boolEncoder(v reflect.Value) interface{} {
98+
func boolEncoder(v reflect.Value) (interface{}, error) {
9999
if v.Bool() {
100-
return true
100+
return true, nil
101101
} else {
102-
return false
102+
return false, nil
103103
}
104104
}
105105

106-
func intEncoder(v reflect.Value) interface{} {
107-
return v.Int()
106+
func intEncoder(v reflect.Value) (interface{}, error) {
107+
return v.Int(), nil
108108
}
109109

110-
func uintEncoder(v reflect.Value) interface{} {
111-
return v.Uint()
110+
func uintEncoder(v reflect.Value) (interface{}, error) {
111+
return v.Uint(), nil
112112
}
113113

114-
func floatEncoder(v reflect.Value) interface{} {
115-
return v.Float()
114+
func floatEncoder(v reflect.Value) (interface{}, error) {
115+
return v.Float(), nil
116116
}
117117

118-
func stringEncoder(v reflect.Value) interface{} {
119-
return v.String()
118+
func stringEncoder(v reflect.Value) (interface{}, error) {
119+
return v.String(), nil
120120
}
121121

122-
func interfaceEncoder(v reflect.Value) interface{} {
122+
func interfaceEncoder(v reflect.Value) (interface{}, error) {
123123
if v.IsNil() {
124-
return nil
124+
return nil, nil
125125
}
126126
return encode(v.Elem())
127127
}
128128

129-
func funcEncoder(v reflect.Value) interface{} {
129+
func funcEncoder(v reflect.Value) (interface{}, error) {
130130
if v.IsNil() {
131-
return nil
131+
return nil, nil
132132
}
133-
return v.Interface()
133+
return v.Interface(), nil
134134
}
135135

136-
func asStringEncoder(v reflect.Value) interface{} {
137-
return fmt.Sprintf("%v", v.Interface())
136+
func asStringEncoder(v reflect.Value) (interface{}, error) {
137+
return fmt.Sprintf("%v", v.Interface()), nil
138138
}
139139

140-
func unsupportedTypeEncoder(v reflect.Value) interface{} {
141-
panic(&UnsupportedTypeError{v.Type()})
140+
func unsupportedTypeEncoder(v reflect.Value) (interface{}, error) {
141+
return nil, &UnsupportedTypeError{v.Type()}
142142
}
143143

144144
type structEncoder struct {
145145
fields []field
146146
fieldEncs []encoderFunc
147147
}
148148

149-
func (se *structEncoder) encode(v reflect.Value) interface{} {
149+
func (se *structEncoder) encode(v reflect.Value) (interface{}, error) {
150150
m := make(map[string]interface{})
151151
for i, f := range se.fields {
152152
fv := fieldByIndex(v, f.index)
153153
if !fv.IsValid() || f.omitEmpty && se.isEmptyValue(fv) {
154154
continue
155155
}
156156

157-
encField := se.fieldEncs[i](fv)
157+
encField, err := se.fieldEncs[i](fv)
158+
if err != nil {
159+
return nil, err
160+
}
158161

159162
// If this field is a referenced field then attempt to extract the value.
160163
if f.reference {
@@ -179,7 +182,7 @@ func (se *structEncoder) encode(v reflect.Value) interface{} {
179182
m[f.name] = encField
180183
}
181184

182-
return m
185+
return m, nil
183186
}
184187

185188
func getReferenceField(f field, v reflect.Value, encField interface{}) interface{} {
@@ -240,18 +243,26 @@ type mapEncoder struct {
240243
keyEnc, elemEnc encoderFunc
241244
}
242245

243-
func (me *mapEncoder) encode(v reflect.Value) interface{} {
246+
func (me *mapEncoder) encode(v reflect.Value) (interface{}, error) {
244247
if v.IsNil() {
245-
return nil
248+
return nil, nil
246249
}
247250

248251
m := make(map[string]interface{})
249252

250253
for _, k := range v.MapKeys() {
251-
m[me.keyEnc(k).(string)] = me.elemEnc(v.MapIndex(k))
254+
encV, err := me.elemEnc(v.MapIndex(k))
255+
if err != nil {
256+
return nil, err
257+
}
258+
encK, err := me.keyEnc(k)
259+
if err != nil {
260+
return nil, err
261+
}
262+
m[encK.(string)] = encV
252263
}
253264

254-
return m
265+
return m, nil
255266
}
256267

257268
func newMapEncoder(t reflect.Type) encoderFunc {
@@ -282,9 +293,9 @@ type sliceEncoder struct {
282293
arrayEnc encoderFunc
283294
}
284295

285-
func (se *sliceEncoder) encode(v reflect.Value) interface{} {
296+
func (se *sliceEncoder) encode(v reflect.Value) (interface{}, error) {
286297
if v.IsNil() {
287-
return []interface{}(nil)
298+
return []interface{}(nil), nil
288299
}
289300
return se.arrayEnc(v)
290301
}
@@ -302,15 +313,19 @@ type arrayEncoder struct {
302313
elemEnc encoderFunc
303314
}
304315

305-
func (ae *arrayEncoder) encode(v reflect.Value) interface{} {
316+
func (ae *arrayEncoder) encode(v reflect.Value) (interface{}, error) {
306317
n := v.Len()
307318

308319
a := make([]interface{}, n)
309320
for i := 0; i < n; i++ {
310-
a[i] = ae.elemEnc(v.Index(i))
321+
var err error
322+
a[i], err = ae.elemEnc(v.Index(i))
323+
if err != nil {
324+
return nil, err
325+
}
311326
}
312327

313-
return a
328+
return a, nil
314329
}
315330

316331
func newArrayEncoder(t reflect.Type) encoderFunc {
@@ -325,9 +340,9 @@ type ptrEncoder struct {
325340
elemEnc encoderFunc
326341
}
327342

328-
func (pe *ptrEncoder) encode(v reflect.Value) interface{} {
343+
func (pe *ptrEncoder) encode(v reflect.Value) (interface{}, error) {
329344
if v.IsNil() {
330-
return nil
345+
return nil, nil
331346
}
332347
return pe.elemEnc(v.Elem())
333348
}
@@ -341,7 +356,7 @@ type condAddrEncoder struct {
341356
canAddrEnc, elseEnc encoderFunc
342357
}
343358

344-
func (ce *condAddrEncoder) encode(v reflect.Value) interface{} {
359+
func (ce *condAddrEncoder) encode(v reflect.Value) (interface{}, error) {
345360
if v.CanAddr() {
346361
return ce.canAddrEnc(v)
347362
} else {
@@ -359,7 +374,7 @@ func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
359374
// Pseudo-type encoders
360375

361376
// Encode a time.Time value to the TIME RQL type
362-
func timePseudoTypeEncoder(v reflect.Value) interface{} {
377+
func timePseudoTypeEncoder(v reflect.Value) (interface{}, error) {
363378
t := v.Interface().(time.Time)
364379

365380
timeVal := float64(t.UnixNano()) / float64(time.Second)
@@ -374,11 +389,11 @@ func timePseudoTypeEncoder(v reflect.Value) interface{} {
374389
"$reql_type$": "TIME",
375390
"epoch_time": timeVal,
376391
"timezone": t.Format("-07:00"),
377-
}
392+
}, nil
378393
}
379394

380395
// Encode a byte slice to the BINARY RQL type
381-
func encodeByteSlice(v reflect.Value) interface{} {
396+
func encodeByteSlice(v reflect.Value) (interface{}, error) {
382397
var b []byte
383398
if !v.IsNil() {
384399
b = v.Bytes()
@@ -390,11 +405,11 @@ func encodeByteSlice(v reflect.Value) interface{} {
390405
return map[string]interface{}{
391406
"$reql_type$": "BINARY",
392407
"data": string(dst),
393-
}
408+
}, nil
394409
}
395410

396411
// Encode a byte array to the BINARY RQL type
397-
func encodeByteArray(v reflect.Value) interface{} {
412+
func encodeByteArray(v reflect.Value) (interface{}, error) {
398413
b := make([]byte, v.Len())
399414
for i := 0; i < v.Len(); i++ {
400415
b[i] = v.Index(i).Interface().(byte)
@@ -406,5 +421,5 @@ func encodeByteArray(v reflect.Value) interface{} {
406421
return map[string]interface{}{
407422
"$reql_type$": "BINARY",
408423
"data": string(dst),
409-
}
424+
}, nil
410425
}

0 commit comments

Comments
 (0)