Skip to content

Commit fda086b

Browse files
GODRIVER-3455 Extend encoder tests to include RF case
1 parent 6b3efad commit fda086b

File tree

3 files changed

+140
-152
lines changed

3 files changed

+140
-152
lines changed

bson/default_value_decoders_test.go

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3414,23 +3414,21 @@ func TestDefaultValueDecoders(t *testing.T) {
34143414
// the top-level to decode to registered type when unmarshalling to interface{}
34153415

34163416
topLevelReg := &Registry{
3417-
typeEncoders: new(typeEncoderCache),
3418-
typeDecoders: new(typeDecoderCache),
3419-
kindEncoders: new(kindEncoderCache),
3420-
kindDecoders: new(kindDecoderCache),
3421-
3417+
typeEncoders: new(typeEncoderCache),
3418+
typeDecoders: new(typeDecoderCache),
3419+
kindEncoders: new(kindEncoderCache),
3420+
kindDecoders: new(kindDecoderCache),
34223421
reflectFreeTypeEncoders: new(typeReflectFreeEncoderCache),
34233422
}
34243423
registerDefaultEncoders(topLevelReg)
34253424
registerDefaultDecoders(topLevelReg)
34263425
topLevelReg.RegisterTypeMapEntry(Type(0), reflect.TypeOf(M{}))
34273426

34283427
embeddedReg := &Registry{
3429-
typeEncoders: new(typeEncoderCache),
3430-
typeDecoders: new(typeDecoderCache),
3431-
kindEncoders: new(kindEncoderCache),
3432-
kindDecoders: new(kindDecoderCache),
3433-
3428+
typeEncoders: new(typeEncoderCache),
3429+
typeDecoders: new(typeDecoderCache),
3430+
kindEncoders: new(kindEncoderCache),
3431+
kindDecoders: new(kindDecoderCache),
34343432
reflectFreeTypeEncoders: new(typeReflectFreeEncoderCache),
34353433
}
34363434
registerDefaultEncoders(embeddedReg)
@@ -3474,11 +3472,10 @@ func TestDefaultValueDecoders(t *testing.T) {
34743472
// type information is not available.
34753473

34763474
reg := &Registry{
3477-
typeEncoders: new(typeEncoderCache),
3478-
typeDecoders: new(typeDecoderCache),
3479-
kindEncoders: new(kindEncoderCache),
3480-
kindDecoders: new(kindDecoderCache),
3481-
3475+
typeEncoders: new(typeEncoderCache),
3476+
typeDecoders: new(typeDecoderCache),
3477+
kindEncoders: new(kindEncoderCache),
3478+
kindDecoders: new(kindDecoderCache),
34823479
reflectFreeTypeEncoders: new(typeReflectFreeEncoderCache),
34833480
}
34843481
registerDefaultEncoders(reg)
@@ -3570,11 +3567,10 @@ func TestDefaultValueDecoders(t *testing.T) {
35703567

35713568
// Use a registry that has all default decoders with the custom interface{} decoder that always errors.
35723569
nestedRegistry := &Registry{
3573-
typeEncoders: new(typeEncoderCache),
3574-
typeDecoders: new(typeDecoderCache),
3575-
kindEncoders: new(kindEncoderCache),
3576-
kindDecoders: new(kindDecoderCache),
3577-
3570+
typeEncoders: new(typeEncoderCache),
3571+
typeDecoders: new(typeDecoderCache),
3572+
kindEncoders: new(kindEncoderCache),
3573+
kindDecoders: new(kindDecoderCache),
35783574
reflectFreeTypeEncoders: new(typeReflectFreeEncoderCache),
35793575
}
35803576
registerDefaultDecoders(nestedRegistry)
@@ -3729,11 +3725,10 @@ func TestDefaultValueDecoders(t *testing.T) {
37293725
)
37303726

37313727
reg := &Registry{
3732-
typeEncoders: new(typeEncoderCache),
3733-
typeDecoders: new(typeDecoderCache),
3734-
kindEncoders: new(kindEncoderCache),
3735-
kindDecoders: new(kindDecoderCache),
3736-
3728+
typeEncoders: new(typeEncoderCache),
3729+
typeDecoders: new(typeDecoderCache),
3730+
kindEncoders: new(kindEncoderCache),
3731+
kindDecoders: new(kindDecoderCache),
37373732
reflectFreeTypeEncoders: new(typeReflectFreeEncoderCache),
37383733
}
37393734
registerDefaultDecoders(reg)
@@ -3805,11 +3800,10 @@ func buildDocument(elems []byte) []byte {
38053800

38063801
func buildDefaultRegistry() *Registry {
38073802
reg := &Registry{
3808-
typeEncoders: new(typeEncoderCache),
3809-
typeDecoders: new(typeDecoderCache),
3810-
kindEncoders: new(kindEncoderCache),
3811-
kindDecoders: new(kindDecoderCache),
3812-
3803+
typeEncoders: new(typeEncoderCache),
3804+
typeDecoders: new(typeDecoderCache),
3805+
kindEncoders: new(kindEncoderCache),
3806+
kindDecoders: new(kindDecoderCache),
38133807
reflectFreeTypeEncoders: new(typeReflectFreeEncoderCache),
38143808
}
38153809
registerDefaultEncoders(reg)

bson/default_value_encoders.go

Lines changed: 38 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ func registerDefaultEncoders(reg *Registry) {
6363
// Register the reflect-free default type encoders.
6464
reg.registerReflectFreeTypeEncoder(tByteSlice, byteSliceEncodeValueRF(false))
6565
reg.registerReflectFreeTypeEncoder(tTime, reflectFreeValueEncoderFunc(timeEncodeValueRF))
66-
reg.registerReflectFreeTypeEncoder(tEmpty, reflectFreeValueEncoderFunc(emptyInterfaceValueRF))
6766
reg.registerReflectFreeTypeEncoder(tCoreArray, reflectFreeValueEncoderFunc(coreArrayEncodeValueRF))
6867
reg.registerReflectFreeTypeEncoder(tNull, reflectFreeValueEncoderFunc(nullEncodeValueRF))
6968
reg.registerReflectFreeTypeEncoder(tOID, reflectFreeValueEncoderFunc(objectIDEncodeValueRF))
@@ -76,21 +75,21 @@ func registerDefaultEncoders(reg *Registry) {
7675
reg.registerReflectFreeTypeEncoder(tVector, reflectFreeValueEncoderFunc(vectorEncodeValueRF))
7776
reg.registerReflectFreeTypeEncoder(tUndefined, reflectFreeValueEncoderFunc(undefinedEncodeValueRF))
7877
reg.registerReflectFreeTypeEncoder(tDateTime, reflectFreeValueEncoderFunc(dateTimeEncodeValueRF))
79-
reg.registerReflectFreeTypeEncoder(tRegex, reflectFreeValueEncoderFunc(regexEncodeValueX))
80-
reg.registerReflectFreeTypeEncoder(tDBPointer, reflectFreeValueEncoderFunc(dbPointerEncodeValueX))
81-
reg.registerReflectFreeTypeEncoder(tTimestamp, reflectFreeValueEncoderFunc(timestampEncodeValueX))
82-
reg.registerReflectFreeTypeEncoder(tMinKey, reflectFreeValueEncoderFunc(minKeyEncodeValueX))
83-
reg.registerReflectFreeTypeEncoder(tMaxKey, reflectFreeValueEncoderFunc(maxKeyEncodeValueX))
84-
reg.registerReflectFreeTypeEncoder(tCoreDocument, reflectFreeValueEncoderFunc(coreDocumentEncodeValueX))
85-
reg.registerReflectFreeTypeEncoder(tCodeWithScope, reflectFreeValueEncoderFunc(codeWithScopeEncodeValueX))
78+
reg.registerReflectFreeTypeEncoder(tRegex, reflectFreeValueEncoderFunc(regexEncodeValueRF))
79+
reg.registerReflectFreeTypeEncoder(tDBPointer, reflectFreeValueEncoderFunc(dbPointerEncodeValueRF))
80+
reg.registerReflectFreeTypeEncoder(tTimestamp, reflectFreeValueEncoderFunc(timestampEncodeValueRF))
81+
reg.registerReflectFreeTypeEncoder(tMinKey, reflectFreeValueEncoderFunc(minKeyEncodeValueRF))
82+
reg.registerReflectFreeTypeEncoder(tMaxKey, reflectFreeValueEncoderFunc(maxKeyEncodeValueRF))
83+
reg.registerReflectFreeTypeEncoder(tCoreDocument, reflectFreeValueEncoderFunc(coreDocumentEncodeValueRF))
84+
reg.registerReflectFreeTypeEncoder(tCodeWithScope, reflectFreeValueEncoderFunc(codeWithScopeEncodeValueRF))
8685

8786
// Register the reflect-based default encoders. These are required since
8887
// removing them would break Registry.LookupEncoder. However, these will
8988
// never be used internally.
9089
//
9190
reg.RegisterTypeEncoder(tByteSlice, byteSliceEncodeValue(false))
9291
reg.RegisterTypeEncoder(tTime, defaultValueEncoderFunc(timeEncodeValue))
93-
reg.RegisterTypeEncoder(tEmpty, defaultValueEncoderFunc(emptyInterfaceValue)) // TODO: extend this to reflection free
92+
reg.RegisterTypeEncoder(tEmpty, ValueEncoderFunc(emptyInterfaceValue))
9493
reg.RegisterTypeEncoder(tCoreArray, defaultValueEncoderFunc(coreArrayEncodeValue))
9594
reg.RegisterTypeEncoder(tOID, defaultValueEncoderFunc(objectIDEncodeValue))
9695
reg.RegisterTypeEncoder(tDecimal, defaultValueEncoderFunc(decimal128EncodeValue))
@@ -508,18 +507,7 @@ func nullEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
508507
return nullEncodeValueRF(EncodeContext{}, vw, val.Interface())
509508
}
510509

511-
// regexEncodeValue is the ValueEncoderFunc for Regex.
512-
func regexEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
513-
if !val.IsValid() || val.Type() != tRegex {
514-
return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: val}
515-
}
516-
517-
regex := val.Interface().(Regex)
518-
519-
return vw.WriteRegex(regex.Pattern, regex.Options)
520-
}
521-
522-
func regexEncodeValueX(_ EncodeContext, vw ValueWriter, val any) error {
510+
func regexEncodeValueRF(_ EncodeContext, vw ValueWriter, val any) error {
523511
regex, ok := val.(Regex)
524512
if !ok {
525513
return ValueEncoderError{Name: "RegexEncodeValue", Types: []reflect.Type{tRegex}, Received: reflect.ValueOf(val)}
@@ -528,18 +516,12 @@ func regexEncodeValueX(_ EncodeContext, vw ValueWriter, val any) error {
528516
return vw.WriteRegex(regex.Pattern, regex.Options)
529517
}
530518

531-
// dbPointerEncodeValue is the ValueEncoderFunc for DBPointer.
532-
func dbPointerEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
533-
if !val.IsValid() || val.Type() != tDBPointer {
534-
return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: val}
535-
}
536-
537-
dbp := val.Interface().(DBPointer)
538-
539-
return vw.WriteDBPointer(dbp.DB, dbp.Pointer)
519+
// regexEncodeValue is the ValueEncoderFunc for Regex.
520+
func regexEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
521+
return regexEncodeValueRF(ec, vw, val.Interface())
540522
}
541523

542-
func dbPointerEncodeValueX(_ EncodeContext, vw ValueWriter, val any) error {
524+
func dbPointerEncodeValueRF(_ EncodeContext, vw ValueWriter, val any) error {
543525
dbp, ok := val.(DBPointer)
544526
if !ok {
545527
return ValueEncoderError{Name: "DBPointerEncodeValue", Types: []reflect.Type{tDBPointer}, Received: reflect.ValueOf(val)}
@@ -548,18 +530,12 @@ func dbPointerEncodeValueX(_ EncodeContext, vw ValueWriter, val any) error {
548530
return vw.WriteDBPointer(dbp.DB, dbp.Pointer)
549531
}
550532

551-
// timestampEncodeValue is the ValueEncoderFunc for Timestamp.
552-
func timestampEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
553-
if !val.IsValid() || val.Type() != tTimestamp {
554-
return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: val}
555-
}
556-
557-
ts := val.Interface().(Timestamp)
558-
559-
return vw.WriteTimestamp(ts.T, ts.I)
533+
// dbPointerEncodeValue is the ValueEncoderFunc for DBPointer.
534+
func dbPointerEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
535+
return dbPointerEncodeValueRF(ec, vw, val.Interface())
560536
}
561537

562-
func timestampEncodeValueX(_ EncodeContext, vw ValueWriter, val any) error {
538+
func timestampEncodeValueRF(_ EncodeContext, vw ValueWriter, val any) error {
563539
ts, ok := val.(Timestamp)
564540
if !ok {
565541
return ValueEncoderError{Name: "TimestampEncodeValue", Types: []reflect.Type{tTimestamp}, Received: reflect.ValueOf(val)}
@@ -568,52 +544,38 @@ func timestampEncodeValueX(_ EncodeContext, vw ValueWriter, val any) error {
568544
return vw.WriteTimestamp(ts.T, ts.I)
569545
}
570546

571-
// minKeyEncodeValue is the ValueEncoderFunc for MinKey.
572-
func minKeyEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
573-
if !val.IsValid() || val.Type() != tMinKey {
574-
return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: val}
575-
}
576-
577-
return vw.WriteMinKey()
547+
// timestampEncodeValue is the ValueEncoderFunc for Timestamp.
548+
func timestampEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
549+
return timestampEncodeValueRF(ec, vw, val.Interface())
578550
}
579551

580-
func minKeyEncodeValueX(_ EncodeContext, vw ValueWriter, val any) error {
552+
func minKeyEncodeValueRF(_ EncodeContext, vw ValueWriter, val any) error {
581553
if _, ok := val.(MinKey); !ok {
582554
return ValueEncoderError{Name: "MinKeyEncodeValue", Types: []reflect.Type{tMinKey}, Received: reflect.ValueOf(val)}
583555
}
584556

585557
return vw.WriteMinKey()
586558
}
587559

588-
// maxKeyEncodeValue is the ValueEncoderFunc for MaxKey.
589-
func maxKeyEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
590-
if !val.IsValid() || val.Type() != tMaxKey {
591-
return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: val}
592-
}
593-
594-
return vw.WriteMaxKey()
560+
// minKeyEncodeValue is the ValueEncoderFunc for MinKey.
561+
func minKeyEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
562+
return minKeyEncodeValueRF(ec, vw, val.Interface())
595563
}
596564

597-
func maxKeyEncodeValueX(_ EncodeContext, vw ValueWriter, val any) error {
565+
func maxKeyEncodeValueRF(_ EncodeContext, vw ValueWriter, val any) error {
598566
if _, ok := val.(MaxKey); !ok {
599567
return ValueEncoderError{Name: "MaxKeyEncodeValue", Types: []reflect.Type{tMaxKey}, Received: reflect.ValueOf(val)}
600568
}
601569

602570
return vw.WriteMaxKey()
603571
}
604572

605-
// coreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document.
606-
func coreDocumentEncodeValue(_ EncodeContext, vw ValueWriter, val reflect.Value) error {
607-
if !val.IsValid() || val.Type() != tCoreDocument {
608-
return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: val}
609-
}
610-
611-
cdoc := val.Interface().(bsoncore.Document)
612-
613-
return copyDocumentFromBytes(vw, cdoc)
573+
// maxKeyEncodeValue is the ValueEncoderFunc for MaxKey.
574+
func maxKeyEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
575+
return maxKeyEncodeValueRF(ec, vw, val.Interface())
614576
}
615577

616-
func coreDocumentEncodeValueX(_ EncodeContext, vw ValueWriter, val any) error {
578+
func coreDocumentEncodeValueRF(_ EncodeContext, vw ValueWriter, val any) error {
617579
cdoc, ok := val.(bsoncore.Document)
618580
if !ok {
619581
return ValueEncoderError{Name: "CoreDocumentEncodeValue", Types: []reflect.Type{tCoreDocument}, Received: reflect.ValueOf(val)}
@@ -622,45 +584,12 @@ func coreDocumentEncodeValueX(_ EncodeContext, vw ValueWriter, val any) error {
622584
return copyDocumentFromBytes(vw, cdoc)
623585
}
624586

625-
// codeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope.
626-
func codeWithScopeEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
627-
if !val.IsValid() || val.Type() != tCodeWithScope {
628-
return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val}
629-
}
630-
631-
cws := val.Interface().(CodeWithScope)
632-
633-
dw, err := vw.WriteCodeWithScope(string(cws.Code))
634-
if err != nil {
635-
return err
636-
}
637-
638-
sw := sliceWriterPool.Get().(*sliceWriter)
639-
defer sliceWriterPool.Put(sw)
640-
*sw = (*sw)[:0]
641-
642-
scopeVW := bvwPool.Get().(*valueWriter)
643-
scopeVW.reset(scopeVW.buf[:0])
644-
scopeVW.w = sw
645-
defer bvwPool.Put(scopeVW)
646-
encoder, err := ec.LookupEncoder(reflect.TypeOf(cws.Scope))
647-
if err != nil {
648-
return err
649-
}
650-
651-
err = encoder.EncodeValue(ec, scopeVW, reflect.ValueOf(cws.Scope))
652-
if err != nil {
653-
return err
654-
}
655-
656-
err = copyBytesToDocumentWriter(dw, *sw)
657-
if err != nil {
658-
return err
659-
}
660-
return dw.WriteDocumentEnd()
587+
// coreDocumentEncodeValue is the ValueEncoderFunc for bsoncore.Document.
588+
func coreDocumentEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
589+
return coreDocumentEncodeValueRF(ec, vw, val.Interface())
661590
}
662591

663-
func codeWithScopeEncodeValueX(ec EncodeContext, vw ValueWriter, val any) error {
592+
func codeWithScopeEncodeValueRF(ec EncodeContext, vw ValueWriter, val any) error {
664593
cws, ok := val.(CodeWithScope)
665594
if !ok {
666595
return ValueEncoderError{Name: "CodeWithScopeEncodeValue", Types: []reflect.Type{tCodeWithScope}, Received: reflect.ValueOf(val)}
@@ -696,6 +625,11 @@ func codeWithScopeEncodeValueX(ec EncodeContext, vw ValueWriter, val any) error
696625
return dw.WriteDocumentEnd()
697626
}
698627

628+
// codeWithScopeEncodeValue is the ValueEncoderFunc for CodeWithScope.
629+
func codeWithScopeEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
630+
return codeWithScopeEncodeValueRF(ec, vw, val.Interface())
631+
}
632+
699633
// isImplementationNil returns if val is a nil pointer and inter is implemented on a concrete type
700634
func isImplementationNil(val reflect.Value, inter reflect.Type) bool {
701635
vt := val.Type()
@@ -757,18 +691,6 @@ func coreArrayEncodeValue(ec EncodeContext, vw ValueWriter, val reflect.Value) e
757691
return coreArrayEncodeValueRF(ec, vw, val.Interface())
758692
}
759693

760-
func emptyInterfaceValueRF(ec EncodeContext, vw ValueWriter, val any) error {
761-
if val == nil {
762-
return vw.WriteNull()
763-
}
764-
encoder, err := ec.LookupEncoder(reflect.TypeOf(val))
765-
if err != nil {
766-
return err
767-
}
768-
769-
return encoder.EncodeValue(ec, vw, reflect.ValueOf(val))
770-
}
771-
772694
func emptyInterfaceValue(ec EncodeContext, vw ValueWriter, val reflect.Value) error {
773695
if !val.IsValid() || val.Type() != tEmpty {
774696
return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val}

0 commit comments

Comments
 (0)