...

Source file src/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders_test.go

Documentation: go.mongodb.org/mongo-driver/bson/bsoncodec

     1  // Copyright (C) MongoDB, Inc. 2017-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package bsoncodec
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/json"
    12  	"errors"
    13  	"fmt"
    14  	"math"
    15  	"net/url"
    16  	"reflect"
    17  	"strings"
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/google/go-cmp/cmp"
    22  	"go.mongodb.org/mongo-driver/bson/bsonrw"
    23  	"go.mongodb.org/mongo-driver/bson/bsonrw/bsonrwtest"
    24  	"go.mongodb.org/mongo-driver/bson/bsontype"
    25  	"go.mongodb.org/mongo-driver/bson/primitive"
    26  	"go.mongodb.org/mongo-driver/internal/assert"
    27  	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
    28  )
    29  
    30  var (
    31  	defaultTestStructCodec = newDefaultStructCodec()
    32  )
    33  
    34  func TestDefaultValueDecoders(t *testing.T) {
    35  	var dvd DefaultValueDecoders
    36  	var wrong = func(string, string) string { return "wrong" }
    37  
    38  	type mybool bool
    39  	type myint8 int8
    40  	type myint16 int16
    41  	type myint32 int32
    42  	type myint64 int64
    43  	type myint int
    44  	type myuint8 uint8
    45  	type myuint16 uint16
    46  	type myuint32 uint32
    47  	type myuint64 uint64
    48  	type myuint uint
    49  	type myfloat32 float32
    50  	type myfloat64 float64
    51  	type mystring string
    52  	type mystruct struct{}
    53  
    54  	const cansetreflectiontest = "cansetreflectiontest"
    55  	const cansettest = "cansettest"
    56  
    57  	now := time.Now().Truncate(time.Millisecond)
    58  	d128 := primitive.NewDecimal128(12345, 67890)
    59  	var pbool = func(b bool) *bool { return &b }
    60  	var pi32 = func(i32 int32) *int32 { return &i32 }
    61  	var pi64 = func(i64 int64) *int64 { return &i64 }
    62  
    63  	type subtest struct {
    64  		name   string
    65  		val    interface{}
    66  		dctx   *DecodeContext
    67  		llvrw  *bsonrwtest.ValueReaderWriter
    68  		invoke bsonrwtest.Invoked
    69  		err    error
    70  	}
    71  
    72  	testCases := []struct {
    73  		name     string
    74  		vd       ValueDecoder
    75  		subtests []subtest
    76  	}{
    77  		{
    78  			"BooleanDecodeValue",
    79  			ValueDecoderFunc(dvd.BooleanDecodeValue),
    80  			[]subtest{
    81  				{
    82  					"wrong type",
    83  					wrong,
    84  					nil,
    85  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Boolean},
    86  					bsonrwtest.Nothing,
    87  					ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: reflect.ValueOf(wrong)},
    88  				},
    89  				{
    90  					"type not boolean",
    91  					bool(false),
    92  					nil,
    93  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
    94  					bsonrwtest.Nothing,
    95  					fmt.Errorf("cannot decode %v into a boolean", bsontype.String),
    96  				},
    97  				{
    98  					"fast path",
    99  					bool(true),
   100  					nil,
   101  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Boolean, Return: bool(true)},
   102  					bsonrwtest.ReadBoolean,
   103  					nil,
   104  				},
   105  				{
   106  					"reflection path",
   107  					mybool(true),
   108  					nil,
   109  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Boolean, Return: bool(true)},
   110  					bsonrwtest.ReadBoolean,
   111  					nil,
   112  				},
   113  				{
   114  					"reflection path error",
   115  					mybool(true),
   116  					nil,
   117  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Boolean, Return: bool(true), Err: errors.New("ReadBoolean Error"), ErrAfter: bsonrwtest.ReadBoolean},
   118  					bsonrwtest.ReadBoolean, errors.New("ReadBoolean Error"),
   119  				},
   120  				{
   121  					"can set false",
   122  					cansettest,
   123  					nil,
   124  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Boolean},
   125  					bsonrwtest.Nothing,
   126  					ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}},
   127  				},
   128  				{
   129  					"decode null",
   130  					mybool(false),
   131  					nil,
   132  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
   133  					bsonrwtest.ReadNull,
   134  					nil,
   135  				},
   136  				{
   137  					"decode undefined",
   138  					mybool(false),
   139  					nil,
   140  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
   141  					bsonrwtest.ReadUndefined,
   142  					nil,
   143  				},
   144  			},
   145  		},
   146  		{
   147  			"IntDecodeValue",
   148  			ValueDecoderFunc(dvd.IntDecodeValue),
   149  			[]subtest{
   150  				{
   151  					"wrong type",
   152  					wrong,
   153  					nil,
   154  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)},
   155  					bsonrwtest.ReadInt32,
   156  					ValueDecoderError{
   157  						Name:     "IntDecodeValue",
   158  						Kinds:    []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
   159  						Received: reflect.ValueOf(wrong),
   160  					},
   161  				},
   162  				{
   163  					"type not int32/int64",
   164  					0,
   165  					nil,
   166  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
   167  					bsonrwtest.Nothing,
   168  					fmt.Errorf("cannot decode %v into an integer type", bsontype.String),
   169  				},
   170  				{
   171  					"ReadInt32 error",
   172  					0,
   173  					nil,
   174  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0), Err: errors.New("ReadInt32 error"), ErrAfter: bsonrwtest.ReadInt32},
   175  					bsonrwtest.ReadInt32,
   176  					errors.New("ReadInt32 error"),
   177  				},
   178  				{
   179  					"ReadInt64 error",
   180  					0,
   181  					nil,
   182  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(0), Err: errors.New("ReadInt64 error"), ErrAfter: bsonrwtest.ReadInt64},
   183  					bsonrwtest.ReadInt64,
   184  					errors.New("ReadInt64 error"),
   185  				},
   186  				{
   187  					"ReadDouble error",
   188  					0,
   189  					nil,
   190  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0), Err: errors.New("ReadDouble error"), ErrAfter: bsonrwtest.ReadDouble},
   191  					bsonrwtest.ReadDouble,
   192  					errors.New("ReadDouble error"),
   193  				},
   194  				{
   195  					"ReadDouble", int64(3), &DecodeContext{},
   196  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.00)}, bsonrwtest.ReadDouble,
   197  					nil,
   198  				},
   199  				{
   200  					"ReadDouble (truncate)", int64(3), &DecodeContext{Truncate: true},
   201  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
   202  					nil,
   203  				},
   204  				{
   205  					"ReadDouble (no truncate)", int64(0), nil,
   206  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
   207  					errCannotTruncate,
   208  				},
   209  				{
   210  					"ReadDouble overflows int64", int64(0), nil,
   211  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: math.MaxFloat64}, bsonrwtest.ReadDouble,
   212  					fmt.Errorf("%g overflows int64", math.MaxFloat64),
   213  				},
   214  				{"int8/fast path", int8(127), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(127)}, bsonrwtest.ReadInt32, nil},
   215  				{"int16/fast path", int16(32676), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(32676)}, bsonrwtest.ReadInt32, nil},
   216  				{"int32/fast path", int32(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1234)}, bsonrwtest.ReadInt32, nil},
   217  				{"int64/fast path", int64(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1234)}, bsonrwtest.ReadInt64, nil},
   218  				{"int/fast path", int(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1234)}, bsonrwtest.ReadInt64, nil},
   219  				{
   220  					"int8/fast path - nil", (*int8)(nil), nil,
   221  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
   222  					ValueDecoderError{
   223  						Name:     "IntDecodeValue",
   224  						Kinds:    []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
   225  						Received: reflect.ValueOf((*int8)(nil)),
   226  					},
   227  				},
   228  				{
   229  					"int16/fast path - nil", (*int16)(nil), nil,
   230  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
   231  					ValueDecoderError{
   232  						Name:     "IntDecodeValue",
   233  						Kinds:    []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
   234  						Received: reflect.ValueOf((*int16)(nil)),
   235  					},
   236  				},
   237  				{
   238  					"int32/fast path - nil", (*int32)(nil), nil,
   239  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
   240  					ValueDecoderError{
   241  						Name:     "IntDecodeValue",
   242  						Kinds:    []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
   243  						Received: reflect.ValueOf((*int32)(nil)),
   244  					},
   245  				},
   246  				{
   247  					"int64/fast path - nil", (*int64)(nil), nil,
   248  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
   249  					ValueDecoderError{
   250  						Name:     "IntDecodeValue",
   251  						Kinds:    []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
   252  						Received: reflect.ValueOf((*int64)(nil)),
   253  					},
   254  				},
   255  				{
   256  					"int/fast path - nil", (*int)(nil), nil,
   257  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
   258  					ValueDecoderError{
   259  						Name:     "IntDecodeValue",
   260  						Kinds:    []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
   261  						Received: reflect.ValueOf((*int)(nil)),
   262  					},
   263  				},
   264  				{
   265  					"int8/fast path - overflow", int8(0), nil,
   266  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(129)}, bsonrwtest.ReadInt32,
   267  					fmt.Errorf("%d overflows int8", 129),
   268  				},
   269  				{
   270  					"int16/fast path - overflow", int16(0), nil,
   271  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(32768)}, bsonrwtest.ReadInt32,
   272  					fmt.Errorf("%d overflows int16", 32768),
   273  				},
   274  				{
   275  					"int32/fast path - overflow", int32(0), nil,
   276  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(2147483648)}, bsonrwtest.ReadInt64,
   277  					fmt.Errorf("%d overflows int32", int64(2147483648)),
   278  				},
   279  				{
   280  					"int8/fast path - overflow (negative)", int8(0), nil,
   281  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-129)}, bsonrwtest.ReadInt32,
   282  					fmt.Errorf("%d overflows int8", -129),
   283  				},
   284  				{
   285  					"int16/fast path - overflow (negative)", int16(0), nil,
   286  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-32769)}, bsonrwtest.ReadInt32,
   287  					fmt.Errorf("%d overflows int16", -32769),
   288  				},
   289  				{
   290  					"int32/fast path - overflow (negative)", int32(0), nil,
   291  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-2147483649)}, bsonrwtest.ReadInt64,
   292  					fmt.Errorf("%d overflows int32", int64(-2147483649)),
   293  				},
   294  				{
   295  					"int8/reflection path", myint8(127), nil,
   296  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(127)}, bsonrwtest.ReadInt32,
   297  					nil,
   298  				},
   299  				{
   300  					"int16/reflection path", myint16(255), nil,
   301  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(255)}, bsonrwtest.ReadInt32,
   302  					nil,
   303  				},
   304  				{
   305  					"int32/reflection path", myint32(511), nil,
   306  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(511)}, bsonrwtest.ReadInt32,
   307  					nil,
   308  				},
   309  				{
   310  					"int64/reflection path", myint64(1023), nil,
   311  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1023)}, bsonrwtest.ReadInt32,
   312  					nil,
   313  				},
   314  				{
   315  					"int/reflection path", myint(2047), nil,
   316  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(2047)}, bsonrwtest.ReadInt32,
   317  					nil,
   318  				},
   319  				{
   320  					"int8/reflection path - overflow", myint8(0), nil,
   321  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(129)}, bsonrwtest.ReadInt32,
   322  					fmt.Errorf("%d overflows int8", 129),
   323  				},
   324  				{
   325  					"int16/reflection path - overflow", myint16(0), nil,
   326  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(32768)}, bsonrwtest.ReadInt32,
   327  					fmt.Errorf("%d overflows int16", 32768),
   328  				},
   329  				{
   330  					"int32/reflection path - overflow", myint32(0), nil,
   331  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(2147483648)}, bsonrwtest.ReadInt64,
   332  					fmt.Errorf("%d overflows int32", int64(2147483648)),
   333  				},
   334  				{
   335  					"int8/reflection path - overflow (negative)", myint8(0), nil,
   336  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-129)}, bsonrwtest.ReadInt32,
   337  					fmt.Errorf("%d overflows int8", -129),
   338  				},
   339  				{
   340  					"int16/reflection path - overflow (negative)", myint16(0), nil,
   341  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-32769)}, bsonrwtest.ReadInt32,
   342  					fmt.Errorf("%d overflows int16", -32769),
   343  				},
   344  				{
   345  					"int32/reflection path - overflow (negative)", myint32(0), nil,
   346  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-2147483649)}, bsonrwtest.ReadInt64,
   347  					fmt.Errorf("%d overflows int32", int64(-2147483649)),
   348  				},
   349  				{
   350  					"can set false",
   351  					cansettest,
   352  					nil,
   353  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)},
   354  					bsonrwtest.Nothing,
   355  					ValueDecoderError{
   356  						Name:  "IntDecodeValue",
   357  						Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
   358  					},
   359  				},
   360  				{
   361  					"decode null",
   362  					myint(0),
   363  					nil,
   364  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
   365  					bsonrwtest.ReadNull,
   366  					nil,
   367  				},
   368  				{
   369  					"decode undefined",
   370  					myint(0),
   371  					nil,
   372  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
   373  					bsonrwtest.ReadUndefined,
   374  					nil,
   375  				},
   376  			},
   377  		},
   378  		{
   379  			"defaultUIntCodec.DecodeValue",
   380  			defaultUIntCodec,
   381  			[]subtest{
   382  				{
   383  					"wrong type",
   384  					wrong,
   385  					nil,
   386  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)},
   387  					bsonrwtest.ReadInt32,
   388  					ValueDecoderError{
   389  						Name:     "UintDecodeValue",
   390  						Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
   391  						Received: reflect.ValueOf(wrong),
   392  					},
   393  				},
   394  				{
   395  					"type not int32/int64",
   396  					0,
   397  					nil,
   398  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
   399  					bsonrwtest.Nothing,
   400  					fmt.Errorf("cannot decode %v into an integer type", bsontype.String),
   401  				},
   402  				{
   403  					"ReadInt32 error",
   404  					uint(0),
   405  					nil,
   406  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0), Err: errors.New("ReadInt32 error"), ErrAfter: bsonrwtest.ReadInt32},
   407  					bsonrwtest.ReadInt32,
   408  					errors.New("ReadInt32 error"),
   409  				},
   410  				{
   411  					"ReadInt64 error",
   412  					uint(0),
   413  					nil,
   414  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(0), Err: errors.New("ReadInt64 error"), ErrAfter: bsonrwtest.ReadInt64},
   415  					bsonrwtest.ReadInt64,
   416  					errors.New("ReadInt64 error"),
   417  				},
   418  				{
   419  					"ReadDouble error",
   420  					0,
   421  					nil,
   422  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0), Err: errors.New("ReadDouble error"), ErrAfter: bsonrwtest.ReadDouble},
   423  					bsonrwtest.ReadDouble,
   424  					errors.New("ReadDouble error"),
   425  				},
   426  				{
   427  					"ReadDouble", uint64(3), &DecodeContext{},
   428  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.00)}, bsonrwtest.ReadDouble,
   429  					nil,
   430  				},
   431  				{
   432  					"ReadDouble (truncate)", uint64(3), &DecodeContext{Truncate: true},
   433  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
   434  					nil,
   435  				},
   436  				{
   437  					"ReadDouble (no truncate)", uint64(0), nil,
   438  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
   439  					errCannotTruncate,
   440  				},
   441  				{
   442  					"ReadDouble overflows int64", uint64(0), nil,
   443  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: math.MaxFloat64}, bsonrwtest.ReadDouble,
   444  					fmt.Errorf("%g overflows int64", math.MaxFloat64),
   445  				},
   446  				{"uint8/fast path", uint8(127), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(127)}, bsonrwtest.ReadInt32, nil},
   447  				{"uint16/fast path", uint16(255), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(255)}, bsonrwtest.ReadInt32, nil},
   448  				{"uint32/fast path", uint32(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1234)}, bsonrwtest.ReadInt32, nil},
   449  				{"uint64/fast path", uint64(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1234)}, bsonrwtest.ReadInt64, nil},
   450  				{"uint/fast path", uint(1234), nil, &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1234)}, bsonrwtest.ReadInt64, nil},
   451  				{
   452  					"uint8/fast path - nil", (*uint8)(nil), nil,
   453  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
   454  					ValueDecoderError{
   455  						Name:     "UintDecodeValue",
   456  						Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
   457  						Received: reflect.ValueOf((*uint8)(nil)),
   458  					},
   459  				},
   460  				{
   461  					"uint16/fast path - nil", (*uint16)(nil), nil,
   462  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
   463  					ValueDecoderError{
   464  						Name:     "UintDecodeValue",
   465  						Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
   466  						Received: reflect.ValueOf((*uint16)(nil)),
   467  					},
   468  				},
   469  				{
   470  					"uint32/fast path - nil", (*uint32)(nil), nil,
   471  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
   472  					ValueDecoderError{
   473  						Name:     "UintDecodeValue",
   474  						Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
   475  						Received: reflect.ValueOf((*uint32)(nil)),
   476  					},
   477  				},
   478  				{
   479  					"uint64/fast path - nil", (*uint64)(nil), nil,
   480  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
   481  					ValueDecoderError{
   482  						Name:     "UintDecodeValue",
   483  						Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
   484  						Received: reflect.ValueOf((*uint64)(nil)),
   485  					},
   486  				},
   487  				{
   488  					"uint/fast path - nil", (*uint)(nil), nil,
   489  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)}, bsonrwtest.ReadInt32,
   490  					ValueDecoderError{
   491  						Name:     "UintDecodeValue",
   492  						Kinds:    []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
   493  						Received: reflect.ValueOf((*uint)(nil)),
   494  					},
   495  				},
   496  				{
   497  					"uint8/fast path - overflow", uint8(0), nil,
   498  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1 << 8)}, bsonrwtest.ReadInt32,
   499  					fmt.Errorf("%d overflows uint8", 1<<8),
   500  				},
   501  				{
   502  					"uint16/fast path - overflow", uint16(0), nil,
   503  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1 << 16)}, bsonrwtest.ReadInt32,
   504  					fmt.Errorf("%d overflows uint16", 1<<16),
   505  				},
   506  				{
   507  					"uint32/fast path - overflow", uint32(0), nil,
   508  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1 << 32)}, bsonrwtest.ReadInt64,
   509  					fmt.Errorf("%d overflows uint32", int64(1<<32)),
   510  				},
   511  				{
   512  					"uint8/fast path - overflow (negative)", uint8(0), nil,
   513  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-1)}, bsonrwtest.ReadInt32,
   514  					fmt.Errorf("%d overflows uint8", -1),
   515  				},
   516  				{
   517  					"uint16/fast path - overflow (negative)", uint16(0), nil,
   518  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-1)}, bsonrwtest.ReadInt32,
   519  					fmt.Errorf("%d overflows uint16", -1),
   520  				},
   521  				{
   522  					"uint32/fast path - overflow (negative)", uint32(0), nil,
   523  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
   524  					fmt.Errorf("%d overflows uint32", -1),
   525  				},
   526  				{
   527  					"uint64/fast path - overflow (negative)", uint64(0), nil,
   528  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
   529  					fmt.Errorf("%d overflows uint64", -1),
   530  				},
   531  				{
   532  					"uint/fast path - overflow (negative)", uint(0), nil,
   533  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
   534  					fmt.Errorf("%d overflows uint", -1),
   535  				},
   536  				{
   537  					"uint8/reflection path", myuint8(127), nil,
   538  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(127)}, bsonrwtest.ReadInt32,
   539  					nil,
   540  				},
   541  				{
   542  					"uint16/reflection path", myuint16(255), nil,
   543  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(255)}, bsonrwtest.ReadInt32,
   544  					nil,
   545  				},
   546  				{
   547  					"uint32/reflection path", myuint32(511), nil,
   548  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(511)}, bsonrwtest.ReadInt32,
   549  					nil,
   550  				},
   551  				{
   552  					"uint64/reflection path", myuint64(1023), nil,
   553  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1023)}, bsonrwtest.ReadInt32,
   554  					nil,
   555  				},
   556  				{
   557  					"uint/reflection path", myuint(2047), nil,
   558  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(2047)}, bsonrwtest.ReadInt32,
   559  					nil,
   560  				},
   561  				{
   562  					"uint8/reflection path - overflow", myuint8(0), nil,
   563  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1 << 8)}, bsonrwtest.ReadInt32,
   564  					fmt.Errorf("%d overflows uint8", 1<<8),
   565  				},
   566  				{
   567  					"uint16/reflection path - overflow", myuint16(0), nil,
   568  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(1 << 16)}, bsonrwtest.ReadInt32,
   569  					fmt.Errorf("%d overflows uint16", 1<<16),
   570  				},
   571  				{
   572  					"uint32/reflection path - overflow", myuint32(0), nil,
   573  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1 << 32)}, bsonrwtest.ReadInt64,
   574  					fmt.Errorf("%d overflows uint32", int64(1<<32)),
   575  				},
   576  				{
   577  					"uint8/reflection path - overflow (negative)", myuint8(0), nil,
   578  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-1)}, bsonrwtest.ReadInt32,
   579  					fmt.Errorf("%d overflows uint8", -1),
   580  				},
   581  				{
   582  					"uint16/reflection path - overflow (negative)", myuint16(0), nil,
   583  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(-1)}, bsonrwtest.ReadInt32,
   584  					fmt.Errorf("%d overflows uint16", -1),
   585  				},
   586  				{
   587  					"uint32/reflection path - overflow (negative)", myuint32(0), nil,
   588  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
   589  					fmt.Errorf("%d overflows uint32", -1),
   590  				},
   591  				{
   592  					"uint64/reflection path - overflow (negative)", myuint64(0), nil,
   593  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
   594  					fmt.Errorf("%d overflows uint64", -1),
   595  				},
   596  				{
   597  					"uint/reflection path - overflow (negative)", myuint(0), nil,
   598  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(-1)}, bsonrwtest.ReadInt64,
   599  					fmt.Errorf("%d overflows uint", -1),
   600  				},
   601  				{
   602  					"can set false",
   603  					cansettest,
   604  					nil,
   605  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0)},
   606  					bsonrwtest.Nothing,
   607  					ValueDecoderError{
   608  						Name:  "UintDecodeValue",
   609  						Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
   610  					},
   611  				},
   612  			},
   613  		},
   614  		{
   615  			"FloatDecodeValue",
   616  			ValueDecoderFunc(dvd.FloatDecodeValue),
   617  			[]subtest{
   618  				{
   619  					"wrong type",
   620  					wrong,
   621  					nil,
   622  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0)},
   623  					bsonrwtest.ReadDouble,
   624  					ValueDecoderError{
   625  						Name:     "FloatDecodeValue",
   626  						Kinds:    []reflect.Kind{reflect.Float32, reflect.Float64},
   627  						Received: reflect.ValueOf(wrong),
   628  					},
   629  				},
   630  				{
   631  					"type not double",
   632  					0,
   633  					nil,
   634  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
   635  					bsonrwtest.Nothing,
   636  					fmt.Errorf("cannot decode %v into a float32 or float64 type", bsontype.String),
   637  				},
   638  				{
   639  					"ReadDouble error",
   640  					float64(0),
   641  					nil,
   642  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0), Err: errors.New("ReadDouble error"), ErrAfter: bsonrwtest.ReadDouble},
   643  					bsonrwtest.ReadDouble,
   644  					errors.New("ReadDouble error"),
   645  				},
   646  				{
   647  					"ReadInt32 error",
   648  					float64(0),
   649  					nil,
   650  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(0), Err: errors.New("ReadInt32 error"), ErrAfter: bsonrwtest.ReadInt32},
   651  					bsonrwtest.ReadInt32,
   652  					errors.New("ReadInt32 error"),
   653  				},
   654  				{
   655  					"ReadInt64 error",
   656  					float64(0),
   657  					nil,
   658  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(0), Err: errors.New("ReadInt64 error"), ErrAfter: bsonrwtest.ReadInt64},
   659  					bsonrwtest.ReadInt64,
   660  					errors.New("ReadInt64 error"),
   661  				},
   662  				{
   663  					"float64/int32", float32(32.0), nil,
   664  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(32)}, bsonrwtest.ReadInt32,
   665  					nil,
   666  				},
   667  				{
   668  					"float64/int64", float32(64.0), nil,
   669  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(64)}, bsonrwtest.ReadInt64,
   670  					nil,
   671  				},
   672  				{
   673  					"float32/fast path (equal)", float32(3.0), nil,
   674  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.0)}, bsonrwtest.ReadDouble,
   675  					nil,
   676  				},
   677  				{
   678  					"float64/fast path", float64(3.14159), nil,
   679  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)}, bsonrwtest.ReadDouble,
   680  					nil,
   681  				},
   682  				{
   683  					"float32/fast path (truncate)", float32(3.14), &DecodeContext{Truncate: true},
   684  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
   685  					nil,
   686  				},
   687  				{
   688  					"float32/fast path (no truncate)", float32(0), nil,
   689  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
   690  					errCannotTruncate,
   691  				},
   692  				{
   693  					"float32/fast path - nil", (*float32)(nil), nil,
   694  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0)}, bsonrwtest.ReadDouble,
   695  					ValueDecoderError{
   696  						Name:     "FloatDecodeValue",
   697  						Kinds:    []reflect.Kind{reflect.Float32, reflect.Float64},
   698  						Received: reflect.ValueOf((*float32)(nil)),
   699  					},
   700  				},
   701  				{
   702  					"float64/fast path - nil", (*float64)(nil), nil,
   703  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0)}, bsonrwtest.ReadDouble,
   704  					ValueDecoderError{
   705  						Name:     "FloatDecodeValue",
   706  						Kinds:    []reflect.Kind{reflect.Float32, reflect.Float64},
   707  						Received: reflect.ValueOf((*float64)(nil)),
   708  					},
   709  				},
   710  				{
   711  					"float32/reflection path (equal)", myfloat32(3.0), nil,
   712  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.0)}, bsonrwtest.ReadDouble,
   713  					nil,
   714  				},
   715  				{
   716  					"float64/reflection path", myfloat64(3.14159), nil,
   717  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)}, bsonrwtest.ReadDouble,
   718  					nil,
   719  				},
   720  				{
   721  					"float32/reflection path (truncate)", myfloat32(3.14), &DecodeContext{Truncate: true},
   722  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
   723  					nil,
   724  				},
   725  				{
   726  					"float32/reflection path (no truncate)", myfloat32(0), nil,
   727  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14)}, bsonrwtest.ReadDouble,
   728  					errCannotTruncate,
   729  				},
   730  				{
   731  					"can set false",
   732  					cansettest,
   733  					nil,
   734  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(0)},
   735  					bsonrwtest.Nothing,
   736  					ValueDecoderError{
   737  						Name:  "FloatDecodeValue",
   738  						Kinds: []reflect.Kind{reflect.Float32, reflect.Float64},
   739  					},
   740  				},
   741  			},
   742  		},
   743  		{
   744  			"defaultTimeCodec.DecodeValue",
   745  			defaultTimeCodec,
   746  			[]subtest{
   747  				{
   748  					"wrong type",
   749  					wrong,
   750  					nil,
   751  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Return: int64(0)},
   752  					bsonrwtest.Nothing,
   753  					ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}, Received: reflect.ValueOf(wrong)},
   754  				},
   755  				{
   756  					"ReadDateTime error",
   757  					time.Time{},
   758  					nil,
   759  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Return: int64(0), Err: errors.New("ReadDateTime error"), ErrAfter: bsonrwtest.ReadDateTime},
   760  					bsonrwtest.ReadDateTime,
   761  					errors.New("ReadDateTime error"),
   762  				},
   763  				{
   764  					"time.Time",
   765  					now,
   766  					nil,
   767  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Return: now.UnixNano() / int64(time.Millisecond)},
   768  					bsonrwtest.ReadDateTime,
   769  					nil,
   770  				},
   771  				{
   772  					"can set false",
   773  					cansettest,
   774  					nil,
   775  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Return: int64(0)},
   776  					bsonrwtest.Nothing,
   777  					ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}},
   778  				},
   779  				{
   780  					"decode null",
   781  					time.Time{},
   782  					nil,
   783  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
   784  					bsonrwtest.ReadNull,
   785  					nil,
   786  				},
   787  				{
   788  					"decode undefined",
   789  					time.Time{},
   790  					nil,
   791  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
   792  					bsonrwtest.ReadUndefined,
   793  					nil,
   794  				},
   795  			},
   796  		},
   797  		{
   798  			"defaultMapCodec.DecodeValue",
   799  			defaultMapCodec,
   800  			[]subtest{
   801  				{
   802  					"wrong kind",
   803  					wrong,
   804  					nil,
   805  					&bsonrwtest.ValueReaderWriter{},
   806  					bsonrwtest.Nothing,
   807  					ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: reflect.ValueOf(wrong)},
   808  				},
   809  				{
   810  					"wrong kind (non-string key)",
   811  					map[bool]interface{}{},
   812  					&DecodeContext{Registry: buildDefaultRegistry()},
   813  					&bsonrwtest.ValueReaderWriter{},
   814  					bsonrwtest.ReadElement,
   815  					fmt.Errorf("unsupported key type: %T", false),
   816  				},
   817  				{
   818  					"ReadDocument Error",
   819  					make(map[string]interface{}),
   820  					nil,
   821  					&bsonrwtest.ValueReaderWriter{Err: errors.New("rd error"), ErrAfter: bsonrwtest.ReadDocument},
   822  					bsonrwtest.ReadDocument,
   823  					errors.New("rd error"),
   824  				},
   825  				{
   826  					"Lookup Error",
   827  					map[string]string{},
   828  					&DecodeContext{Registry: NewRegistryBuilder().Build()},
   829  					&bsonrwtest.ValueReaderWriter{},
   830  					bsonrwtest.ReadDocument,
   831  					ErrNoDecoder{Type: reflect.TypeOf("")},
   832  				},
   833  				{
   834  					"ReadElement Error",
   835  					make(map[string]interface{}),
   836  					&DecodeContext{Registry: buildDefaultRegistry()},
   837  					&bsonrwtest.ValueReaderWriter{Err: errors.New("re error"), ErrAfter: bsonrwtest.ReadElement},
   838  					bsonrwtest.ReadElement,
   839  					errors.New("re error"),
   840  				},
   841  				{
   842  					"can set false",
   843  					cansettest,
   844  					nil,
   845  					&bsonrwtest.ValueReaderWriter{},
   846  					bsonrwtest.Nothing,
   847  					ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}},
   848  				},
   849  				{
   850  					"wrong BSON type",
   851  					map[string]interface{}{},
   852  					nil,
   853  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
   854  					bsonrwtest.Nothing,
   855  					errors.New("cannot decode string into a map[string]interface {}"),
   856  				},
   857  				{
   858  					"decode null",
   859  					(map[string]interface{})(nil),
   860  					nil,
   861  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
   862  					bsonrwtest.ReadNull,
   863  					nil,
   864  				},
   865  				{
   866  					"decode undefined",
   867  					(map[string]interface{})(nil),
   868  					nil,
   869  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
   870  					bsonrwtest.ReadUndefined,
   871  					nil,
   872  				},
   873  			},
   874  		},
   875  		{
   876  			"ArrayDecodeValue",
   877  			ValueDecoderFunc(dvd.ArrayDecodeValue),
   878  			[]subtest{
   879  				{
   880  					"wrong kind",
   881  					wrong,
   882  					nil,
   883  					&bsonrwtest.ValueReaderWriter{},
   884  					bsonrwtest.Nothing,
   885  					ValueDecoderError{Name: "ArrayDecodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: reflect.ValueOf(wrong)},
   886  				},
   887  				{
   888  					"can set false",
   889  					cansettest,
   890  					nil,
   891  					&bsonrwtest.ValueReaderWriter{},
   892  					bsonrwtest.Nothing,
   893  					ValueDecoderError{Name: "ArrayDecodeValue", Kinds: []reflect.Kind{reflect.Array}},
   894  				},
   895  				{
   896  					"Not Type Array",
   897  					[1]interface{}{},
   898  					nil,
   899  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
   900  					bsonrwtest.Nothing,
   901  					errors.New("cannot decode string into an array"),
   902  				},
   903  				{
   904  					"ReadArray Error",
   905  					[1]interface{}{},
   906  					nil,
   907  					&bsonrwtest.ValueReaderWriter{Err: errors.New("ra error"), ErrAfter: bsonrwtest.ReadArray, BSONType: bsontype.Array},
   908  					bsonrwtest.ReadArray,
   909  					errors.New("ra error"),
   910  				},
   911  				{
   912  					"Lookup Error",
   913  					[1]string{},
   914  					&DecodeContext{Registry: NewRegistryBuilder().Build()},
   915  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
   916  					bsonrwtest.ReadArray,
   917  					ErrNoDecoder{Type: reflect.TypeOf("")},
   918  				},
   919  				{
   920  					"ReadValue Error",
   921  					[1]string{},
   922  					&DecodeContext{Registry: buildDefaultRegistry()},
   923  					&bsonrwtest.ValueReaderWriter{Err: errors.New("rv error"), ErrAfter: bsonrwtest.ReadValue, BSONType: bsontype.Array},
   924  					bsonrwtest.ReadValue,
   925  					errors.New("rv error"),
   926  				},
   927  				{
   928  					"DecodeValue Error",
   929  					[1]string{},
   930  					&DecodeContext{Registry: buildDefaultRegistry()},
   931  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
   932  					bsonrwtest.ReadValue,
   933  					&DecodeError{keys: []string{"0"}, wrapped: errors.New("cannot decode array into a string type")},
   934  				},
   935  				{
   936  					"Document but not D",
   937  					[1]string{},
   938  					nil,
   939  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Type(0)},
   940  					bsonrwtest.Nothing,
   941  					errors.New("cannot decode document into [1]string"),
   942  				},
   943  				{
   944  					"EmbeddedDocument but not D",
   945  					[1]string{},
   946  					nil,
   947  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.EmbeddedDocument},
   948  					bsonrwtest.Nothing,
   949  					errors.New("cannot decode document into [1]string"),
   950  				},
   951  				{
   952  					"decode null",
   953  					[1]string{},
   954  					nil,
   955  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
   956  					bsonrwtest.ReadNull,
   957  					nil,
   958  				},
   959  				{
   960  					"decode undefined",
   961  					[1]string{},
   962  					nil,
   963  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
   964  					bsonrwtest.ReadUndefined,
   965  					nil,
   966  				},
   967  			},
   968  		},
   969  		{
   970  			"defaultSliceCodec.DecodeValue",
   971  			defaultSliceCodec,
   972  			[]subtest{
   973  				{
   974  					"wrong kind",
   975  					wrong,
   976  					nil,
   977  					&bsonrwtest.ValueReaderWriter{},
   978  					bsonrwtest.Nothing,
   979  					ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: reflect.ValueOf(wrong)},
   980  				},
   981  				{
   982  					"can set false",
   983  					cansettest,
   984  					nil,
   985  					&bsonrwtest.ValueReaderWriter{},
   986  					bsonrwtest.Nothing,
   987  					ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}},
   988  				},
   989  				{
   990  					"Not Type Array",
   991  					[]interface{}{},
   992  					nil,
   993  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32},
   994  					bsonrwtest.Nothing,
   995  					errors.New("cannot decode 32-bit integer into a slice"),
   996  				},
   997  				{
   998  					"ReadArray Error",
   999  					[]interface{}{},
  1000  					nil,
  1001  					&bsonrwtest.ValueReaderWriter{Err: errors.New("ra error"), ErrAfter: bsonrwtest.ReadArray, BSONType: bsontype.Array},
  1002  					bsonrwtest.ReadArray,
  1003  					errors.New("ra error"),
  1004  				},
  1005  				{
  1006  					"Lookup Error",
  1007  					[]string{},
  1008  					&DecodeContext{Registry: NewRegistryBuilder().Build()},
  1009  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
  1010  					bsonrwtest.ReadArray,
  1011  					ErrNoDecoder{Type: reflect.TypeOf("")},
  1012  				},
  1013  				{
  1014  					"ReadValue Error",
  1015  					[]string{},
  1016  					&DecodeContext{Registry: buildDefaultRegistry()},
  1017  					&bsonrwtest.ValueReaderWriter{Err: errors.New("rv error"), ErrAfter: bsonrwtest.ReadValue, BSONType: bsontype.Array},
  1018  					bsonrwtest.ReadValue,
  1019  					errors.New("rv error"),
  1020  				},
  1021  				{
  1022  					"DecodeValue Error",
  1023  					[]string{},
  1024  					&DecodeContext{Registry: buildDefaultRegistry()},
  1025  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
  1026  					bsonrwtest.ReadValue,
  1027  					&DecodeError{keys: []string{"0"}, wrapped: errors.New("cannot decode array into a string type")},
  1028  				},
  1029  				{
  1030  					"Document but not D",
  1031  					[]string{},
  1032  					nil,
  1033  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Type(0)},
  1034  					bsonrwtest.Nothing,
  1035  					errors.New("cannot decode document into []string"),
  1036  				},
  1037  				{
  1038  					"EmbeddedDocument but not D",
  1039  					[]string{},
  1040  					nil,
  1041  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.EmbeddedDocument},
  1042  					bsonrwtest.Nothing,
  1043  					errors.New("cannot decode document into []string"),
  1044  				},
  1045  				{
  1046  					"decode null",
  1047  					([]string)(nil),
  1048  					nil,
  1049  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1050  					bsonrwtest.ReadNull,
  1051  					nil,
  1052  				},
  1053  				{
  1054  					"decode undefined",
  1055  					([]string)(nil),
  1056  					nil,
  1057  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1058  					bsonrwtest.ReadUndefined,
  1059  					nil,
  1060  				},
  1061  			},
  1062  		},
  1063  		{
  1064  			"ObjectIDDecodeValue",
  1065  			ValueDecoderFunc(dvd.ObjectIDDecodeValue),
  1066  			[]subtest{
  1067  				{
  1068  					"wrong type",
  1069  					wrong,
  1070  					nil,
  1071  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.ObjectID},
  1072  					bsonrwtest.Nothing,
  1073  					ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}, Received: reflect.ValueOf(wrong)},
  1074  				},
  1075  				{
  1076  					"type not objectID",
  1077  					primitive.ObjectID{},
  1078  					nil,
  1079  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32},
  1080  					bsonrwtest.Nothing,
  1081  					fmt.Errorf("cannot decode %v into an ObjectID", bsontype.Int32),
  1082  				},
  1083  				{
  1084  					"ReadObjectID Error",
  1085  					primitive.ObjectID{},
  1086  					nil,
  1087  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.ObjectID, Err: errors.New("roid error"), ErrAfter: bsonrwtest.ReadObjectID},
  1088  					bsonrwtest.ReadObjectID,
  1089  					errors.New("roid error"),
  1090  				},
  1091  				{
  1092  					"can set false",
  1093  					cansettest,
  1094  					nil,
  1095  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.ObjectID, Return: primitive.ObjectID{}},
  1096  					bsonrwtest.Nothing,
  1097  					ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}},
  1098  				},
  1099  				{
  1100  					"success",
  1101  					primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
  1102  					nil,
  1103  					&bsonrwtest.ValueReaderWriter{
  1104  						BSONType: bsontype.ObjectID,
  1105  						Return:   primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
  1106  					},
  1107  					bsonrwtest.ReadObjectID,
  1108  					nil,
  1109  				},
  1110  				{
  1111  					"success/string",
  1112  					primitive.ObjectID{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62},
  1113  					nil,
  1114  					&bsonrwtest.ValueReaderWriter{
  1115  						BSONType: bsontype.String,
  1116  						Return:   "0123456789ab",
  1117  					},
  1118  					bsonrwtest.ReadString,
  1119  					nil,
  1120  				},
  1121  				{
  1122  					"success/string-hex",
  1123  					primitive.ObjectID{0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62},
  1124  					nil,
  1125  					&bsonrwtest.ValueReaderWriter{
  1126  						BSONType: bsontype.String,
  1127  						Return:   "303132333435363738396162",
  1128  					},
  1129  					bsonrwtest.ReadString,
  1130  					nil,
  1131  				},
  1132  				{
  1133  					"decode null",
  1134  					primitive.ObjectID{},
  1135  					nil,
  1136  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1137  					bsonrwtest.ReadNull,
  1138  					nil,
  1139  				},
  1140  				{
  1141  					"decode undefined",
  1142  					primitive.ObjectID{},
  1143  					nil,
  1144  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1145  					bsonrwtest.ReadUndefined,
  1146  					nil,
  1147  				},
  1148  			},
  1149  		},
  1150  		{
  1151  			"Decimal128DecodeValue",
  1152  			ValueDecoderFunc(dvd.Decimal128DecodeValue),
  1153  			[]subtest{
  1154  				{
  1155  					"wrong type",
  1156  					wrong,
  1157  					nil,
  1158  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Decimal128},
  1159  					bsonrwtest.Nothing,
  1160  					ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}, Received: reflect.ValueOf(wrong)},
  1161  				},
  1162  				{
  1163  					"type not decimal128",
  1164  					primitive.Decimal128{},
  1165  					nil,
  1166  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  1167  					bsonrwtest.Nothing,
  1168  					fmt.Errorf("cannot decode %v into a primitive.Decimal128", bsontype.String),
  1169  				},
  1170  				{
  1171  					"ReadDecimal128 Error",
  1172  					primitive.Decimal128{},
  1173  					nil,
  1174  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Decimal128, Err: errors.New("rd128 error"), ErrAfter: bsonrwtest.ReadDecimal128},
  1175  					bsonrwtest.ReadDecimal128,
  1176  					errors.New("rd128 error"),
  1177  				},
  1178  				{
  1179  					"can set false",
  1180  					cansettest,
  1181  					nil,
  1182  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Decimal128, Return: d128},
  1183  					bsonrwtest.Nothing,
  1184  					ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}},
  1185  				},
  1186  				{
  1187  					"success",
  1188  					d128,
  1189  					nil,
  1190  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Decimal128, Return: d128},
  1191  					bsonrwtest.ReadDecimal128,
  1192  					nil,
  1193  				},
  1194  				{
  1195  					"decode null",
  1196  					primitive.Decimal128{},
  1197  					nil,
  1198  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1199  					bsonrwtest.ReadNull,
  1200  					nil,
  1201  				},
  1202  				{
  1203  					"decode undefined",
  1204  					primitive.Decimal128{},
  1205  					nil,
  1206  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1207  					bsonrwtest.ReadUndefined,
  1208  					nil,
  1209  				},
  1210  			},
  1211  		},
  1212  		{
  1213  			"JSONNumberDecodeValue",
  1214  			ValueDecoderFunc(dvd.JSONNumberDecodeValue),
  1215  			[]subtest{
  1216  				{
  1217  					"wrong type",
  1218  					wrong,
  1219  					nil,
  1220  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.ObjectID},
  1221  					bsonrwtest.Nothing,
  1222  					ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}, Received: reflect.ValueOf(wrong)},
  1223  				},
  1224  				{
  1225  					"type not double/int32/int64",
  1226  					json.Number(""),
  1227  					nil,
  1228  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  1229  					bsonrwtest.Nothing,
  1230  					fmt.Errorf("cannot decode %v into a json.Number", bsontype.String),
  1231  				},
  1232  				{
  1233  					"ReadDouble Error",
  1234  					json.Number(""),
  1235  					nil,
  1236  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Err: errors.New("rd error"), ErrAfter: bsonrwtest.ReadDouble},
  1237  					bsonrwtest.ReadDouble,
  1238  					errors.New("rd error"),
  1239  				},
  1240  				{
  1241  					"ReadInt32 Error",
  1242  					json.Number(""),
  1243  					nil,
  1244  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Err: errors.New("ri32 error"), ErrAfter: bsonrwtest.ReadInt32},
  1245  					bsonrwtest.ReadInt32,
  1246  					errors.New("ri32 error"),
  1247  				},
  1248  				{
  1249  					"ReadInt64 Error",
  1250  					json.Number(""),
  1251  					nil,
  1252  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Err: errors.New("ri64 error"), ErrAfter: bsonrwtest.ReadInt64},
  1253  					bsonrwtest.ReadInt64,
  1254  					errors.New("ri64 error"),
  1255  				},
  1256  				{
  1257  					"can set false",
  1258  					cansettest,
  1259  					nil,
  1260  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.ObjectID, Return: primitive.ObjectID{}},
  1261  					bsonrwtest.Nothing,
  1262  					ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}},
  1263  				},
  1264  				{
  1265  					"success/double",
  1266  					json.Number("3.14159"),
  1267  					nil,
  1268  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)},
  1269  					bsonrwtest.ReadDouble,
  1270  					nil,
  1271  				},
  1272  				{
  1273  					"success/int32",
  1274  					json.Number("12345"),
  1275  					nil,
  1276  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32, Return: int32(12345)},
  1277  					bsonrwtest.ReadInt32,
  1278  					nil,
  1279  				},
  1280  				{
  1281  					"success/int64",
  1282  					json.Number("1234567890"),
  1283  					nil,
  1284  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int64, Return: int64(1234567890)},
  1285  					bsonrwtest.ReadInt64,
  1286  					nil,
  1287  				},
  1288  				{
  1289  					"decode null",
  1290  					json.Number(""),
  1291  					nil,
  1292  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1293  					bsonrwtest.ReadNull,
  1294  					nil,
  1295  				},
  1296  				{
  1297  					"decode undefined",
  1298  					json.Number(""),
  1299  					nil,
  1300  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1301  					bsonrwtest.ReadUndefined,
  1302  					nil,
  1303  				},
  1304  			},
  1305  		},
  1306  		{
  1307  			"URLDecodeValue",
  1308  			ValueDecoderFunc(dvd.URLDecodeValue),
  1309  			[]subtest{
  1310  				{
  1311  					"wrong type",
  1312  					url.URL{},
  1313  					nil,
  1314  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32},
  1315  					bsonrwtest.Nothing,
  1316  					fmt.Errorf("cannot decode %v into a *url.URL", bsontype.Int32),
  1317  				},
  1318  				{
  1319  					"type not *url.URL",
  1320  					int64(0),
  1321  					nil,
  1322  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: "http://example.com"},
  1323  					bsonrwtest.Nothing,
  1324  					ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}, Received: reflect.ValueOf(int64(0))},
  1325  				},
  1326  				{
  1327  					"ReadString error",
  1328  					url.URL{},
  1329  					nil,
  1330  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Err: errors.New("rs error"), ErrAfter: bsonrwtest.ReadString},
  1331  					bsonrwtest.ReadString,
  1332  					errors.New("rs error"),
  1333  				},
  1334  				{
  1335  					"url.Parse error",
  1336  					url.URL{},
  1337  					nil,
  1338  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: "not-valid-%%%%://"},
  1339  					bsonrwtest.ReadString,
  1340  					&url.Error{
  1341  						Op:  "parse",
  1342  						URL: "not-valid-%%%%://",
  1343  						Err: errors.New("first path segment in URL cannot contain colon"),
  1344  					},
  1345  				},
  1346  				{
  1347  					"can set false",
  1348  					cansettest,
  1349  					nil,
  1350  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: "http://example.com"},
  1351  					bsonrwtest.Nothing,
  1352  					ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}},
  1353  				},
  1354  				{
  1355  					"url.URL",
  1356  					url.URL{Scheme: "http", Host: "example.com"},
  1357  					nil,
  1358  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: "http://example.com"},
  1359  					bsonrwtest.ReadString,
  1360  					nil,
  1361  				},
  1362  				{
  1363  					"decode null",
  1364  					url.URL{},
  1365  					nil,
  1366  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1367  					bsonrwtest.ReadNull,
  1368  					nil,
  1369  				},
  1370  				{
  1371  					"decode undefined",
  1372  					url.URL{},
  1373  					nil,
  1374  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1375  					bsonrwtest.ReadUndefined,
  1376  					nil,
  1377  				},
  1378  			},
  1379  		},
  1380  		{
  1381  			"defaultByteSliceCodec.DecodeValue",
  1382  			defaultByteSliceCodec,
  1383  			[]subtest{
  1384  				{
  1385  					"wrong type",
  1386  					[]byte{},
  1387  					nil,
  1388  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32},
  1389  					bsonrwtest.Nothing,
  1390  					fmt.Errorf("cannot decode %v into a []byte", bsontype.Int32),
  1391  				},
  1392  				{
  1393  					"type not []byte",
  1394  					int64(0),
  1395  					nil,
  1396  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Binary, Return: bsoncore.Value{Type: bsontype.Binary}},
  1397  					bsonrwtest.Nothing,
  1398  					ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: reflect.ValueOf(int64(0))},
  1399  				},
  1400  				{
  1401  					"ReadBinary error",
  1402  					[]byte{},
  1403  					nil,
  1404  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Binary, Err: errors.New("rb error"), ErrAfter: bsonrwtest.ReadBinary},
  1405  					bsonrwtest.ReadBinary,
  1406  					errors.New("rb error"),
  1407  				},
  1408  				{
  1409  					"incorrect subtype",
  1410  					[]byte{},
  1411  					nil,
  1412  					&bsonrwtest.ValueReaderWriter{
  1413  						BSONType: bsontype.Binary,
  1414  						Return: bsoncore.Value{
  1415  							Type: bsontype.Binary,
  1416  							Data: bsoncore.AppendBinary(nil, 0xFF, []byte{0x01, 0x02, 0x03}),
  1417  						},
  1418  					},
  1419  					bsonrwtest.ReadBinary,
  1420  					decodeBinaryError{subtype: byte(0xFF), typeName: "[]byte"},
  1421  				},
  1422  				{
  1423  					"can set false",
  1424  					cansettest,
  1425  					nil,
  1426  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Binary, Return: bsoncore.AppendBinary(nil, 0x00, []byte{0x01, 0x02, 0x03})},
  1427  					bsonrwtest.Nothing,
  1428  					ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}},
  1429  				},
  1430  				{
  1431  					"decode null",
  1432  					([]byte)(nil),
  1433  					nil,
  1434  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1435  					bsonrwtest.ReadNull,
  1436  					nil,
  1437  				},
  1438  				{
  1439  					"decode undefined",
  1440  					([]byte)(nil),
  1441  					nil,
  1442  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1443  					bsonrwtest.ReadUndefined,
  1444  					nil,
  1445  				},
  1446  			},
  1447  		},
  1448  		{
  1449  			"defaultStringCodec.DecodeValue",
  1450  			defaultStringCodec,
  1451  			[]subtest{
  1452  				{
  1453  					"symbol",
  1454  					"var hello = 'world';",
  1455  					nil,
  1456  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Symbol, Return: "var hello = 'world';"},
  1457  					bsonrwtest.ReadSymbol,
  1458  					nil,
  1459  				},
  1460  				{
  1461  					"decode null",
  1462  					"",
  1463  					nil,
  1464  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1465  					bsonrwtest.ReadNull,
  1466  					nil,
  1467  				},
  1468  				{
  1469  					"decode undefined",
  1470  					"",
  1471  					nil,
  1472  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1473  					bsonrwtest.ReadUndefined,
  1474  					nil,
  1475  				},
  1476  			},
  1477  		},
  1478  		{
  1479  			"ValueUnmarshalerDecodeValue",
  1480  			ValueDecoderFunc(dvd.ValueUnmarshalerDecodeValue),
  1481  			[]subtest{
  1482  				{
  1483  					"wrong type",
  1484  					wrong,
  1485  					nil,
  1486  					nil,
  1487  					bsonrwtest.Nothing,
  1488  					ValueDecoderError{
  1489  						Name:     "ValueUnmarshalerDecodeValue",
  1490  						Types:    []reflect.Type{tValueUnmarshaler},
  1491  						Received: reflect.ValueOf(wrong),
  1492  					},
  1493  				},
  1494  				{
  1495  					"copy error",
  1496  					&testValueUnmarshaler{},
  1497  					nil,
  1498  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Err: errors.New("copy error"), ErrAfter: bsonrwtest.ReadString},
  1499  					bsonrwtest.ReadString,
  1500  					errors.New("copy error"),
  1501  				},
  1502  				{
  1503  					"ValueUnmarshaler",
  1504  					&testValueUnmarshaler{t: bsontype.String, val: bsoncore.AppendString(nil, "hello, world")},
  1505  					nil,
  1506  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: "hello, world"},
  1507  					bsonrwtest.ReadString,
  1508  					nil,
  1509  				},
  1510  			},
  1511  		},
  1512  		{
  1513  			"UnmarshalerDecodeValue",
  1514  			ValueDecoderFunc(dvd.UnmarshalerDecodeValue),
  1515  			[]subtest{
  1516  				{
  1517  					"wrong type",
  1518  					wrong,
  1519  					nil,
  1520  					nil,
  1521  					bsonrwtest.Nothing,
  1522  					ValueDecoderError{Name: "UnmarshalerDecodeValue", Types: []reflect.Type{tUnmarshaler}, Received: reflect.ValueOf(wrong)},
  1523  				},
  1524  				{
  1525  					"copy error",
  1526  					&testUnmarshaler{},
  1527  					nil,
  1528  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Err: errors.New("copy error"), ErrAfter: bsonrwtest.ReadString},
  1529  					bsonrwtest.ReadString,
  1530  					errors.New("copy error"),
  1531  				},
  1532  				{
  1533  					// Only the pointer form of testUnmarshaler implements Unmarshaler
  1534  					"value does not implement Unmarshaler",
  1535  					testUnmarshaler{Val: bsoncore.AppendDouble(nil, 3.14159)},
  1536  					nil,
  1537  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)},
  1538  					bsonrwtest.ReadDouble,
  1539  					nil,
  1540  				},
  1541  				{
  1542  					"Unmarshaler",
  1543  					&testUnmarshaler{Val: bsoncore.AppendDouble(nil, 3.14159)},
  1544  					nil,
  1545  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double, Return: float64(3.14159)},
  1546  					bsonrwtest.ReadDouble,
  1547  					nil,
  1548  				},
  1549  			},
  1550  		},
  1551  		{
  1552  			"PointerCodec.DecodeValue",
  1553  			NewPointerCodec(),
  1554  			[]subtest{
  1555  				{
  1556  					"not valid", nil, nil, nil, bsonrwtest.Nothing,
  1557  					ValueDecoderError{Name: "PointerCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Ptr}, Received: reflect.Value{}},
  1558  				},
  1559  				{
  1560  					"can set", cansettest, nil, nil, bsonrwtest.Nothing,
  1561  					ValueDecoderError{Name: "PointerCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Ptr}},
  1562  				},
  1563  				{
  1564  					"No Decoder", &wrong, &DecodeContext{Registry: buildDefaultRegistry()}, nil, bsonrwtest.Nothing,
  1565  					ErrNoDecoder{Type: reflect.TypeOf(wrong)},
  1566  				},
  1567  				{
  1568  					"decode null",
  1569  					(*mystruct)(nil),
  1570  					nil,
  1571  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1572  					bsonrwtest.ReadNull,
  1573  					nil,
  1574  				},
  1575  				{
  1576  					"decode undefined",
  1577  					(*mystruct)(nil),
  1578  					nil,
  1579  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1580  					bsonrwtest.ReadUndefined,
  1581  					nil,
  1582  				},
  1583  			},
  1584  		},
  1585  		{
  1586  			"BinaryDecodeValue",
  1587  			ValueDecoderFunc(dvd.BinaryDecodeValue),
  1588  			[]subtest{
  1589  				{
  1590  					"wrong type",
  1591  					wrong,
  1592  					nil,
  1593  					&bsonrwtest.ValueReaderWriter{},
  1594  					bsonrwtest.Nothing,
  1595  					ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tBinary}, Received: reflect.ValueOf(wrong)},
  1596  				},
  1597  				{
  1598  					"type not binary",
  1599  					primitive.Binary{},
  1600  					nil,
  1601  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  1602  					bsonrwtest.Nothing,
  1603  					fmt.Errorf("cannot decode %v into a Binary", bsontype.String),
  1604  				},
  1605  				{
  1606  					"ReadBinary Error",
  1607  					primitive.Binary{},
  1608  					nil,
  1609  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Binary, Err: errors.New("rb error"), ErrAfter: bsonrwtest.ReadBinary},
  1610  					bsonrwtest.ReadBinary,
  1611  					errors.New("rb error"),
  1612  				},
  1613  				{
  1614  					"Binary/success",
  1615  					primitive.Binary{Data: []byte{0x01, 0x02, 0x03}, Subtype: 0xFF},
  1616  					nil,
  1617  					&bsonrwtest.ValueReaderWriter{
  1618  						BSONType: bsontype.Binary,
  1619  						Return: bsoncore.Value{
  1620  							Type: bsontype.Binary,
  1621  							Data: bsoncore.AppendBinary(nil, 0xFF, []byte{0x01, 0x02, 0x03}),
  1622  						},
  1623  					},
  1624  					bsonrwtest.ReadBinary,
  1625  					nil,
  1626  				},
  1627  				{
  1628  					"decode null",
  1629  					primitive.Binary{},
  1630  					nil,
  1631  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1632  					bsonrwtest.ReadNull,
  1633  					nil,
  1634  				},
  1635  				{
  1636  					"decode undefined",
  1637  					primitive.Binary{},
  1638  					nil,
  1639  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1640  					bsonrwtest.ReadUndefined,
  1641  					nil,
  1642  				},
  1643  			},
  1644  		},
  1645  		{
  1646  			"UndefinedDecodeValue",
  1647  			ValueDecoderFunc(dvd.UndefinedDecodeValue),
  1648  			[]subtest{
  1649  				{
  1650  					"wrong type",
  1651  					wrong,
  1652  					nil,
  1653  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1654  					bsonrwtest.Nothing,
  1655  					ValueDecoderError{Name: "UndefinedDecodeValue", Types: []reflect.Type{tUndefined}, Received: reflect.ValueOf(wrong)},
  1656  				},
  1657  				{
  1658  					"type not undefined",
  1659  					primitive.Undefined{},
  1660  					nil,
  1661  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  1662  					bsonrwtest.Nothing,
  1663  					fmt.Errorf("cannot decode %v into an Undefined", bsontype.String),
  1664  				},
  1665  				{
  1666  					"ReadUndefined Error",
  1667  					primitive.Undefined{},
  1668  					nil,
  1669  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined, Err: errors.New("ru error"), ErrAfter: bsonrwtest.ReadUndefined},
  1670  					bsonrwtest.ReadUndefined,
  1671  					errors.New("ru error"),
  1672  				},
  1673  				{
  1674  					"ReadUndefined/success",
  1675  					primitive.Undefined{},
  1676  					nil,
  1677  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1678  					bsonrwtest.ReadUndefined,
  1679  					nil,
  1680  				},
  1681  				{
  1682  					"decode null",
  1683  					primitive.Undefined{},
  1684  					nil,
  1685  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1686  					bsonrwtest.ReadNull,
  1687  					nil,
  1688  				},
  1689  			},
  1690  		},
  1691  		{
  1692  			"DateTimeDecodeValue",
  1693  			ValueDecoderFunc(dvd.DateTimeDecodeValue),
  1694  			[]subtest{
  1695  				{
  1696  					"wrong type",
  1697  					wrong,
  1698  					nil,
  1699  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime},
  1700  					bsonrwtest.Nothing,
  1701  					ValueDecoderError{Name: "DateTimeDecodeValue", Types: []reflect.Type{tDateTime}, Received: reflect.ValueOf(wrong)},
  1702  				},
  1703  				{
  1704  					"type not datetime",
  1705  					primitive.DateTime(0),
  1706  					nil,
  1707  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  1708  					bsonrwtest.Nothing,
  1709  					fmt.Errorf("cannot decode %v into a DateTime", bsontype.String),
  1710  				},
  1711  				{
  1712  					"ReadDateTime Error",
  1713  					primitive.DateTime(0),
  1714  					nil,
  1715  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Err: errors.New("rdt error"), ErrAfter: bsonrwtest.ReadDateTime},
  1716  					bsonrwtest.ReadDateTime,
  1717  					errors.New("rdt error"),
  1718  				},
  1719  				{
  1720  					"success",
  1721  					primitive.DateTime(1234567890),
  1722  					nil,
  1723  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.DateTime, Return: int64(1234567890)},
  1724  					bsonrwtest.ReadDateTime,
  1725  					nil,
  1726  				},
  1727  				{
  1728  					"decode null",
  1729  					primitive.DateTime(0),
  1730  					nil,
  1731  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1732  					bsonrwtest.ReadNull,
  1733  					nil,
  1734  				},
  1735  				{
  1736  					"decode undefined",
  1737  					primitive.DateTime(0),
  1738  					nil,
  1739  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1740  					bsonrwtest.ReadUndefined,
  1741  					nil,
  1742  				},
  1743  			},
  1744  		},
  1745  		{
  1746  			"NullDecodeValue",
  1747  			ValueDecoderFunc(dvd.NullDecodeValue),
  1748  			[]subtest{
  1749  				{
  1750  					"wrong type",
  1751  					wrong,
  1752  					nil,
  1753  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1754  					bsonrwtest.Nothing,
  1755  					ValueDecoderError{Name: "NullDecodeValue", Types: []reflect.Type{tNull}, Received: reflect.ValueOf(wrong)},
  1756  				},
  1757  				{
  1758  					"type not null",
  1759  					primitive.Null{},
  1760  					nil,
  1761  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  1762  					bsonrwtest.Nothing,
  1763  					fmt.Errorf("cannot decode %v into a Null", bsontype.String),
  1764  				},
  1765  				{
  1766  					"ReadNull Error",
  1767  					primitive.Null{},
  1768  					nil,
  1769  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null, Err: errors.New("rn error"), ErrAfter: bsonrwtest.ReadNull},
  1770  					bsonrwtest.ReadNull,
  1771  					errors.New("rn error"),
  1772  				},
  1773  				{
  1774  					"success",
  1775  					primitive.Null{},
  1776  					nil,
  1777  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1778  					bsonrwtest.ReadNull,
  1779  					nil,
  1780  				},
  1781  			},
  1782  		},
  1783  		{
  1784  			"RegexDecodeValue",
  1785  			ValueDecoderFunc(dvd.RegexDecodeValue),
  1786  			[]subtest{
  1787  				{
  1788  					"wrong type",
  1789  					wrong,
  1790  					nil,
  1791  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Regex},
  1792  					bsonrwtest.Nothing,
  1793  					ValueDecoderError{Name: "RegexDecodeValue", Types: []reflect.Type{tRegex}, Received: reflect.ValueOf(wrong)},
  1794  				},
  1795  				{
  1796  					"type not regex",
  1797  					primitive.Regex{},
  1798  					nil,
  1799  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  1800  					bsonrwtest.Nothing,
  1801  					fmt.Errorf("cannot decode %v into a Regex", bsontype.String),
  1802  				},
  1803  				{
  1804  					"ReadRegex Error",
  1805  					primitive.Regex{},
  1806  					nil,
  1807  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Regex, Err: errors.New("rr error"), ErrAfter: bsonrwtest.ReadRegex},
  1808  					bsonrwtest.ReadRegex,
  1809  					errors.New("rr error"),
  1810  				},
  1811  				{
  1812  					"success",
  1813  					primitive.Regex{Pattern: "foo", Options: "bar"},
  1814  					nil,
  1815  					&bsonrwtest.ValueReaderWriter{
  1816  						BSONType: bsontype.Regex,
  1817  						Return: bsoncore.Value{
  1818  							Type: bsontype.Regex,
  1819  							Data: bsoncore.AppendRegex(nil, "foo", "bar"),
  1820  						},
  1821  					},
  1822  					bsonrwtest.ReadRegex,
  1823  					nil,
  1824  				},
  1825  				{
  1826  					"decode null",
  1827  					primitive.Regex{},
  1828  					nil,
  1829  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1830  					bsonrwtest.ReadNull,
  1831  					nil,
  1832  				},
  1833  				{
  1834  					"decode undefined",
  1835  					primitive.Regex{},
  1836  					nil,
  1837  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1838  					bsonrwtest.ReadUndefined,
  1839  					nil,
  1840  				},
  1841  			},
  1842  		},
  1843  		{
  1844  			"DBPointerDecodeValue",
  1845  			ValueDecoderFunc(dvd.DBPointerDecodeValue),
  1846  			[]subtest{
  1847  				{
  1848  					"wrong type",
  1849  					wrong,
  1850  					nil,
  1851  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.DBPointer},
  1852  					bsonrwtest.Nothing,
  1853  					ValueDecoderError{Name: "DBPointerDecodeValue", Types: []reflect.Type{tDBPointer}, Received: reflect.ValueOf(wrong)},
  1854  				},
  1855  				{
  1856  					"type not dbpointer",
  1857  					primitive.DBPointer{},
  1858  					nil,
  1859  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  1860  					bsonrwtest.Nothing,
  1861  					fmt.Errorf("cannot decode %v into a DBPointer", bsontype.String),
  1862  				},
  1863  				{
  1864  					"ReadDBPointer Error",
  1865  					primitive.DBPointer{},
  1866  					nil,
  1867  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.DBPointer, Err: errors.New("rdbp error"), ErrAfter: bsonrwtest.ReadDBPointer},
  1868  					bsonrwtest.ReadDBPointer,
  1869  					errors.New("rdbp error"),
  1870  				},
  1871  				{
  1872  					"success",
  1873  					primitive.DBPointer{
  1874  						DB:      "foobar",
  1875  						Pointer: primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
  1876  					},
  1877  					nil,
  1878  					&bsonrwtest.ValueReaderWriter{
  1879  						BSONType: bsontype.DBPointer,
  1880  						Return: bsoncore.Value{
  1881  							Type: bsontype.DBPointer,
  1882  							Data: bsoncore.AppendDBPointer(
  1883  								nil, "foobar", primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
  1884  							),
  1885  						},
  1886  					},
  1887  					bsonrwtest.ReadDBPointer,
  1888  					nil,
  1889  				},
  1890  				{
  1891  					"decode null",
  1892  					primitive.DBPointer{},
  1893  					nil,
  1894  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1895  					bsonrwtest.ReadNull,
  1896  					nil,
  1897  				},
  1898  				{
  1899  					"decode undefined",
  1900  					primitive.DBPointer{},
  1901  					nil,
  1902  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1903  					bsonrwtest.ReadUndefined,
  1904  					nil,
  1905  				},
  1906  			},
  1907  		},
  1908  		{
  1909  			"TimestampDecodeValue",
  1910  			ValueDecoderFunc(dvd.TimestampDecodeValue),
  1911  			[]subtest{
  1912  				{
  1913  					"wrong type",
  1914  					wrong,
  1915  					nil,
  1916  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Timestamp},
  1917  					bsonrwtest.Nothing,
  1918  					ValueDecoderError{Name: "TimestampDecodeValue", Types: []reflect.Type{tTimestamp}, Received: reflect.ValueOf(wrong)},
  1919  				},
  1920  				{
  1921  					"type not timestamp",
  1922  					primitive.Timestamp{},
  1923  					nil,
  1924  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  1925  					bsonrwtest.Nothing,
  1926  					fmt.Errorf("cannot decode %v into a Timestamp", bsontype.String),
  1927  				},
  1928  				{
  1929  					"ReadTimestamp Error",
  1930  					primitive.Timestamp{},
  1931  					nil,
  1932  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Timestamp, Err: errors.New("rt error"), ErrAfter: bsonrwtest.ReadTimestamp},
  1933  					bsonrwtest.ReadTimestamp,
  1934  					errors.New("rt error"),
  1935  				},
  1936  				{
  1937  					"success",
  1938  					primitive.Timestamp{T: 12345, I: 67890},
  1939  					nil,
  1940  					&bsonrwtest.ValueReaderWriter{
  1941  						BSONType: bsontype.Timestamp,
  1942  						Return: bsoncore.Value{
  1943  							Type: bsontype.Timestamp,
  1944  							Data: bsoncore.AppendTimestamp(nil, 12345, 67890),
  1945  						},
  1946  					},
  1947  					bsonrwtest.ReadTimestamp,
  1948  					nil,
  1949  				},
  1950  				{
  1951  					"decode null",
  1952  					primitive.Timestamp{},
  1953  					nil,
  1954  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  1955  					bsonrwtest.ReadNull,
  1956  					nil,
  1957  				},
  1958  				{
  1959  					"decode undefined",
  1960  					primitive.Timestamp{},
  1961  					nil,
  1962  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  1963  					bsonrwtest.ReadUndefined,
  1964  					nil,
  1965  				},
  1966  			},
  1967  		},
  1968  		{
  1969  			"MinKeyDecodeValue",
  1970  			ValueDecoderFunc(dvd.MinKeyDecodeValue),
  1971  			[]subtest{
  1972  				{
  1973  					"wrong type",
  1974  					wrong,
  1975  					nil,
  1976  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.MinKey},
  1977  					bsonrwtest.Nothing,
  1978  					ValueDecoderError{Name: "MinKeyDecodeValue", Types: []reflect.Type{tMinKey}, Received: reflect.ValueOf(wrong)},
  1979  				},
  1980  				{
  1981  					"type not null",
  1982  					primitive.MinKey{},
  1983  					nil,
  1984  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  1985  					bsonrwtest.Nothing,
  1986  					fmt.Errorf("cannot decode %v into a MinKey", bsontype.String),
  1987  				},
  1988  				{
  1989  					"ReadMinKey Error",
  1990  					primitive.MinKey{},
  1991  					nil,
  1992  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.MinKey, Err: errors.New("rn error"), ErrAfter: bsonrwtest.ReadMinKey},
  1993  					bsonrwtest.ReadMinKey,
  1994  					errors.New("rn error"),
  1995  				},
  1996  				{
  1997  					"success",
  1998  					primitive.MinKey{},
  1999  					nil,
  2000  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.MinKey},
  2001  					bsonrwtest.ReadMinKey,
  2002  					nil,
  2003  				},
  2004  				{
  2005  					"decode null",
  2006  					primitive.MinKey{},
  2007  					nil,
  2008  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  2009  					bsonrwtest.ReadNull,
  2010  					nil,
  2011  				},
  2012  				{
  2013  					"decode undefined",
  2014  					primitive.MinKey{},
  2015  					nil,
  2016  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  2017  					bsonrwtest.ReadUndefined,
  2018  					nil,
  2019  				},
  2020  			},
  2021  		},
  2022  		{
  2023  			"MaxKeyDecodeValue",
  2024  			ValueDecoderFunc(dvd.MaxKeyDecodeValue),
  2025  			[]subtest{
  2026  				{
  2027  					"wrong type",
  2028  					wrong,
  2029  					nil,
  2030  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.MaxKey},
  2031  					bsonrwtest.Nothing,
  2032  					ValueDecoderError{Name: "MaxKeyDecodeValue", Types: []reflect.Type{tMaxKey}, Received: reflect.ValueOf(wrong)},
  2033  				},
  2034  				{
  2035  					"type not null",
  2036  					primitive.MaxKey{},
  2037  					nil,
  2038  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  2039  					bsonrwtest.Nothing,
  2040  					fmt.Errorf("cannot decode %v into a MaxKey", bsontype.String),
  2041  				},
  2042  				{
  2043  					"ReadMaxKey Error",
  2044  					primitive.MaxKey{},
  2045  					nil,
  2046  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.MaxKey, Err: errors.New("rn error"), ErrAfter: bsonrwtest.ReadMaxKey},
  2047  					bsonrwtest.ReadMaxKey,
  2048  					errors.New("rn error"),
  2049  				},
  2050  				{
  2051  					"success",
  2052  					primitive.MaxKey{},
  2053  					nil,
  2054  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.MaxKey},
  2055  					bsonrwtest.ReadMaxKey,
  2056  					nil,
  2057  				},
  2058  				{
  2059  					"decode null",
  2060  					primitive.MaxKey{},
  2061  					nil,
  2062  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  2063  					bsonrwtest.ReadNull,
  2064  					nil,
  2065  				},
  2066  				{
  2067  					"decode undefined",
  2068  					primitive.MaxKey{},
  2069  					nil,
  2070  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  2071  					bsonrwtest.ReadUndefined,
  2072  					nil,
  2073  				},
  2074  			},
  2075  		},
  2076  		{
  2077  			"JavaScriptDecodeValue",
  2078  			ValueDecoderFunc(dvd.JavaScriptDecodeValue),
  2079  			[]subtest{
  2080  				{
  2081  					"wrong type",
  2082  					wrong,
  2083  					nil,
  2084  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.JavaScript, Return: ""},
  2085  					bsonrwtest.Nothing,
  2086  					ValueDecoderError{Name: "JavaScriptDecodeValue", Types: []reflect.Type{tJavaScript}, Received: reflect.ValueOf(wrong)},
  2087  				},
  2088  				{
  2089  					"type not Javascript",
  2090  					primitive.JavaScript(""),
  2091  					nil,
  2092  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  2093  					bsonrwtest.Nothing,
  2094  					fmt.Errorf("cannot decode %v into a primitive.JavaScript", bsontype.String),
  2095  				},
  2096  				{
  2097  					"ReadJavascript Error",
  2098  					primitive.JavaScript(""),
  2099  					nil,
  2100  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.JavaScript, Err: errors.New("rjs error"), ErrAfter: bsonrwtest.ReadJavascript},
  2101  					bsonrwtest.ReadJavascript,
  2102  					errors.New("rjs error"),
  2103  				},
  2104  				{
  2105  					"JavaScript/success",
  2106  					primitive.JavaScript("var hello = 'world';"),
  2107  					nil,
  2108  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.JavaScript, Return: "var hello = 'world';"},
  2109  					bsonrwtest.ReadJavascript,
  2110  					nil,
  2111  				},
  2112  				{
  2113  					"decode null",
  2114  					primitive.JavaScript(""),
  2115  					nil,
  2116  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  2117  					bsonrwtest.ReadNull,
  2118  					nil,
  2119  				},
  2120  				{
  2121  					"decode undefined",
  2122  					primitive.JavaScript(""),
  2123  					nil,
  2124  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  2125  					bsonrwtest.ReadUndefined,
  2126  					nil,
  2127  				},
  2128  			},
  2129  		},
  2130  		{
  2131  			"SymbolDecodeValue",
  2132  			ValueDecoderFunc(dvd.SymbolDecodeValue),
  2133  			[]subtest{
  2134  				{
  2135  					"wrong type",
  2136  					wrong,
  2137  					nil,
  2138  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Symbol, Return: ""},
  2139  					bsonrwtest.Nothing,
  2140  					ValueDecoderError{Name: "SymbolDecodeValue", Types: []reflect.Type{tSymbol}, Received: reflect.ValueOf(wrong)},
  2141  				},
  2142  				{
  2143  					"type not Symbol",
  2144  					primitive.Symbol(""),
  2145  					nil,
  2146  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Int32},
  2147  					bsonrwtest.Nothing,
  2148  					fmt.Errorf("cannot decode %v into a primitive.Symbol", bsontype.Int32),
  2149  				},
  2150  				{
  2151  					"ReadSymbol Error",
  2152  					primitive.Symbol(""),
  2153  					nil,
  2154  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Symbol, Err: errors.New("rjs error"), ErrAfter: bsonrwtest.ReadSymbol},
  2155  					bsonrwtest.ReadSymbol,
  2156  					errors.New("rjs error"),
  2157  				},
  2158  				{
  2159  					"Symbol/success",
  2160  					primitive.Symbol("var hello = 'world';"),
  2161  					nil,
  2162  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Symbol, Return: "var hello = 'world';"},
  2163  					bsonrwtest.ReadSymbol,
  2164  					nil,
  2165  				},
  2166  				{
  2167  					"decode null",
  2168  					primitive.Symbol(""),
  2169  					nil,
  2170  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  2171  					bsonrwtest.ReadNull,
  2172  					nil,
  2173  				},
  2174  				{
  2175  					"decode undefined",
  2176  					primitive.Symbol(""),
  2177  					nil,
  2178  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  2179  					bsonrwtest.ReadUndefined,
  2180  					nil,
  2181  				},
  2182  			},
  2183  		},
  2184  		{
  2185  			"CoreDocumentDecodeValue",
  2186  			ValueDecoderFunc(dvd.CoreDocumentDecodeValue),
  2187  			[]subtest{
  2188  				{
  2189  					"wrong type",
  2190  					wrong,
  2191  					nil,
  2192  					&bsonrwtest.ValueReaderWriter{},
  2193  					bsonrwtest.Nothing,
  2194  					ValueDecoderError{
  2195  						Name:     "CoreDocumentDecodeValue",
  2196  						Types:    []reflect.Type{tCoreDocument},
  2197  						Received: reflect.ValueOf(wrong),
  2198  					},
  2199  				},
  2200  				{
  2201  					"*bsoncore.Document is nil",
  2202  					(*bsoncore.Document)(nil),
  2203  					nil,
  2204  					nil,
  2205  					bsonrwtest.Nothing,
  2206  					ValueDecoderError{
  2207  						Name:     "CoreDocumentDecodeValue",
  2208  						Types:    []reflect.Type{tCoreDocument},
  2209  						Received: reflect.ValueOf((*bsoncore.Document)(nil)),
  2210  					},
  2211  				},
  2212  				{
  2213  					"Copy error",
  2214  					bsoncore.Document{},
  2215  					nil,
  2216  					&bsonrwtest.ValueReaderWriter{Err: errors.New("copy error"), ErrAfter: bsonrwtest.ReadDocument},
  2217  					bsonrwtest.ReadDocument,
  2218  					errors.New("copy error"),
  2219  				},
  2220  			},
  2221  		},
  2222  		{
  2223  			"StructCodec.DecodeValue",
  2224  			defaultTestStructCodec,
  2225  			[]subtest{
  2226  				{
  2227  					"Not struct",
  2228  					reflect.New(reflect.TypeOf(struct{ Foo string }{})).Elem().Interface(),
  2229  					nil,
  2230  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  2231  					bsonrwtest.Nothing,
  2232  					errors.New("cannot decode string into a struct { Foo string }"),
  2233  				},
  2234  				{
  2235  					"decode null",
  2236  					reflect.New(reflect.TypeOf(struct{ Foo string }{})).Elem().Interface(),
  2237  					nil,
  2238  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  2239  					bsonrwtest.ReadNull,
  2240  					nil,
  2241  				},
  2242  				{
  2243  					"decode undefined",
  2244  					reflect.New(reflect.TypeOf(struct{ Foo string }{})).Elem().Interface(),
  2245  					nil,
  2246  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  2247  					bsonrwtest.ReadUndefined,
  2248  					nil,
  2249  				},
  2250  			},
  2251  		},
  2252  		{
  2253  			"CodeWithScopeDecodeValue",
  2254  			ValueDecoderFunc(dvd.CodeWithScopeDecodeValue),
  2255  			[]subtest{
  2256  				{
  2257  					"wrong type",
  2258  					wrong,
  2259  					nil,
  2260  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.CodeWithScope},
  2261  					bsonrwtest.Nothing,
  2262  					ValueDecoderError{
  2263  						Name:     "CodeWithScopeDecodeValue",
  2264  						Types:    []reflect.Type{tCodeWithScope},
  2265  						Received: reflect.ValueOf(wrong),
  2266  					},
  2267  				},
  2268  				{
  2269  					"type not codewithscope",
  2270  					primitive.CodeWithScope{},
  2271  					nil,
  2272  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.String},
  2273  					bsonrwtest.Nothing,
  2274  					fmt.Errorf("cannot decode %v into a primitive.CodeWithScope", bsontype.String),
  2275  				},
  2276  				{
  2277  					"ReadCodeWithScope Error",
  2278  					primitive.CodeWithScope{},
  2279  					nil,
  2280  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.CodeWithScope, Err: errors.New("rcws error"), ErrAfter: bsonrwtest.ReadCodeWithScope},
  2281  					bsonrwtest.ReadCodeWithScope,
  2282  					errors.New("rcws error"),
  2283  				},
  2284  				{
  2285  					"decodeDocument Error",
  2286  					primitive.CodeWithScope{
  2287  						Code:  "var hello = 'world';",
  2288  						Scope: primitive.D{{"foo", nil}},
  2289  					},
  2290  					&DecodeContext{Registry: buildDefaultRegistry()},
  2291  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.CodeWithScope, Err: errors.New("dd error"), ErrAfter: bsonrwtest.ReadElement},
  2292  					bsonrwtest.ReadElement,
  2293  					errors.New("dd error"),
  2294  				},
  2295  				{
  2296  					"decode null",
  2297  					primitive.CodeWithScope{},
  2298  					nil,
  2299  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Null},
  2300  					bsonrwtest.ReadNull,
  2301  					nil,
  2302  				},
  2303  				{
  2304  					"decode undefined",
  2305  					primitive.CodeWithScope{},
  2306  					nil,
  2307  					&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Undefined},
  2308  					bsonrwtest.ReadUndefined,
  2309  					nil,
  2310  				},
  2311  			},
  2312  		},
  2313  		{
  2314  			"CoreArrayDecodeValue",
  2315  			defaultArrayCodec,
  2316  			[]subtest{
  2317  				{
  2318  					"wrong type",
  2319  					wrong,
  2320  					nil,
  2321  					&bsonrwtest.ValueReaderWriter{},
  2322  					bsonrwtest.Nothing,
  2323  					ValueDecoderError{
  2324  						Name:     "CoreArrayDecodeValue",
  2325  						Types:    []reflect.Type{tCoreArray},
  2326  						Received: reflect.ValueOf(wrong),
  2327  					},
  2328  				},
  2329  				{
  2330  					"*bsoncore.Array is nil",
  2331  					(*bsoncore.Array)(nil),
  2332  					nil,
  2333  					nil,
  2334  					bsonrwtest.Nothing,
  2335  					ValueDecoderError{
  2336  						Name:     "CoreArrayDecodeValue",
  2337  						Types:    []reflect.Type{tCoreArray},
  2338  						Received: reflect.ValueOf((*bsoncore.Array)(nil)),
  2339  					},
  2340  				},
  2341  			},
  2342  		},
  2343  	}
  2344  
  2345  	for _, tc := range testCases {
  2346  		t.Run(tc.name, func(t *testing.T) {
  2347  			for _, rc := range tc.subtests {
  2348  				t.Run(rc.name, func(t *testing.T) {
  2349  					var dc DecodeContext
  2350  					if rc.dctx != nil {
  2351  						dc = *rc.dctx
  2352  					}
  2353  					llvrw := new(bsonrwtest.ValueReaderWriter)
  2354  					if rc.llvrw != nil {
  2355  						llvrw = rc.llvrw
  2356  					}
  2357  					llvrw.T = t
  2358  					// var got interface{}
  2359  					if rc.val == cansetreflectiontest { // We're doing a CanSet reflection test
  2360  						err := tc.vd.DecodeValue(dc, llvrw, reflect.Value{})
  2361  						if !compareErrors(err, rc.err) {
  2362  							t.Errorf("Errors do not match. got %v; want %v", err, rc.err)
  2363  						}
  2364  
  2365  						val := reflect.New(reflect.TypeOf(rc.val)).Elem()
  2366  						err = tc.vd.DecodeValue(dc, llvrw, val)
  2367  						if !compareErrors(err, rc.err) {
  2368  							t.Errorf("Errors do not match. got %v; want %v", err, rc.err)
  2369  						}
  2370  						return
  2371  					}
  2372  					if rc.val == cansettest { // We're doing an IsValid and CanSet test
  2373  						var wanterr ValueDecoderError
  2374  						if !errors.As(rc.err, &wanterr) {
  2375  							t.Fatalf("Error must be a DecodeValueError, but got a %T", rc.err)
  2376  						}
  2377  
  2378  						err := tc.vd.DecodeValue(dc, llvrw, reflect.Value{})
  2379  						wanterr.Received = reflect.ValueOf(nil)
  2380  						if !compareErrors(err, wanterr) {
  2381  							t.Errorf("Errors do not match. got %v; want %v", err, wanterr)
  2382  						}
  2383  
  2384  						err = tc.vd.DecodeValue(dc, llvrw, reflect.ValueOf(int(12345)))
  2385  						wanterr.Received = reflect.ValueOf(int(12345))
  2386  						if !compareErrors(err, wanterr) {
  2387  							t.Errorf("Errors do not match. got %v; want %v", err, wanterr)
  2388  						}
  2389  						return
  2390  					}
  2391  					var val reflect.Value
  2392  					if rtype := reflect.TypeOf(rc.val); rtype != nil {
  2393  						val = reflect.New(rtype).Elem()
  2394  					}
  2395  					want := rc.val
  2396  					defer func() {
  2397  						if err := recover(); err != nil {
  2398  							fmt.Println(t.Name())
  2399  							panic(err)
  2400  						}
  2401  					}()
  2402  					err := tc.vd.DecodeValue(dc, llvrw, val)
  2403  					if !compareErrors(err, rc.err) {
  2404  						t.Errorf("Errors do not match. got %v; want %v", err, rc.err)
  2405  					}
  2406  					invoked := llvrw.Invoked
  2407  					if !cmp.Equal(invoked, rc.invoke) {
  2408  						t.Errorf("Incorrect method invoked. got %v; want %v", invoked, rc.invoke)
  2409  					}
  2410  					var got interface{}
  2411  					if val.IsValid() && val.CanInterface() {
  2412  						got = val.Interface()
  2413  					}
  2414  					if rc.err == nil && !cmp.Equal(got, want, cmp.Comparer(compareDecimal128)) {
  2415  						t.Errorf("Values do not match. got (%T)%v; want (%T)%v", got, got, want, want)
  2416  					}
  2417  				})
  2418  			}
  2419  		})
  2420  	}
  2421  
  2422  	t.Run("CodeWithScopeCodec/DecodeValue/success", func(t *testing.T) {
  2423  		dc := DecodeContext{Registry: buildDefaultRegistry()}
  2424  		b := bsoncore.BuildDocument(nil,
  2425  			bsoncore.AppendCodeWithScopeElement(
  2426  				nil, "foo", "var hello = 'world';",
  2427  				buildDocument(bsoncore.AppendNullElement(nil, "bar")),
  2428  			),
  2429  		)
  2430  		dvr := bsonrw.NewBSONDocumentReader(b)
  2431  		dr, err := dvr.ReadDocument()
  2432  		noerr(t, err)
  2433  		_, vr, err := dr.ReadElement()
  2434  		noerr(t, err)
  2435  
  2436  		want := primitive.CodeWithScope{
  2437  			Code:  "var hello = 'world';",
  2438  			Scope: primitive.D{{"bar", nil}},
  2439  		}
  2440  		val := reflect.New(tCodeWithScope).Elem()
  2441  		err = dvd.CodeWithScopeDecodeValue(dc, vr, val)
  2442  		noerr(t, err)
  2443  
  2444  		got := val.Interface().(primitive.CodeWithScope)
  2445  		if got.Code != want.Code && !cmp.Equal(got.Scope, want.Scope) {
  2446  			t.Errorf("CodeWithScopes do not match. got %v; want %v", got, want)
  2447  		}
  2448  	})
  2449  	t.Run("ValueUnmarshalerDecodeValue/UnmarshalBSONValue error", func(t *testing.T) {
  2450  		var dc DecodeContext
  2451  		llvrw := &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: string("hello, world!")}
  2452  		llvrw.T = t
  2453  
  2454  		want := errors.New("ubsonv error")
  2455  		valUnmarshaler := &testValueUnmarshaler{err: want}
  2456  		got := dvd.ValueUnmarshalerDecodeValue(dc, llvrw, reflect.ValueOf(valUnmarshaler))
  2457  		if !compareErrors(got, want) {
  2458  			t.Errorf("Errors do not match. got %v; want %v", got, want)
  2459  		}
  2460  	})
  2461  	t.Run("ValueUnmarshalerDecodeValue/Unaddressable value", func(t *testing.T) {
  2462  		var dc DecodeContext
  2463  		llvrw := &bsonrwtest.ValueReaderWriter{BSONType: bsontype.String, Return: string("hello, world!")}
  2464  		llvrw.T = t
  2465  
  2466  		val := reflect.ValueOf(testValueUnmarshaler{})
  2467  		want := ValueDecoderError{Name: "ValueUnmarshalerDecodeValue", Types: []reflect.Type{tValueUnmarshaler}, Received: val}
  2468  		got := dvd.ValueUnmarshalerDecodeValue(dc, llvrw, val)
  2469  		if !compareErrors(got, want) {
  2470  			t.Errorf("Errors do not match. got %v; want %v", got, want)
  2471  		}
  2472  	})
  2473  
  2474  	t.Run("SliceCodec/DecodeValue/can't set slice", func(t *testing.T) {
  2475  		var val []string
  2476  		want := ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: reflect.ValueOf(val)}
  2477  		got := dvd.SliceDecodeValue(DecodeContext{}, nil, reflect.ValueOf(val))
  2478  		if !compareErrors(got, want) {
  2479  			t.Errorf("Errors do not match. got %v; want %v", got, want)
  2480  		}
  2481  	})
  2482  	t.Run("SliceCodec/DecodeValue/too many elements", func(t *testing.T) {
  2483  		idx, doc := bsoncore.AppendDocumentStart(nil)
  2484  		aidx, doc := bsoncore.AppendArrayElementStart(doc, "foo")
  2485  		doc = bsoncore.AppendStringElement(doc, "0", "foo")
  2486  		doc = bsoncore.AppendStringElement(doc, "1", "bar")
  2487  		doc, err := bsoncore.AppendArrayEnd(doc, aidx)
  2488  		noerr(t, err)
  2489  		doc, err = bsoncore.AppendDocumentEnd(doc, idx)
  2490  		noerr(t, err)
  2491  		dvr := bsonrw.NewBSONDocumentReader(doc)
  2492  		noerr(t, err)
  2493  		dr, err := dvr.ReadDocument()
  2494  		noerr(t, err)
  2495  		_, vr, err := dr.ReadElement()
  2496  		noerr(t, err)
  2497  		var val [1]string
  2498  		want := fmt.Errorf("more elements returned in array than can fit inside %T, got 2 elements", val)
  2499  
  2500  		dc := DecodeContext{Registry: buildDefaultRegistry()}
  2501  		got := dvd.ArrayDecodeValue(dc, vr, reflect.ValueOf(val))
  2502  		if !compareErrors(got, want) {
  2503  			t.Errorf("Errors do not match. got %v; want %v", got, want)
  2504  		}
  2505  	})
  2506  
  2507  	t.Run("success path", func(t *testing.T) {
  2508  		oid := primitive.NewObjectID()
  2509  		oids := []primitive.ObjectID{primitive.NewObjectID(), primitive.NewObjectID(), primitive.NewObjectID()}
  2510  		var str = new(string)
  2511  		*str = "bar"
  2512  		now := time.Now().Truncate(time.Millisecond).UTC()
  2513  		murl, err := url.Parse("https://mongodb.com/random-url?hello=world")
  2514  		if err != nil {
  2515  			t.Errorf("Error parsing URL: %v", err)
  2516  			t.FailNow()
  2517  		}
  2518  		decimal128, err := primitive.ParseDecimal128("1.5e10")
  2519  		if err != nil {
  2520  			t.Errorf("Error parsing decimal128: %v", err)
  2521  			t.FailNow()
  2522  		}
  2523  
  2524  		testCases := []struct {
  2525  			name  string
  2526  			value interface{}
  2527  			b     []byte
  2528  			err   error
  2529  		}{
  2530  			{
  2531  				"map[string]int",
  2532  				map[string]int32{"foo": 1},
  2533  				[]byte{
  2534  					0x0E, 0x00, 0x00, 0x00,
  2535  					0x10, 'f', 'o', 'o', 0x00,
  2536  					0x01, 0x00, 0x00, 0x00,
  2537  					0x00,
  2538  				},
  2539  				nil,
  2540  			},
  2541  			{
  2542  				"map[string]primitive.ObjectID",
  2543  				map[string]primitive.ObjectID{"foo": oid},
  2544  				func() []byte {
  2545  					idx, doc := bsoncore.AppendDocumentStart(nil)
  2546  					doc = bsoncore.AppendObjectIDElement(doc, "foo", oid)
  2547  					doc, _ = bsoncore.AppendDocumentEnd(doc, idx)
  2548  					return doc
  2549  				}(),
  2550  				nil,
  2551  			},
  2552  			{
  2553  				"map[string][]int32",
  2554  				map[string][]int32{"Z": {1, 2, 3}},
  2555  				buildDocumentArray(func(doc []byte) []byte {
  2556  					doc = bsoncore.AppendInt32Element(doc, "0", 1)
  2557  					doc = bsoncore.AppendInt32Element(doc, "1", 2)
  2558  					return bsoncore.AppendInt32Element(doc, "2", 3)
  2559  				}),
  2560  				nil,
  2561  			},
  2562  			{
  2563  				"map[string][]primitive.ObjectID",
  2564  				map[string][]primitive.ObjectID{"Z": oids},
  2565  				buildDocumentArray(func(doc []byte) []byte {
  2566  					doc = bsoncore.AppendObjectIDElement(doc, "0", oids[0])
  2567  					doc = bsoncore.AppendObjectIDElement(doc, "1", oids[1])
  2568  					return bsoncore.AppendObjectIDElement(doc, "2", oids[2])
  2569  				}),
  2570  				nil,
  2571  			},
  2572  			{
  2573  				"map[string][]json.Number(int64)",
  2574  				map[string][]json.Number{"Z": {json.Number("5"), json.Number("10")}},
  2575  				buildDocumentArray(func(doc []byte) []byte {
  2576  					doc = bsoncore.AppendInt64Element(doc, "0", 5)
  2577  					return bsoncore.AppendInt64Element(doc, "1", 10)
  2578  				}),
  2579  				nil,
  2580  			},
  2581  			{
  2582  				"map[string][]json.Number(float64)",
  2583  				map[string][]json.Number{"Z": {json.Number("5"), json.Number("10.1")}},
  2584  				buildDocumentArray(func(doc []byte) []byte {
  2585  					doc = bsoncore.AppendInt64Element(doc, "0", 5)
  2586  					return bsoncore.AppendDoubleElement(doc, "1", 10.1)
  2587  				}),
  2588  				nil,
  2589  			},
  2590  			{
  2591  				"map[string][]*url.URL",
  2592  				map[string][]*url.URL{"Z": {murl}},
  2593  				buildDocumentArray(func(doc []byte) []byte {
  2594  					return bsoncore.AppendStringElement(doc, "0", murl.String())
  2595  				}),
  2596  				nil,
  2597  			},
  2598  			{
  2599  				"map[string][]primitive.Decimal128",
  2600  				map[string][]primitive.Decimal128{"Z": {decimal128}},
  2601  				buildDocumentArray(func(doc []byte) []byte {
  2602  					return bsoncore.AppendDecimal128Element(doc, "0", decimal128)
  2603  				}),
  2604  				nil,
  2605  			},
  2606  			{
  2607  				"map[mystring]interface{}",
  2608  				map[mystring]interface{}{"pi": 3.14159},
  2609  				buildDocument(bsoncore.AppendDoubleElement(nil, "pi", 3.14159)),
  2610  				nil,
  2611  			},
  2612  			{
  2613  				"-",
  2614  				struct {
  2615  					A string `bson:"-"`
  2616  				}{
  2617  					A: "",
  2618  				},
  2619  				[]byte{0x05, 0x00, 0x00, 0x00, 0x00},
  2620  				nil,
  2621  			},
  2622  			{
  2623  				"omitempty",
  2624  				struct {
  2625  					A string `bson:",omitempty"`
  2626  				}{
  2627  					A: "",
  2628  				},
  2629  				[]byte{0x05, 0x00, 0x00, 0x00, 0x00},
  2630  				nil,
  2631  			},
  2632  			{
  2633  				"omitempty, empty time",
  2634  				struct {
  2635  					A time.Time `bson:",omitempty"`
  2636  				}{
  2637  					A: time.Time{},
  2638  				},
  2639  				[]byte{0x05, 0x00, 0x00, 0x00, 0x00},
  2640  				nil,
  2641  			},
  2642  			{
  2643  				"no private fields",
  2644  				noPrivateFields{a: "should be empty"},
  2645  				[]byte{0x05, 0x00, 0x00, 0x00, 0x00},
  2646  				nil,
  2647  			},
  2648  			{
  2649  				"minsize",
  2650  				struct {
  2651  					A int64 `bson:",minsize"`
  2652  				}{
  2653  					A: 12345,
  2654  				},
  2655  				buildDocument(bsoncore.AppendInt32Element(nil, "a", 12345)),
  2656  				nil,
  2657  			},
  2658  			{
  2659  				"inline",
  2660  				struct {
  2661  					Foo struct {
  2662  						A int64 `bson:",minsize"`
  2663  					} `bson:",inline"`
  2664  				}{
  2665  					Foo: struct {
  2666  						A int64 `bson:",minsize"`
  2667  					}{
  2668  						A: 12345,
  2669  					},
  2670  				},
  2671  				buildDocument(bsoncore.AppendInt32Element(nil, "a", 12345)),
  2672  				nil,
  2673  			},
  2674  			{
  2675  				"inline struct pointer",
  2676  				struct {
  2677  					Foo *struct {
  2678  						A int64 `bson:",minsize"`
  2679  					} `bson:",inline"`
  2680  					Bar *struct {
  2681  						B int64
  2682  					} `bson:",inline"`
  2683  				}{
  2684  					Foo: &struct {
  2685  						A int64 `bson:",minsize"`
  2686  					}{
  2687  						A: 12345,
  2688  					},
  2689  					Bar: nil,
  2690  				},
  2691  				buildDocument(bsoncore.AppendInt32Element(nil, "a", 12345)),
  2692  				nil,
  2693  			},
  2694  			{
  2695  				"nested inline struct pointer",
  2696  				struct {
  2697  					Foo *struct {
  2698  						Bar *struct {
  2699  							A int64 `bson:",minsize"`
  2700  						} `bson:",inline"`
  2701  					} `bson:",inline"`
  2702  				}{
  2703  					Foo: &struct {
  2704  						Bar *struct {
  2705  							A int64 `bson:",minsize"`
  2706  						} `bson:",inline"`
  2707  					}{
  2708  						Bar: &struct {
  2709  							A int64 `bson:",minsize"`
  2710  						}{
  2711  							A: 12345,
  2712  						},
  2713  					},
  2714  				},
  2715  				buildDocument(bsoncore.AppendInt32Element(nil, "a", 12345)),
  2716  				nil,
  2717  			},
  2718  			{
  2719  				"inline nil struct pointer",
  2720  				struct {
  2721  					Foo *struct {
  2722  						A int64 `bson:",minsize"`
  2723  					} `bson:",inline"`
  2724  				}{
  2725  					Foo: nil,
  2726  				},
  2727  				buildDocument([]byte{}),
  2728  				nil,
  2729  			},
  2730  			{
  2731  				"inline overwrite",
  2732  				struct {
  2733  					Foo struct {
  2734  						A int32
  2735  						B string
  2736  					} `bson:",inline"`
  2737  					A int64
  2738  				}{
  2739  					Foo: struct {
  2740  						A int32
  2741  						B string
  2742  					}{
  2743  						A: 0,
  2744  						B: "foo",
  2745  					},
  2746  					A: 54321,
  2747  				},
  2748  				buildDocument(func(doc []byte) []byte {
  2749  					doc = bsoncore.AppendStringElement(doc, "b", "foo")
  2750  					doc = bsoncore.AppendInt64Element(doc, "a", 54321)
  2751  					return doc
  2752  				}(nil)),
  2753  				nil,
  2754  			},
  2755  			{
  2756  				"inline overwrite with nested structs",
  2757  				struct {
  2758  					Foo struct {
  2759  						A int32
  2760  					} `bson:",inline"`
  2761  					Bar struct {
  2762  						A int32
  2763  					} `bson:",inline"`
  2764  					A int64
  2765  				}{
  2766  					Foo: struct {
  2767  						A int32
  2768  					}{},
  2769  					Bar: struct {
  2770  						A int32
  2771  					}{},
  2772  					A: 54321,
  2773  				},
  2774  				buildDocument(bsoncore.AppendInt64Element(nil, "a", 54321)),
  2775  				nil,
  2776  			},
  2777  			{
  2778  				"inline map",
  2779  				struct {
  2780  					Foo map[string]string `bson:",inline"`
  2781  				}{
  2782  					Foo: map[string]string{"foo": "bar"},
  2783  				},
  2784  				buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar")),
  2785  				nil,
  2786  			},
  2787  			{
  2788  				"alternate name bson:name",
  2789  				struct {
  2790  					A string `bson:"foo"`
  2791  				}{
  2792  					A: "bar",
  2793  				},
  2794  				buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar")),
  2795  				nil,
  2796  			},
  2797  			{
  2798  				"alternate name",
  2799  				struct {
  2800  					A string `bson:"foo"`
  2801  				}{
  2802  					A: "bar",
  2803  				},
  2804  				buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar")),
  2805  				nil,
  2806  			},
  2807  			{
  2808  				"inline, omitempty",
  2809  				struct {
  2810  					A   string
  2811  					Foo zeroTest `bson:"omitempty,inline"`
  2812  				}{
  2813  					A:   "bar",
  2814  					Foo: zeroTest{true},
  2815  				},
  2816  				buildDocument(bsoncore.AppendStringElement(nil, "a", "bar")),
  2817  				nil,
  2818  			},
  2819  			{
  2820  				"struct{}",
  2821  				struct {
  2822  					A bool
  2823  					B int32
  2824  					C int64
  2825  					D uint16
  2826  					E uint64
  2827  					F float64
  2828  					G string
  2829  					H map[string]string
  2830  					I []byte
  2831  					K [2]string
  2832  					L struct {
  2833  						M string
  2834  					}
  2835  					Q  primitive.ObjectID
  2836  					T  []struct{}
  2837  					Y  json.Number
  2838  					Z  time.Time
  2839  					AA json.Number
  2840  					AB *url.URL
  2841  					AC primitive.Decimal128
  2842  					AD *time.Time
  2843  					AE *testValueUnmarshaler
  2844  					AF *bool
  2845  					AG *bool
  2846  					AH *int32
  2847  					AI *int64
  2848  					AJ *primitive.ObjectID
  2849  					AK *primitive.ObjectID
  2850  					AL testValueUnmarshaler
  2851  					AM interface{}
  2852  					AN interface{}
  2853  					AO interface{}
  2854  					AP primitive.D
  2855  					AQ primitive.A
  2856  					AR [2]primitive.E
  2857  					AS []byte
  2858  					AT map[string]interface{}
  2859  					AU primitive.CodeWithScope
  2860  					AV primitive.M
  2861  					AW primitive.D
  2862  					AX map[string]interface{}
  2863  					AY []primitive.E
  2864  					AZ interface{}
  2865  				}{
  2866  					A: true,
  2867  					B: 123,
  2868  					C: 456,
  2869  					D: 789,
  2870  					E: 101112,
  2871  					F: 3.14159,
  2872  					G: "Hello, world",
  2873  					H: map[string]string{"foo": "bar"},
  2874  					I: []byte{0x01, 0x02, 0x03},
  2875  					K: [2]string{"baz", "qux"},
  2876  					L: struct {
  2877  						M string
  2878  					}{
  2879  						M: "foobar",
  2880  					},
  2881  					Q:  oid,
  2882  					T:  nil,
  2883  					Y:  json.Number("5"),
  2884  					Z:  now,
  2885  					AA: json.Number("10.1"),
  2886  					AB: murl,
  2887  					AC: decimal128,
  2888  					AD: &now,
  2889  					AE: &testValueUnmarshaler{t: bsontype.String, val: bsoncore.AppendString(nil, "hello, world!")},
  2890  					AF: func(b bool) *bool { return &b }(true),
  2891  					AG: nil,
  2892  					AH: func(i32 int32) *int32 { return &i32 }(12345),
  2893  					AI: func(i64 int64) *int64 { return &i64 }(1234567890),
  2894  					AJ: &oid,
  2895  					AK: nil,
  2896  					AL: testValueUnmarshaler{t: bsontype.String, val: bsoncore.AppendString(nil, "hello, world!")},
  2897  					AM: "hello, world",
  2898  					AN: int32(12345),
  2899  					AO: oid,
  2900  					AP: primitive.D{{"foo", "bar"}},
  2901  					AQ: primitive.A{"foo", "bar"},
  2902  					AR: [2]primitive.E{{"hello", "world"}, {"pi", 3.14159}},
  2903  					AS: nil,
  2904  					AT: nil,
  2905  					AU: primitive.CodeWithScope{Code: "var hello = 'world';", Scope: primitive.D{{"pi", 3.14159}}},
  2906  					AV: primitive.M{"foo": primitive.M{"bar": "baz"}},
  2907  					AW: primitive.D{{"foo", primitive.D{{"bar", "baz"}}}},
  2908  					AX: map[string]interface{}{"foo": map[string]interface{}{"bar": "baz"}},
  2909  					AY: []primitive.E{{"foo", []primitive.E{{"bar", "baz"}}}},
  2910  					AZ: primitive.D{{"foo", primitive.D{{"bar", "baz"}}}},
  2911  				},
  2912  				buildDocument(func(doc []byte) []byte {
  2913  					doc = bsoncore.AppendBooleanElement(doc, "a", true)
  2914  					doc = bsoncore.AppendInt32Element(doc, "b", 123)
  2915  					doc = bsoncore.AppendInt64Element(doc, "c", 456)
  2916  					doc = bsoncore.AppendInt32Element(doc, "d", 789)
  2917  					doc = bsoncore.AppendInt64Element(doc, "e", 101112)
  2918  					doc = bsoncore.AppendDoubleElement(doc, "f", 3.14159)
  2919  					doc = bsoncore.AppendStringElement(doc, "g", "Hello, world")
  2920  					doc = bsoncore.AppendDocumentElement(doc, "h", buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar")))
  2921  					doc = bsoncore.AppendBinaryElement(doc, "i", 0x00, []byte{0x01, 0x02, 0x03})
  2922  					doc = bsoncore.AppendArrayElement(doc, "k",
  2923  						buildArray(bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "baz"), "1", "qux")),
  2924  					)
  2925  					doc = bsoncore.AppendDocumentElement(doc, "l", buildDocument(bsoncore.AppendStringElement(nil, "m", "foobar")))
  2926  					doc = bsoncore.AppendObjectIDElement(doc, "q", oid)
  2927  					doc = bsoncore.AppendNullElement(doc, "t")
  2928  					doc = bsoncore.AppendInt64Element(doc, "y", 5)
  2929  					doc = bsoncore.AppendDateTimeElement(doc, "z", now.UnixNano()/int64(time.Millisecond))
  2930  					doc = bsoncore.AppendDoubleElement(doc, "aa", 10.1)
  2931  					doc = bsoncore.AppendStringElement(doc, "ab", murl.String())
  2932  					doc = bsoncore.AppendDecimal128Element(doc, "ac", decimal128)
  2933  					doc = bsoncore.AppendDateTimeElement(doc, "ad", now.UnixNano()/int64(time.Millisecond))
  2934  					doc = bsoncore.AppendStringElement(doc, "ae", "hello, world!")
  2935  					doc = bsoncore.AppendBooleanElement(doc, "af", true)
  2936  					doc = bsoncore.AppendNullElement(doc, "ag")
  2937  					doc = bsoncore.AppendInt32Element(doc, "ah", 12345)
  2938  					doc = bsoncore.AppendInt32Element(doc, "ai", 1234567890)
  2939  					doc = bsoncore.AppendObjectIDElement(doc, "aj", oid)
  2940  					doc = bsoncore.AppendNullElement(doc, "ak")
  2941  					doc = bsoncore.AppendStringElement(doc, "al", "hello, world!")
  2942  					doc = bsoncore.AppendStringElement(doc, "am", "hello, world")
  2943  					doc = bsoncore.AppendInt32Element(doc, "an", 12345)
  2944  					doc = bsoncore.AppendObjectIDElement(doc, "ao", oid)
  2945  					doc = bsoncore.AppendDocumentElement(doc, "ap", buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar")))
  2946  					doc = bsoncore.AppendArrayElement(doc, "aq",
  2947  						buildArray(bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "foo"), "1", "bar")),
  2948  					)
  2949  					doc = bsoncore.AppendDocumentElement(doc, "ar",
  2950  						buildDocument(bsoncore.AppendDoubleElement(bsoncore.AppendStringElement(nil, "hello", "world"), "pi", 3.14159)),
  2951  					)
  2952  					doc = bsoncore.AppendNullElement(doc, "as")
  2953  					doc = bsoncore.AppendNullElement(doc, "at")
  2954  					doc = bsoncore.AppendCodeWithScopeElement(doc, "au",
  2955  						"var hello = 'world';", buildDocument(bsoncore.AppendDoubleElement(nil, "pi", 3.14159)),
  2956  					)
  2957  					for _, name := range [5]string{"av", "aw", "ax", "ay", "az"} {
  2958  						doc = bsoncore.AppendDocumentElement(doc, name, buildDocument(
  2959  							bsoncore.AppendDocumentElement(nil, "foo", buildDocument(
  2960  								bsoncore.AppendStringElement(nil, "bar", "baz"),
  2961  							)),
  2962  						))
  2963  					}
  2964  					return doc
  2965  				}(nil)),
  2966  				nil,
  2967  			},
  2968  			{
  2969  				"struct{[]interface{}}",
  2970  				struct {
  2971  					A []bool
  2972  					B []int32
  2973  					C []int64
  2974  					D []uint16
  2975  					E []uint64
  2976  					F []float64
  2977  					G []string
  2978  					H []map[string]string
  2979  					I [][]byte
  2980  					K [1][2]string
  2981  					L []struct {
  2982  						M string
  2983  					}
  2984  					N  [][]string
  2985  					R  []primitive.ObjectID
  2986  					T  []struct{}
  2987  					W  []map[string]struct{}
  2988  					X  []map[string]struct{}
  2989  					Y  []map[string]struct{}
  2990  					Z  []time.Time
  2991  					AA []json.Number
  2992  					AB []*url.URL
  2993  					AC []primitive.Decimal128
  2994  					AD []*time.Time
  2995  					AE []*testValueUnmarshaler
  2996  					AF []*bool
  2997  					AG []*int32
  2998  					AH []*int64
  2999  					AI []*primitive.ObjectID
  3000  					AJ []primitive.D
  3001  					AK []primitive.A
  3002  					AL [][2]primitive.E
  3003  				}{
  3004  					A: []bool{true},
  3005  					B: []int32{123},
  3006  					C: []int64{456},
  3007  					D: []uint16{789},
  3008  					E: []uint64{101112},
  3009  					F: []float64{3.14159},
  3010  					G: []string{"Hello, world"},
  3011  					H: []map[string]string{{"foo": "bar"}},
  3012  					I: [][]byte{{0x01, 0x02, 0x03}},
  3013  					K: [1][2]string{{"baz", "qux"}},
  3014  					L: []struct {
  3015  						M string
  3016  					}{
  3017  						{
  3018  							M: "foobar",
  3019  						},
  3020  					},
  3021  					N:  [][]string{{"foo", "bar"}},
  3022  					R:  oids,
  3023  					T:  nil,
  3024  					W:  nil,
  3025  					X:  []map[string]struct{}{},   // Should be empty BSON Array
  3026  					Y:  []map[string]struct{}{{}}, // Should be BSON array with one element, an empty BSON SubDocument
  3027  					Z:  []time.Time{now, now},
  3028  					AA: []json.Number{json.Number("5"), json.Number("10.1")},
  3029  					AB: []*url.URL{murl},
  3030  					AC: []primitive.Decimal128{decimal128},
  3031  					AD: []*time.Time{&now, &now},
  3032  					AE: []*testValueUnmarshaler{
  3033  						{t: bsontype.String, val: bsoncore.AppendString(nil, "hello")},
  3034  						{t: bsontype.String, val: bsoncore.AppendString(nil, "world")},
  3035  					},
  3036  					AF: []*bool{pbool(true), nil},
  3037  					AG: []*int32{pi32(12345), nil},
  3038  					AH: []*int64{pi64(1234567890), nil, pi64(9012345678)},
  3039  					AI: []*primitive.ObjectID{&oid, nil},
  3040  					AJ: []primitive.D{{{"foo", "bar"}}, nil},
  3041  					AK: []primitive.A{{"foo", "bar"}, nil},
  3042  					AL: [][2]primitive.E{{{"hello", "world"}, {"pi", 3.14159}}},
  3043  				},
  3044  				buildDocument(func(doc []byte) []byte {
  3045  					doc = appendArrayElement(doc, "a", bsoncore.AppendBooleanElement(nil, "0", true))
  3046  					doc = appendArrayElement(doc, "b", bsoncore.AppendInt32Element(nil, "0", 123))
  3047  					doc = appendArrayElement(doc, "c", bsoncore.AppendInt64Element(nil, "0", 456))
  3048  					doc = appendArrayElement(doc, "d", bsoncore.AppendInt32Element(nil, "0", 789))
  3049  					doc = appendArrayElement(doc, "e", bsoncore.AppendInt64Element(nil, "0", 101112))
  3050  					doc = appendArrayElement(doc, "f", bsoncore.AppendDoubleElement(nil, "0", 3.14159))
  3051  					doc = appendArrayElement(doc, "g", bsoncore.AppendStringElement(nil, "0", "Hello, world"))
  3052  					doc = appendArrayElement(doc, "h", bsoncore.BuildDocumentElement(nil, "0", bsoncore.AppendStringElement(nil, "foo", "bar")))
  3053  					doc = appendArrayElement(doc, "i", bsoncore.AppendBinaryElement(nil, "0", 0x00, []byte{0x01, 0x02, 0x03}))
  3054  					doc = appendArrayElement(doc, "k",
  3055  						appendArrayElement(nil, "0",
  3056  							bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "baz"), "1", "qux")),
  3057  					)
  3058  					doc = appendArrayElement(doc, "l", bsoncore.BuildDocumentElement(nil, "0", bsoncore.AppendStringElement(nil, "m", "foobar")))
  3059  					doc = appendArrayElement(doc, "n",
  3060  						appendArrayElement(nil, "0",
  3061  							bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "foo"), "1", "bar")),
  3062  					)
  3063  					doc = appendArrayElement(doc, "r",
  3064  						bsoncore.AppendObjectIDElement(
  3065  							bsoncore.AppendObjectIDElement(
  3066  								bsoncore.AppendObjectIDElement(nil,
  3067  									"0", oids[0]),
  3068  								"1", oids[1]),
  3069  							"2", oids[2]),
  3070  					)
  3071  					doc = bsoncore.AppendNullElement(doc, "t")
  3072  					doc = bsoncore.AppendNullElement(doc, "w")
  3073  					doc = appendArrayElement(doc, "x", nil)
  3074  					doc = appendArrayElement(doc, "y", bsoncore.BuildDocumentElement(nil, "0", nil))
  3075  					doc = appendArrayElement(doc, "z",
  3076  						bsoncore.AppendDateTimeElement(
  3077  							bsoncore.AppendDateTimeElement(
  3078  								nil, "0", now.UnixNano()/int64(time.Millisecond)),
  3079  							"1", now.UnixNano()/int64(time.Millisecond)),
  3080  					)
  3081  					doc = appendArrayElement(doc, "aa", bsoncore.AppendDoubleElement(bsoncore.AppendInt64Element(nil, "0", 5), "1", 10.10))
  3082  					doc = appendArrayElement(doc, "ab", bsoncore.AppendStringElement(nil, "0", murl.String()))
  3083  					doc = appendArrayElement(doc, "ac", bsoncore.AppendDecimal128Element(nil, "0", decimal128))
  3084  					doc = appendArrayElement(doc, "ad",
  3085  						bsoncore.AppendDateTimeElement(
  3086  							bsoncore.AppendDateTimeElement(nil, "0", now.UnixNano()/int64(time.Millisecond)),
  3087  							"1", now.UnixNano()/int64(time.Millisecond)),
  3088  					)
  3089  					doc = appendArrayElement(doc, "ae",
  3090  						bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "hello"), "1", "world"),
  3091  					)
  3092  					doc = appendArrayElement(doc, "af",
  3093  						bsoncore.AppendNullElement(bsoncore.AppendBooleanElement(nil, "0", true), "1"),
  3094  					)
  3095  					doc = appendArrayElement(doc, "ag",
  3096  						bsoncore.AppendNullElement(bsoncore.AppendInt32Element(nil, "0", 12345), "1"),
  3097  					)
  3098  					doc = appendArrayElement(doc, "ah",
  3099  						bsoncore.AppendInt64Element(
  3100  							bsoncore.AppendNullElement(bsoncore.AppendInt64Element(nil, "0", 1234567890), "1"),
  3101  							"2", 9012345678,
  3102  						),
  3103  					)
  3104  					doc = appendArrayElement(doc, "ai",
  3105  						bsoncore.AppendNullElement(bsoncore.AppendObjectIDElement(nil, "0", oid), "1"),
  3106  					)
  3107  					doc = appendArrayElement(doc, "aj",
  3108  						bsoncore.AppendNullElement(
  3109  							bsoncore.AppendDocumentElement(nil, "0", buildDocument(bsoncore.AppendStringElement(nil, "foo", "bar"))),
  3110  							"1",
  3111  						),
  3112  					)
  3113  					doc = appendArrayElement(doc, "ak",
  3114  						bsoncore.AppendNullElement(
  3115  							appendArrayElement(nil, "0",
  3116  								bsoncore.AppendStringElement(bsoncore.AppendStringElement(nil, "0", "foo"), "1", "bar"),
  3117  							),
  3118  							"1",
  3119  						),
  3120  					)
  3121  					doc = appendArrayElement(doc, "al",
  3122  						bsoncore.BuildDocumentElement(nil, "0",
  3123  							bsoncore.AppendDoubleElement(bsoncore.AppendStringElement(nil, "hello", "world"), "pi", 3.14159),
  3124  						),
  3125  					)
  3126  					return doc
  3127  				}(nil)),
  3128  				nil,
  3129  			},
  3130  		}
  3131  
  3132  		t.Run("Decode", func(t *testing.T) {
  3133  			for _, tc := range testCases {
  3134  				t.Run(tc.name, func(t *testing.T) {
  3135  					vr := bsonrw.NewBSONDocumentReader(tc.b)
  3136  					reg := buildDefaultRegistry()
  3137  					vtype := reflect.TypeOf(tc.value)
  3138  					dec, err := reg.LookupDecoder(vtype)
  3139  					noerr(t, err)
  3140  
  3141  					gotVal := reflect.New(reflect.TypeOf(tc.value)).Elem()
  3142  					err = dec.DecodeValue(DecodeContext{Registry: reg}, vr, gotVal)
  3143  					noerr(t, err)
  3144  
  3145  					got := gotVal.Interface()
  3146  					want := tc.value
  3147  					if diff := cmp.Diff(
  3148  						got, want,
  3149  						cmp.Comparer(compareDecimal128),
  3150  						cmp.Comparer(compareNoPrivateFields),
  3151  						cmp.Comparer(compareZeroTest),
  3152  						cmp.Comparer(compareTime),
  3153  					); diff != "" {
  3154  						t.Errorf("difference:\n%s", diff)
  3155  						t.Errorf("Values are not equal.\ngot: %#v\nwant:%#v", got, want)
  3156  					}
  3157  				})
  3158  			}
  3159  		})
  3160  	})
  3161  	t.Run("error path", func(t *testing.T) {
  3162  		testCases := []struct {
  3163  			name  string
  3164  			value interface{}
  3165  			b     []byte
  3166  			err   error
  3167  		}{
  3168  			{
  3169  				"duplicate name struct",
  3170  				struct {
  3171  					A int64
  3172  					B int64 `bson:"a"`
  3173  				}{
  3174  					A: 0,
  3175  					B: 54321,
  3176  				},
  3177  				buildDocument(bsoncore.AppendInt32Element(nil, "a", 12345)),
  3178  				fmt.Errorf("duplicated key a"),
  3179  			},
  3180  		}
  3181  
  3182  		for _, tc := range testCases {
  3183  			t.Run(tc.name, func(t *testing.T) {
  3184  				vr := bsonrw.NewBSONDocumentReader(tc.b)
  3185  				reg := buildDefaultRegistry()
  3186  				vtype := reflect.TypeOf(tc.value)
  3187  				dec, err := reg.LookupDecoder(vtype)
  3188  				noerr(t, err)
  3189  
  3190  				gotVal := reflect.New(reflect.TypeOf(tc.value)).Elem()
  3191  				err = dec.DecodeValue(DecodeContext{Registry: reg}, vr, gotVal)
  3192  				if err == nil || !strings.Contains(err.Error(), tc.err.Error()) {
  3193  					t.Errorf("Did not receive expected error. got %v; want %v", err, tc.err)
  3194  				}
  3195  			})
  3196  		}
  3197  	})
  3198  
  3199  	t.Run("defaultEmptyInterfaceCodec.DecodeValue", func(t *testing.T) {
  3200  		t.Run("DecodeValue", func(t *testing.T) {
  3201  			testCases := []struct {
  3202  				name     string
  3203  				val      interface{}
  3204  				bsontype bsontype.Type
  3205  			}{
  3206  				{
  3207  					"Double - float64",
  3208  					float64(3.14159),
  3209  					bsontype.Double,
  3210  				},
  3211  				{
  3212  					"String - string",
  3213  					"foo bar baz",
  3214  					bsontype.String,
  3215  				},
  3216  				{
  3217  					"Array - primitive.A",
  3218  					primitive.A{3.14159},
  3219  					bsontype.Array,
  3220  				},
  3221  				{
  3222  					"Binary - Binary",
  3223  					primitive.Binary{Subtype: 0xFF, Data: []byte{0x01, 0x02, 0x03}},
  3224  					bsontype.Binary,
  3225  				},
  3226  				{
  3227  					"Undefined - Undefined",
  3228  					primitive.Undefined{},
  3229  					bsontype.Undefined,
  3230  				},
  3231  				{
  3232  					"ObjectID - primitive.ObjectID",
  3233  					primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
  3234  					bsontype.ObjectID,
  3235  				},
  3236  				{
  3237  					"Boolean - bool",
  3238  					bool(true),
  3239  					bsontype.Boolean,
  3240  				},
  3241  				{
  3242  					"DateTime - DateTime",
  3243  					primitive.DateTime(1234567890),
  3244  					bsontype.DateTime,
  3245  				},
  3246  				{
  3247  					"Null - Null",
  3248  					nil,
  3249  					bsontype.Null,
  3250  				},
  3251  				{
  3252  					"Regex - Regex",
  3253  					primitive.Regex{Pattern: "foo", Options: "bar"},
  3254  					bsontype.Regex,
  3255  				},
  3256  				{
  3257  					"DBPointer - DBPointer",
  3258  					primitive.DBPointer{
  3259  						DB:      "foobar",
  3260  						Pointer: primitive.ObjectID{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C},
  3261  					},
  3262  					bsontype.DBPointer,
  3263  				},
  3264  				{
  3265  					"JavaScript - JavaScript",
  3266  					primitive.JavaScript("var foo = 'bar';"),
  3267  					bsontype.JavaScript,
  3268  				},
  3269  				{
  3270  					"Symbol - Symbol",
  3271  					primitive.Symbol("foobarbazlolz"),
  3272  					bsontype.Symbol,
  3273  				},
  3274  				{
  3275  					"Int32 - int32",
  3276  					int32(123456),
  3277  					bsontype.Int32,
  3278  				},
  3279  				{
  3280  					"Int64 - int64",
  3281  					int64(1234567890),
  3282  					bsontype.Int64,
  3283  				},
  3284  				{
  3285  					"Timestamp - Timestamp",
  3286  					primitive.Timestamp{T: 12345, I: 67890},
  3287  					bsontype.Timestamp,
  3288  				},
  3289  				{
  3290  					"Decimal128 - decimal.Decimal128",
  3291  					primitive.NewDecimal128(12345, 67890),
  3292  					bsontype.Decimal128,
  3293  				},
  3294  				{
  3295  					"MinKey - MinKey",
  3296  					primitive.MinKey{},
  3297  					bsontype.MinKey,
  3298  				},
  3299  				{
  3300  					"MaxKey - MaxKey",
  3301  					primitive.MaxKey{},
  3302  					bsontype.MaxKey,
  3303  				},
  3304  			}
  3305  			for _, tc := range testCases {
  3306  				t.Run(tc.name, func(t *testing.T) {
  3307  					llvr := &bsonrwtest.ValueReaderWriter{BSONType: tc.bsontype}
  3308  
  3309  					t.Run("Type Map failure", func(t *testing.T) {
  3310  						if tc.bsontype == bsontype.Null {
  3311  							t.Skip()
  3312  						}
  3313  						val := reflect.New(tEmpty).Elem()
  3314  						dc := DecodeContext{Registry: NewRegistryBuilder().Build()}
  3315  						want := ErrNoTypeMapEntry{Type: tc.bsontype}
  3316  						got := defaultEmptyInterfaceCodec.DecodeValue(dc, llvr, val)
  3317  						if !compareErrors(got, want) {
  3318  							t.Errorf("Errors are not equal. got %v; want %v", got, want)
  3319  						}
  3320  					})
  3321  
  3322  					t.Run("Lookup failure", func(t *testing.T) {
  3323  						if tc.bsontype == bsontype.Null {
  3324  							t.Skip()
  3325  						}
  3326  						val := reflect.New(tEmpty).Elem()
  3327  						dc := DecodeContext{
  3328  							Registry: NewRegistryBuilder().
  3329  								RegisterTypeMapEntry(tc.bsontype, reflect.TypeOf(tc.val)).
  3330  								Build(),
  3331  						}
  3332  						want := ErrNoDecoder{Type: reflect.TypeOf(tc.val)}
  3333  						got := defaultEmptyInterfaceCodec.DecodeValue(dc, llvr, val)
  3334  						if !compareErrors(got, want) {
  3335  							t.Errorf("Errors are not equal. got %v; want %v", got, want)
  3336  						}
  3337  					})
  3338  
  3339  					t.Run("DecodeValue failure", func(t *testing.T) {
  3340  						if tc.bsontype == bsontype.Null {
  3341  							t.Skip()
  3342  						}
  3343  						want := errors.New("DecodeValue failure error")
  3344  						llc := &llCodec{t: t, err: want}
  3345  						dc := DecodeContext{
  3346  							Registry: NewRegistryBuilder().
  3347  								RegisterTypeDecoder(reflect.TypeOf(tc.val), llc).
  3348  								RegisterTypeMapEntry(tc.bsontype, reflect.TypeOf(tc.val)).
  3349  								Build(),
  3350  						}
  3351  						got := defaultEmptyInterfaceCodec.DecodeValue(dc, llvr, reflect.New(tEmpty).Elem())
  3352  						if !compareErrors(got, want) {
  3353  							t.Errorf("Errors are not equal. got %v; want %v", got, want)
  3354  						}
  3355  					})
  3356  
  3357  					t.Run("Success", func(t *testing.T) {
  3358  						want := tc.val
  3359  						llc := &llCodec{t: t, decodeval: tc.val}
  3360  						dc := DecodeContext{
  3361  							Registry: NewRegistryBuilder().
  3362  								RegisterTypeDecoder(reflect.TypeOf(tc.val), llc).
  3363  								RegisterTypeMapEntry(tc.bsontype, reflect.TypeOf(tc.val)).
  3364  								Build(),
  3365  						}
  3366  						got := reflect.New(tEmpty).Elem()
  3367  						err := defaultEmptyInterfaceCodec.DecodeValue(dc, llvr, got)
  3368  						noerr(t, err)
  3369  						if !cmp.Equal(got.Interface(), want, cmp.Comparer(compareDecimal128)) {
  3370  							t.Errorf("Did not receive expected value. got %v; want %v", got.Interface(), want)
  3371  						}
  3372  					})
  3373  				})
  3374  			}
  3375  		})
  3376  
  3377  		t.Run("non-interface{}", func(t *testing.T) {
  3378  			val := uint64(1234567890)
  3379  			want := ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: reflect.ValueOf(val)}
  3380  			got := defaultEmptyInterfaceCodec.DecodeValue(DecodeContext{}, nil, reflect.ValueOf(val))
  3381  			if !compareErrors(got, want) {
  3382  				t.Errorf("Errors are not equal. got %v; want %v", got, want)
  3383  			}
  3384  		})
  3385  
  3386  		t.Run("nil *interface{}", func(t *testing.T) {
  3387  			var val interface{}
  3388  			want := ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: reflect.ValueOf(val)}
  3389  			got := defaultEmptyInterfaceCodec.DecodeValue(DecodeContext{}, nil, reflect.ValueOf(val))
  3390  			if !compareErrors(got, want) {
  3391  				t.Errorf("Errors are not equal. got %v; want %v", got, want)
  3392  			}
  3393  		})
  3394  
  3395  		t.Run("no type registered", func(t *testing.T) {
  3396  			llvr := &bsonrwtest.ValueReaderWriter{BSONType: bsontype.Double}
  3397  			want := ErrNoTypeMapEntry{Type: bsontype.Double}
  3398  			val := reflect.New(tEmpty).Elem()
  3399  			got := defaultEmptyInterfaceCodec.DecodeValue(DecodeContext{Registry: NewRegistryBuilder().Build()}, llvr, val)
  3400  			if !compareErrors(got, want) {
  3401  				t.Errorf("Errors are not equal. got %v; want %v", got, want)
  3402  			}
  3403  		})
  3404  		t.Run("top level document", func(t *testing.T) {
  3405  			data := bsoncore.BuildDocument(nil, bsoncore.AppendDoubleElement(nil, "pi", 3.14159))
  3406  			vr := bsonrw.NewBSONDocumentReader(data)
  3407  			want := primitive.D{{"pi", 3.14159}}
  3408  			var got interface{}
  3409  			val := reflect.ValueOf(&got).Elem()
  3410  			err := defaultEmptyInterfaceCodec.DecodeValue(DecodeContext{Registry: buildDefaultRegistry()}, vr, val)
  3411  			noerr(t, err)
  3412  			if !cmp.Equal(got, want) {
  3413  				t.Errorf("Did not get correct result. got %v; want %v", got, want)
  3414  			}
  3415  		})
  3416  		t.Run("custom type map entry", func(t *testing.T) {
  3417  			// registering a custom type map entry for both bsontype.Type(0) anad bsontype.EmbeddedDocument should cause
  3418  			// both top-level and embedded documents to decode to registered type when unmarshalling to interface{}
  3419  
  3420  			topLevelRb := NewRegistryBuilder()
  3421  			defaultValueEncoders.RegisterDefaultEncoders(topLevelRb)
  3422  			defaultValueDecoders.RegisterDefaultDecoders(topLevelRb)
  3423  			topLevelRb.RegisterTypeMapEntry(bsontype.Type(0), reflect.TypeOf(primitive.M{}))
  3424  
  3425  			embeddedRb := NewRegistryBuilder()
  3426  			defaultValueEncoders.RegisterDefaultEncoders(embeddedRb)
  3427  			defaultValueDecoders.RegisterDefaultDecoders(embeddedRb)
  3428  			embeddedRb.RegisterTypeMapEntry(bsontype.Type(0), reflect.TypeOf(primitive.M{}))
  3429  
  3430  			// create doc {"nested": {"foo": 1}}
  3431  			innerDoc := bsoncore.BuildDocument(
  3432  				nil,
  3433  				bsoncore.AppendInt32Element(nil, "foo", 1),
  3434  			)
  3435  			doc := bsoncore.BuildDocument(
  3436  				nil,
  3437  				bsoncore.AppendDocumentElement(nil, "nested", innerDoc),
  3438  			)
  3439  			want := primitive.M{
  3440  				"nested": primitive.M{
  3441  					"foo": int32(1),
  3442  				},
  3443  			}
  3444  
  3445  			testCases := []struct {
  3446  				name     string
  3447  				registry *Registry
  3448  			}{
  3449  				{"top level", topLevelRb.Build()},
  3450  				{"embedded", embeddedRb.Build()},
  3451  			}
  3452  			for _, tc := range testCases {
  3453  				var got interface{}
  3454  				vr := bsonrw.NewBSONDocumentReader(doc)
  3455  				val := reflect.ValueOf(&got).Elem()
  3456  
  3457  				err := defaultEmptyInterfaceCodec.DecodeValue(DecodeContext{Registry: tc.registry}, vr, val)
  3458  				noerr(t, err)
  3459  				if !cmp.Equal(got, want) {
  3460  					t.Fatalf("got %v, want %v", got, want)
  3461  				}
  3462  			}
  3463  		})
  3464  		t.Run("ancestor info is used over custom type map entry", func(t *testing.T) {
  3465  			// If a type map entry is registered for bsontype.EmbeddedDocument, the decoder should use ancestor
  3466  			// information if available instead of the registered entry.
  3467  
  3468  			rb := NewRegistryBuilder()
  3469  			defaultValueEncoders.RegisterDefaultEncoders(rb)
  3470  			defaultValueDecoders.RegisterDefaultDecoders(rb)
  3471  			rb.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(primitive.M{}))
  3472  			reg := rb.Build()
  3473  
  3474  			// build document {"nested": {"foo": 10}}
  3475  			inner := bsoncore.BuildDocument(
  3476  				nil,
  3477  				bsoncore.AppendInt32Element(nil, "foo", 10),
  3478  			)
  3479  			doc := bsoncore.BuildDocument(
  3480  				nil,
  3481  				bsoncore.AppendDocumentElement(nil, "nested", inner),
  3482  			)
  3483  			want := primitive.D{
  3484  				{"nested", primitive.D{
  3485  					{"foo", int32(10)},
  3486  				}},
  3487  			}
  3488  
  3489  			var got primitive.D
  3490  			vr := bsonrw.NewBSONDocumentReader(doc)
  3491  			val := reflect.ValueOf(&got).Elem()
  3492  			err := defaultSliceCodec.DecodeValue(DecodeContext{Registry: reg}, vr, val)
  3493  			noerr(t, err)
  3494  			if !cmp.Equal(got, want) {
  3495  				t.Fatalf("got %v, want %v", got, want)
  3496  			}
  3497  		})
  3498  	})
  3499  
  3500  	t.Run("decode errors contain key information", func(t *testing.T) {
  3501  		decodeValueError := errors.New("decode value error")
  3502  		emptyInterfaceErrorDecode := func(DecodeContext, bsonrw.ValueReader, reflect.Value) error {
  3503  			return decodeValueError
  3504  		}
  3505  		emptyInterfaceErrorRegistry := NewRegistryBuilder().
  3506  			RegisterTypeDecoder(tEmpty, ValueDecoderFunc(emptyInterfaceErrorDecode)).Build()
  3507  
  3508  		// Set up a document {foo: 10} and an error that would happen if the value were decoded into interface{}
  3509  		// using the registry defined above.
  3510  		docBytes := bsoncore.BuildDocumentFromElements(
  3511  			nil,
  3512  			bsoncore.AppendInt32Element(nil, "foo", 10),
  3513  		)
  3514  		docEmptyInterfaceErr := &DecodeError{
  3515  			keys:    []string{"foo"},
  3516  			wrapped: decodeValueError,
  3517  		}
  3518  
  3519  		// Set up struct definitions where Foo maps to interface{} and string. When decoded using the registry defined
  3520  		// above, the interface{} struct will get an error when calling DecodeValue and the string struct will get an
  3521  		// error when looking up a decoder.
  3522  		type emptyInterfaceStruct struct {
  3523  			Foo interface{}
  3524  		}
  3525  		type stringStruct struct {
  3526  			Foo string
  3527  		}
  3528  		emptyInterfaceStructErr := &DecodeError{
  3529  			keys:    []string{"foo"},
  3530  			wrapped: decodeValueError,
  3531  		}
  3532  		stringStructErr := &DecodeError{
  3533  			keys:    []string{"foo"},
  3534  			wrapped: ErrNoDecoder{reflect.TypeOf("")},
  3535  		}
  3536  
  3537  		// Test a deeply nested struct mixed with maps and slices.
  3538  		// Build document {"first": {"second": {"randomKey": {"third": [{}, {"fourth": "value"}]}}}}
  3539  		type inner3 struct{ Fourth interface{} }
  3540  		type inner2 struct{ Third []inner3 }
  3541  		type inner1 struct{ Second map[string]inner2 }
  3542  		type outer struct{ First inner1 }
  3543  		inner3EmptyDoc := buildDocument(nil)
  3544  		inner3Doc := buildDocument(bsoncore.AppendStringElement(nil, "fourth", "value"))
  3545  		inner3Array := buildArray(
  3546  			// buildArray takes []byte so we first append() all of the values into a single []byte
  3547  			append(
  3548  				bsoncore.AppendDocumentElement(nil, "0", inner3EmptyDoc),
  3549  				bsoncore.AppendDocumentElement(nil, "1", inner3Doc)...,
  3550  			),
  3551  		)
  3552  		inner2Doc := buildDocument(bsoncore.AppendArrayElement(nil, "third", inner3Array))
  3553  		inner2Map := buildDocument(bsoncore.AppendDocumentElement(nil, "randomKey", inner2Doc))
  3554  		inner1Doc := buildDocument(bsoncore.AppendDocumentElement(nil, "second", inner2Map))
  3555  		outerDoc := buildDocument(bsoncore.AppendDocumentElement(nil, "first", inner1Doc))
  3556  
  3557  		// Use a registry that has all default decoders with the custom interface{} decoder that always errors.
  3558  		nestedRegistryBuilder := NewRegistryBuilder()
  3559  		defaultValueDecoders.RegisterDefaultDecoders(nestedRegistryBuilder)
  3560  		nestedRegistry := nestedRegistryBuilder.
  3561  			RegisterTypeDecoder(tEmpty, ValueDecoderFunc(emptyInterfaceErrorDecode)).
  3562  			Build()
  3563  		nestedErr := &DecodeError{
  3564  			keys:    []string{"fourth", "1", "third", "randomKey", "second", "first"},
  3565  			wrapped: decodeValueError,
  3566  		}
  3567  
  3568  		testCases := []struct {
  3569  			name     string
  3570  			val      interface{}
  3571  			vr       bsonrw.ValueReader
  3572  			registry *Registry // buildDefaultRegistry will be used if this is nil
  3573  			decoder  ValueDecoder
  3574  			err      error
  3575  		}{
  3576  			{
  3577  				// DecodeValue error when decoding into a primitive.D.
  3578  				"primitive.D slice",
  3579  				primitive.D{},
  3580  				bsonrw.NewBSONDocumentReader(docBytes),
  3581  				emptyInterfaceErrorRegistry,
  3582  				defaultSliceCodec,
  3583  				docEmptyInterfaceErr,
  3584  			},
  3585  			{
  3586  				// DecodeValue error when decoding into a []string.
  3587  				"string slice",
  3588  				[]string{},
  3589  				&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
  3590  				nil,
  3591  				defaultSliceCodec,
  3592  				&DecodeError{
  3593  					keys:    []string{"0"},
  3594  					wrapped: errors.New("cannot decode array into a string type"),
  3595  				},
  3596  			},
  3597  			{
  3598  				// DecodeValue error when decoding into a primitive.E array. This should have the same behavior as
  3599  				// the "primitive.D slice" test above because both the defaultSliceCodec and ArrayDecodeValue use
  3600  				// the decodeD helper function.
  3601  				"primitive.D array",
  3602  				[1]primitive.E{},
  3603  				bsonrw.NewBSONDocumentReader(docBytes),
  3604  				emptyInterfaceErrorRegistry,
  3605  				ValueDecoderFunc(dvd.ArrayDecodeValue),
  3606  				docEmptyInterfaceErr,
  3607  			},
  3608  			{
  3609  				// DecodeValue error when decoding into a string array. This should have the same behavior as
  3610  				// the "primitive.D slice" test above because both the defaultSliceCodec and ArrayDecodeValue use
  3611  				// the decodeDefault helper function.
  3612  				"string array",
  3613  				[1]string{},
  3614  				&bsonrwtest.ValueReaderWriter{BSONType: bsontype.Array},
  3615  				nil,
  3616  				ValueDecoderFunc(dvd.ArrayDecodeValue),
  3617  				&DecodeError{
  3618  					keys:    []string{"0"},
  3619  					wrapped: errors.New("cannot decode array into a string type"),
  3620  				},
  3621  			},
  3622  			{
  3623  				// DecodeValue error when decoding into a map.
  3624  				"map",
  3625  				map[string]interface{}{},
  3626  				bsonrw.NewBSONDocumentReader(docBytes),
  3627  				emptyInterfaceErrorRegistry,
  3628  				defaultMapCodec,
  3629  				docEmptyInterfaceErr,
  3630  			},
  3631  			{
  3632  				// DecodeValue error when decoding into a struct.
  3633  				"struct - DecodeValue error",
  3634  				emptyInterfaceStruct{},
  3635  				bsonrw.NewBSONDocumentReader(docBytes),
  3636  				emptyInterfaceErrorRegistry,
  3637  				defaultTestStructCodec,
  3638  				emptyInterfaceStructErr,
  3639  			},
  3640  			{
  3641  				// ErrNoDecoder when decoding into a struct.
  3642  				// This test uses NewRegistryBuilder().Build rather than buildDefaultRegistry to ensure that there is
  3643  				// no decoder for strings.
  3644  				"struct - no decoder found",
  3645  				stringStruct{},
  3646  				bsonrw.NewBSONDocumentReader(docBytes),
  3647  				NewRegistryBuilder().Build(),
  3648  				defaultTestStructCodec,
  3649  				stringStructErr,
  3650  			},
  3651  			{
  3652  				"deeply nested struct",
  3653  				outer{},
  3654  				bsonrw.NewBSONDocumentReader(outerDoc),
  3655  				nestedRegistry,
  3656  				defaultTestStructCodec,
  3657  				nestedErr,
  3658  			},
  3659  		}
  3660  		for _, tc := range testCases {
  3661  			t.Run(tc.name, func(t *testing.T) {
  3662  				dc := DecodeContext{Registry: tc.registry}
  3663  				if dc.Registry == nil {
  3664  					dc.Registry = buildDefaultRegistry()
  3665  				}
  3666  
  3667  				var val reflect.Value
  3668  				if rtype := reflect.TypeOf(tc.val); rtype != nil {
  3669  					val = reflect.New(rtype).Elem()
  3670  				}
  3671  				err := tc.decoder.DecodeValue(dc, tc.vr, val)
  3672  				assert.Equal(t, tc.err, err, "expected error %v, got %v", tc.err, err)
  3673  			})
  3674  		}
  3675  
  3676  		t.Run("keys are correctly reversed", func(t *testing.T) {
  3677  			innerBytes := bsoncore.BuildDocumentFromElements(nil, bsoncore.AppendInt32Element(nil, "bar", 10))
  3678  			outerBytes := bsoncore.BuildDocumentFromElements(nil, bsoncore.AppendDocumentElement(nil, "foo", innerBytes))
  3679  
  3680  			type inner struct{ Bar string }
  3681  			type outer struct{ Foo inner }
  3682  
  3683  			dc := DecodeContext{Registry: buildDefaultRegistry()}
  3684  			vr := bsonrw.NewBSONDocumentReader(outerBytes)
  3685  			val := reflect.New(reflect.TypeOf(outer{})).Elem()
  3686  			err := defaultTestStructCodec.DecodeValue(dc, vr, val)
  3687  
  3688  			var decodeErr *DecodeError
  3689  			assert.True(t, errors.As(err, &decodeErr), "expected DecodeError, got %v of type %T", err, err)
  3690  			expectedKeys := []string{"foo", "bar"}
  3691  			assert.Equal(t, expectedKeys, decodeErr.Keys(), "expected keys slice %v, got %v", expectedKeys,
  3692  				decodeErr.Keys())
  3693  			keyPath := strings.Join(expectedKeys, ".")
  3694  			assert.True(t, strings.Contains(decodeErr.Error(), keyPath),
  3695  				"expected error %v to contain key pattern %s", decodeErr, keyPath)
  3696  		})
  3697  	})
  3698  
  3699  	t.Run("values are converted", func(t *testing.T) {
  3700  		// When decoding into a D or M, values must be converted if they are not being decoded to the default type.
  3701  
  3702  		t.Run("D", func(t *testing.T) {
  3703  			trueValue := bsoncore.Value{
  3704  				Type: bsontype.Boolean,
  3705  				Data: bsoncore.AppendBoolean(nil, true),
  3706  			}
  3707  			docBytes := bsoncore.BuildDocumentFromElements(nil,
  3708  				bsoncore.AppendBooleanElement(nil, "bool", true),
  3709  				bsoncore.BuildArrayElement(nil, "boolArray", trueValue),
  3710  			)
  3711  
  3712  			rb := NewRegistryBuilder()
  3713  			defaultValueDecoders.RegisterDefaultDecoders(rb)
  3714  			reg := rb.RegisterTypeMapEntry(bsontype.Boolean, reflect.TypeOf(mybool(true))).Build()
  3715  
  3716  			dc := DecodeContext{Registry: reg}
  3717  			vr := bsonrw.NewBSONDocumentReader(docBytes)
  3718  			val := reflect.New(tD).Elem()
  3719  			err := defaultValueDecoders.DDecodeValue(dc, vr, val)
  3720  			assert.Nil(t, err, "DDecodeValue error: %v", err)
  3721  
  3722  			want := primitive.D{
  3723  				{"bool", mybool(true)},
  3724  				{"boolArray", primitive.A{mybool(true)}},
  3725  			}
  3726  			got := val.Interface().(primitive.D)
  3727  			assert.Equal(t, want, got, "want document %v, got %v", want, got)
  3728  		})
  3729  		t.Run("M", func(t *testing.T) {
  3730  			docBytes := bsoncore.BuildDocumentFromElements(nil,
  3731  				bsoncore.AppendBooleanElement(nil, "bool", true),
  3732  			)
  3733  
  3734  			type myMap map[string]mybool
  3735  			dc := DecodeContext{Registry: buildDefaultRegistry()}
  3736  			vr := bsonrw.NewBSONDocumentReader(docBytes)
  3737  			val := reflect.New(reflect.TypeOf(myMap{})).Elem()
  3738  			err := defaultMapCodec.DecodeValue(dc, vr, val)
  3739  			assert.Nil(t, err, "DecodeValue error: %v", err)
  3740  
  3741  			want := myMap{
  3742  				"bool": mybool(true),
  3743  			}
  3744  			got := val.Interface().(myMap)
  3745  			assert.Equal(t, want, got, "expected map %v, got %v", want, got)
  3746  		})
  3747  	})
  3748  }
  3749  
  3750  type testValueUnmarshaler struct {
  3751  	t   bsontype.Type
  3752  	val []byte
  3753  	err error
  3754  }
  3755  
  3756  func (tvu *testValueUnmarshaler) UnmarshalBSONValue(t bsontype.Type, val []byte) error {
  3757  	tvu.t, tvu.val = t, val
  3758  	return tvu.err
  3759  }
  3760  
  3761  type testUnmarshaler struct {
  3762  	Val []byte
  3763  	Err error
  3764  }
  3765  
  3766  func (tvu *testUnmarshaler) UnmarshalBSON(val []byte) error {
  3767  	tvu.Val = val
  3768  	return tvu.Err
  3769  }
  3770  
  3771  func (tvu testValueUnmarshaler) Equal(tvu2 testValueUnmarshaler) bool {
  3772  	return tvu.t == tvu2.t && bytes.Equal(tvu.val, tvu2.val)
  3773  }
  3774  
  3775  // buildDocumentArray inserts vals inside of an array inside of a document.
  3776  func buildDocumentArray(fn func([]byte) []byte) []byte {
  3777  	aix, doc := bsoncore.AppendArrayElementStart(nil, "Z")
  3778  	doc = fn(doc)
  3779  	doc, _ = bsoncore.AppendArrayEnd(doc, aix)
  3780  	return buildDocument(doc)
  3781  }
  3782  
  3783  func buildArray(vals []byte) []byte {
  3784  	aix, doc := bsoncore.AppendArrayStart(nil)
  3785  	doc = append(doc, vals...)
  3786  	doc, _ = bsoncore.AppendArrayEnd(doc, aix)
  3787  	return doc
  3788  }
  3789  
  3790  func appendArrayElement(dst []byte, key string, vals []byte) []byte {
  3791  	aix, doc := bsoncore.AppendArrayElementStart(dst, key)
  3792  	doc = append(doc, vals...)
  3793  	doc, _ = bsoncore.AppendArrayEnd(doc, aix)
  3794  	return doc
  3795  }
  3796  
  3797  // buildDocument inserts elems inside of a document.
  3798  func buildDocument(elems []byte) []byte {
  3799  	idx, doc := bsoncore.AppendDocumentStart(nil)
  3800  	doc = append(doc, elems...)
  3801  	doc, _ = bsoncore.AppendDocumentEnd(doc, idx)
  3802  	return doc
  3803  }
  3804  
  3805  func buildDefaultRegistry() *Registry {
  3806  	rb := NewRegistryBuilder()
  3807  	defaultValueEncoders.RegisterDefaultEncoders(rb)
  3808  	defaultValueDecoders.RegisterDefaultDecoders(rb)
  3809  	return rb.Build()
  3810  }
  3811  

View as plain text