mirror of
https://github.com/go-gitea/gitea
synced 2025-07-22 18:28:37 +00:00
[Vendor] update go-swagger v0.21.0 -> v0.25.0 (#12670)
* Update go-swagger * vendor
This commit is contained in:
87
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go
generated
vendored
Normal file
87
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/byte_slice_codec.go
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonoptions"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
)
|
||||
|
||||
var defaultByteSliceCodec = NewByteSliceCodec()
|
||||
|
||||
// ByteSliceCodec is the Codec used for []byte values.
|
||||
type ByteSliceCodec struct {
|
||||
EncodeNilAsEmpty bool
|
||||
}
|
||||
|
||||
var _ ValueCodec = &ByteSliceCodec{}
|
||||
|
||||
// NewByteSliceCodec returns a StringCodec with options opts.
|
||||
func NewByteSliceCodec(opts ...*bsonoptions.ByteSliceCodecOptions) *ByteSliceCodec {
|
||||
byteSliceOpt := bsonoptions.MergeByteSliceCodecOptions(opts...)
|
||||
codec := ByteSliceCodec{}
|
||||
if byteSliceOpt.EncodeNilAsEmpty != nil {
|
||||
codec.EncodeNilAsEmpty = *byteSliceOpt.EncodeNilAsEmpty
|
||||
}
|
||||
return &codec
|
||||
}
|
||||
|
||||
// EncodeValue is the ValueEncoder for []byte.
|
||||
func (bsc *ByteSliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tByteSlice {
|
||||
return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
|
||||
}
|
||||
if val.IsNil() && !bsc.EncodeNilAsEmpty {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
return vw.WriteBinary(val.Interface().([]byte))
|
||||
}
|
||||
|
||||
// DecodeValue is the ValueDecoder for []byte.
|
||||
func (bsc *ByteSliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Type() != tByteSlice {
|
||||
return ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
|
||||
}
|
||||
|
||||
var data []byte
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.String:
|
||||
str, err := vr.ReadString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data = []byte(str)
|
||||
case bsontype.Symbol:
|
||||
sym, err := vr.ReadSymbol()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data = []byte(sym)
|
||||
case bsontype.Binary:
|
||||
var subtype byte
|
||||
data, subtype, err = vr.ReadBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld {
|
||||
return fmt.Errorf("ByteSliceDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", bsontype.Binary, subtype)
|
||||
}
|
||||
case bsontype.Null:
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a []byte", vrType)
|
||||
}
|
||||
|
||||
val.Set(reflect.ValueOf(data))
|
||||
return nil
|
||||
}
|
63
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go
generated
vendored
Normal file
63
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/cond_addr_codec.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
)
|
||||
|
||||
// condAddrEncoder is the encoder used when a pointer to the encoding value has an encoder.
|
||||
type condAddrEncoder struct {
|
||||
canAddrEnc ValueEncoder
|
||||
elseEnc ValueEncoder
|
||||
}
|
||||
|
||||
var _ ValueEncoder = (*condAddrEncoder)(nil)
|
||||
|
||||
// newCondAddrEncoder returns an condAddrEncoder.
|
||||
func newCondAddrEncoder(canAddrEnc, elseEnc ValueEncoder) *condAddrEncoder {
|
||||
encoder := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
|
||||
return &encoder
|
||||
}
|
||||
|
||||
// EncodeValue is the ValueEncoderFunc for a value that may be addressable.
|
||||
func (cae *condAddrEncoder) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if val.CanAddr() {
|
||||
return cae.canAddrEnc.EncodeValue(ec, vw, val)
|
||||
}
|
||||
if cae.elseEnc != nil {
|
||||
return cae.elseEnc.EncodeValue(ec, vw, val)
|
||||
}
|
||||
return ErrNoEncoder{Type: val.Type()}
|
||||
}
|
||||
|
||||
// condAddrDecoder is the decoder used when a pointer to the value has a decoder.
|
||||
type condAddrDecoder struct {
|
||||
canAddrDec ValueDecoder
|
||||
elseDec ValueDecoder
|
||||
}
|
||||
|
||||
var _ ValueDecoder = (*condAddrDecoder)(nil)
|
||||
|
||||
// newCondAddrDecoder returns an CondAddrDecoder.
|
||||
func newCondAddrDecoder(canAddrDec, elseDec ValueDecoder) *condAddrDecoder {
|
||||
decoder := condAddrDecoder{canAddrDec: canAddrDec, elseDec: elseDec}
|
||||
return &decoder
|
||||
}
|
||||
|
||||
// DecodeValue is the ValueDecoderFunc for a value that may be addressable.
|
||||
func (cad *condAddrDecoder) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if val.CanAddr() {
|
||||
return cad.canAddrDec.DecodeValue(dc, vr, val)
|
||||
}
|
||||
if cad.elseDec != nil {
|
||||
return cad.elseDec.DecodeValue(dc, vr, val)
|
||||
}
|
||||
return ErrNoDecoder{Type: val.Type()}
|
||||
}
|
527
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go
generated
vendored
527
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go
generated
vendored
@@ -40,46 +40,44 @@ func (dvd DefaultValueDecoders) RegisterDefaultDecoders(rb *RegistryBuilder) {
|
||||
}
|
||||
|
||||
rb.
|
||||
RegisterDecoder(tBinary, ValueDecoderFunc(dvd.BinaryDecodeValue)).
|
||||
RegisterDecoder(tUndefined, ValueDecoderFunc(dvd.UndefinedDecodeValue)).
|
||||
RegisterDecoder(tDateTime, ValueDecoderFunc(dvd.DateTimeDecodeValue)).
|
||||
RegisterDecoder(tNull, ValueDecoderFunc(dvd.NullDecodeValue)).
|
||||
RegisterDecoder(tRegex, ValueDecoderFunc(dvd.RegexDecodeValue)).
|
||||
RegisterDecoder(tDBPointer, ValueDecoderFunc(dvd.DBPointerDecodeValue)).
|
||||
RegisterDecoder(tTimestamp, ValueDecoderFunc(dvd.TimestampDecodeValue)).
|
||||
RegisterDecoder(tMinKey, ValueDecoderFunc(dvd.MinKeyDecodeValue)).
|
||||
RegisterDecoder(tMaxKey, ValueDecoderFunc(dvd.MaxKeyDecodeValue)).
|
||||
RegisterDecoder(tJavaScript, ValueDecoderFunc(dvd.JavaScriptDecodeValue)).
|
||||
RegisterDecoder(tSymbol, ValueDecoderFunc(dvd.SymbolDecodeValue)).
|
||||
RegisterDecoder(tByteSlice, ValueDecoderFunc(dvd.ByteSliceDecodeValue)).
|
||||
RegisterDecoder(tTime, ValueDecoderFunc(dvd.TimeDecodeValue)).
|
||||
RegisterDecoder(tEmpty, ValueDecoderFunc(dvd.EmptyInterfaceDecodeValue)).
|
||||
RegisterDecoder(tOID, ValueDecoderFunc(dvd.ObjectIDDecodeValue)).
|
||||
RegisterDecoder(tDecimal, ValueDecoderFunc(dvd.Decimal128DecodeValue)).
|
||||
RegisterDecoder(tJSONNumber, ValueDecoderFunc(dvd.JSONNumberDecodeValue)).
|
||||
RegisterDecoder(tURL, ValueDecoderFunc(dvd.URLDecodeValue)).
|
||||
RegisterDecoder(tValueUnmarshaler, ValueDecoderFunc(dvd.ValueUnmarshalerDecodeValue)).
|
||||
RegisterDecoder(tUnmarshaler, ValueDecoderFunc(dvd.UnmarshalerDecodeValue)).
|
||||
RegisterDecoder(tCoreDocument, ValueDecoderFunc(dvd.CoreDocumentDecodeValue)).
|
||||
RegisterDecoder(tCodeWithScope, ValueDecoderFunc(dvd.CodeWithScopeDecodeValue)).
|
||||
RegisterTypeDecoder(tBinary, ValueDecoderFunc(dvd.BinaryDecodeValue)).
|
||||
RegisterTypeDecoder(tUndefined, ValueDecoderFunc(dvd.UndefinedDecodeValue)).
|
||||
RegisterTypeDecoder(tDateTime, ValueDecoderFunc(dvd.DateTimeDecodeValue)).
|
||||
RegisterTypeDecoder(tNull, ValueDecoderFunc(dvd.NullDecodeValue)).
|
||||
RegisterTypeDecoder(tRegex, ValueDecoderFunc(dvd.RegexDecodeValue)).
|
||||
RegisterTypeDecoder(tDBPointer, ValueDecoderFunc(dvd.DBPointerDecodeValue)).
|
||||
RegisterTypeDecoder(tTimestamp, ValueDecoderFunc(dvd.TimestampDecodeValue)).
|
||||
RegisterTypeDecoder(tMinKey, ValueDecoderFunc(dvd.MinKeyDecodeValue)).
|
||||
RegisterTypeDecoder(tMaxKey, ValueDecoderFunc(dvd.MaxKeyDecodeValue)).
|
||||
RegisterTypeDecoder(tJavaScript, ValueDecoderFunc(dvd.JavaScriptDecodeValue)).
|
||||
RegisterTypeDecoder(tSymbol, ValueDecoderFunc(dvd.SymbolDecodeValue)).
|
||||
RegisterTypeDecoder(tByteSlice, defaultByteSliceCodec).
|
||||
RegisterTypeDecoder(tTime, defaultTimeCodec).
|
||||
RegisterTypeDecoder(tEmpty, defaultEmptyInterfaceCodec).
|
||||
RegisterTypeDecoder(tOID, ValueDecoderFunc(dvd.ObjectIDDecodeValue)).
|
||||
RegisterTypeDecoder(tDecimal, ValueDecoderFunc(dvd.Decimal128DecodeValue)).
|
||||
RegisterTypeDecoder(tJSONNumber, ValueDecoderFunc(dvd.JSONNumberDecodeValue)).
|
||||
RegisterTypeDecoder(tURL, ValueDecoderFunc(dvd.URLDecodeValue)).
|
||||
RegisterTypeDecoder(tCoreDocument, ValueDecoderFunc(dvd.CoreDocumentDecodeValue)).
|
||||
RegisterTypeDecoder(tCodeWithScope, ValueDecoderFunc(dvd.CodeWithScopeDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Bool, ValueDecoderFunc(dvd.BooleanDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Int, ValueDecoderFunc(dvd.IntDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Int8, ValueDecoderFunc(dvd.IntDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Int16, ValueDecoderFunc(dvd.IntDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Int32, ValueDecoderFunc(dvd.IntDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Int64, ValueDecoderFunc(dvd.IntDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Uint, ValueDecoderFunc(dvd.UintDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Uint8, ValueDecoderFunc(dvd.UintDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Uint16, ValueDecoderFunc(dvd.UintDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Uint32, ValueDecoderFunc(dvd.UintDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Uint64, ValueDecoderFunc(dvd.UintDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Uint, defaultUIntCodec).
|
||||
RegisterDefaultDecoder(reflect.Uint8, defaultUIntCodec).
|
||||
RegisterDefaultDecoder(reflect.Uint16, defaultUIntCodec).
|
||||
RegisterDefaultDecoder(reflect.Uint32, defaultUIntCodec).
|
||||
RegisterDefaultDecoder(reflect.Uint64, defaultUIntCodec).
|
||||
RegisterDefaultDecoder(reflect.Float32, ValueDecoderFunc(dvd.FloatDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Float64, ValueDecoderFunc(dvd.FloatDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Array, ValueDecoderFunc(dvd.ArrayDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Map, ValueDecoderFunc(dvd.MapDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Slice, ValueDecoderFunc(dvd.SliceDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.String, ValueDecoderFunc(dvd.StringDecodeValue)).
|
||||
RegisterDefaultDecoder(reflect.Struct, &StructCodec{cache: make(map[reflect.Type]*structDescription), parser: DefaultStructTagParser}).
|
||||
RegisterDefaultDecoder(reflect.Map, defaultMapCodec).
|
||||
RegisterDefaultDecoder(reflect.Slice, defaultSliceCodec).
|
||||
RegisterDefaultDecoder(reflect.String, defaultStringCodec).
|
||||
RegisterDefaultDecoder(reflect.Struct, defaultStructCodec).
|
||||
RegisterDefaultDecoder(reflect.Ptr, NewPointerCodec()).
|
||||
RegisterTypeMapEntry(bsontype.Double, tFloat64).
|
||||
RegisterTypeMapEntry(bsontype.String, tString).
|
||||
@@ -100,28 +98,68 @@ func (dvd DefaultValueDecoders) RegisterDefaultDecoders(rb *RegistryBuilder) {
|
||||
RegisterTypeMapEntry(bsontype.Decimal128, tDecimal).
|
||||
RegisterTypeMapEntry(bsontype.MinKey, tMinKey).
|
||||
RegisterTypeMapEntry(bsontype.MaxKey, tMaxKey).
|
||||
RegisterTypeMapEntry(bsontype.Type(0), tD)
|
||||
RegisterTypeMapEntry(bsontype.Type(0), tD).
|
||||
RegisterTypeMapEntry(bsontype.EmbeddedDocument, tD).
|
||||
RegisterHookDecoder(tValueUnmarshaler, ValueDecoderFunc(dvd.ValueUnmarshalerDecodeValue)).
|
||||
RegisterHookDecoder(tUnmarshaler, ValueDecoderFunc(dvd.UnmarshalerDecodeValue))
|
||||
}
|
||||
|
||||
// BooleanDecodeValue is the ValueDecoderFunc for bool types.
|
||||
func (dvd DefaultValueDecoders) BooleanDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if vr.Type() != bsontype.Boolean {
|
||||
return fmt.Errorf("cannot decode %v into a boolean", vr.Type())
|
||||
}
|
||||
if !val.IsValid() || !val.CanSet() || val.Kind() != reflect.Bool {
|
||||
return ValueDecoderError{Name: "BooleanDecodeValue", Kinds: []reflect.Kind{reflect.Bool}, Received: val}
|
||||
}
|
||||
|
||||
b, err := vr.ReadBoolean()
|
||||
var b bool
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Int32:
|
||||
i32, err := vr.ReadInt32()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b = (i32 != 0)
|
||||
case bsontype.Int64:
|
||||
i64, err := vr.ReadInt64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b = (i64 != 0)
|
||||
case bsontype.Double:
|
||||
f64, err := vr.ReadDouble()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b = (f64 != 0)
|
||||
case bsontype.Boolean:
|
||||
b, err = vr.ReadBoolean()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case bsontype.Null:
|
||||
if err = vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a boolean", vrType)
|
||||
}
|
||||
val.SetBool(b)
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
// IntDecodeValue is the ValueDecoderFunc for bool types.
|
||||
// IntDecodeValue is the ValueDecoderFunc for int types.
|
||||
func (dvd DefaultValueDecoders) IntDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() {
|
||||
return ValueDecoderError{
|
||||
Name: "IntDecodeValue",
|
||||
Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
|
||||
Received: val,
|
||||
}
|
||||
}
|
||||
|
||||
var i64 int64
|
||||
var err error
|
||||
switch vr.Type() {
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Int32:
|
||||
i32, err := vr.ReadInt32()
|
||||
if err != nil {
|
||||
@@ -145,16 +183,20 @@ func (dvd DefaultValueDecoders) IntDecodeValue(dc DecodeContext, vr bsonrw.Value
|
||||
return fmt.Errorf("%g overflows int64", f64)
|
||||
}
|
||||
i64 = int64(f64)
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into an integer type", vr.Type())
|
||||
}
|
||||
|
||||
if !val.CanSet() {
|
||||
return ValueDecoderError{
|
||||
Name: "IntDecodeValue",
|
||||
Kinds: []reflect.Kind{reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int},
|
||||
Received: val,
|
||||
case bsontype.Boolean:
|
||||
b, err := vr.ReadBoolean()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b {
|
||||
i64 = 1
|
||||
}
|
||||
case bsontype.Null:
|
||||
if err = vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into an integer type", vrType)
|
||||
}
|
||||
|
||||
switch val.Kind() {
|
||||
@@ -188,6 +230,8 @@ func (dvd DefaultValueDecoders) IntDecodeValue(dc DecodeContext, vr bsonrw.Value
|
||||
}
|
||||
|
||||
// UintDecodeValue is the ValueDecoderFunc for uint types.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use UIntCodec.DecodeValue instead.
|
||||
func (dvd DefaultValueDecoders) UintDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
var i64 int64
|
||||
var err error
|
||||
@@ -215,6 +259,14 @@ func (dvd DefaultValueDecoders) UintDecodeValue(dc DecodeContext, vr bsonrw.Valu
|
||||
return fmt.Errorf("%g overflows int64", f64)
|
||||
}
|
||||
i64 = int64(f64)
|
||||
case bsontype.Boolean:
|
||||
b, err := vr.ReadBoolean()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b {
|
||||
i64 = 1
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into an integer type", vr.Type())
|
||||
}
|
||||
@@ -262,9 +314,17 @@ func (dvd DefaultValueDecoders) UintDecodeValue(dc DecodeContext, vr bsonrw.Valu
|
||||
|
||||
// FloatDecodeValue is the ValueDecoderFunc for float types.
|
||||
func (dvd DefaultValueDecoders) FloatDecodeValue(ec DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() {
|
||||
return ValueDecoderError{
|
||||
Name: "FloatDecodeValue",
|
||||
Kinds: []reflect.Kind{reflect.Float32, reflect.Float64},
|
||||
Received: val,
|
||||
}
|
||||
}
|
||||
|
||||
var f float64
|
||||
var err error
|
||||
switch vr.Type() {
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Int32:
|
||||
i32, err := vr.ReadInt32()
|
||||
if err != nil {
|
||||
@@ -282,12 +342,20 @@ func (dvd DefaultValueDecoders) FloatDecodeValue(ec DecodeContext, vr bsonrw.Val
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case bsontype.Boolean:
|
||||
b, err := vr.ReadBoolean()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b {
|
||||
f = 1
|
||||
}
|
||||
case bsontype.Null:
|
||||
if err = vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a float32 or float64 type", vr.Type())
|
||||
}
|
||||
|
||||
if !val.CanSet() {
|
||||
return ValueDecoderError{Name: "FloatDecodeValue", Kinds: []reflect.Kind{reflect.Float32, reflect.Float64}, Received: val}
|
||||
return fmt.Errorf("cannot decode %v into a float32 or float64 type", vrType)
|
||||
}
|
||||
|
||||
switch val.Kind() {
|
||||
@@ -305,6 +373,8 @@ func (dvd DefaultValueDecoders) FloatDecodeValue(ec DecodeContext, vr bsonrw.Val
|
||||
}
|
||||
|
||||
// StringDecodeValue is the ValueDecoderFunc for string types.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use StringCodec.DecodeValue instead.
|
||||
func (dvd DefaultValueDecoders) StringDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
var str string
|
||||
var err error
|
||||
@@ -329,18 +399,23 @@ func (dvd DefaultValueDecoders) StringDecodeValue(dctx DecodeContext, vr bsonrw.
|
||||
// JavaScriptDecodeValue is the ValueDecoderFunc for the primitive.JavaScript type.
|
||||
func (DefaultValueDecoders) JavaScriptDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Type() != tJavaScript {
|
||||
return ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
|
||||
return ValueDecoderError{Name: "JavaScriptDecodeValue", Types: []reflect.Type{tJavaScript}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.JavaScript {
|
||||
return fmt.Errorf("cannot decode %v into a primitive.JavaScript", vr.Type())
|
||||
var js string
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.JavaScript:
|
||||
js, err = vr.ReadJavascript()
|
||||
case bsontype.Null:
|
||||
err = vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a primitive.JavaScript", vrType)
|
||||
}
|
||||
|
||||
js, err := vr.ReadJavascript()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.SetString(js)
|
||||
return nil
|
||||
}
|
||||
@@ -348,16 +423,37 @@ func (DefaultValueDecoders) JavaScriptDecodeValue(dctx DecodeContext, vr bsonrw.
|
||||
// SymbolDecodeValue is the ValueDecoderFunc for the primitive.Symbol type.
|
||||
func (DefaultValueDecoders) SymbolDecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Type() != tSymbol {
|
||||
return ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tSymbol}, Received: val}
|
||||
return ValueDecoderError{Name: "SymbolDecodeValue", Types: []reflect.Type{tSymbol}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.Symbol {
|
||||
return fmt.Errorf("cannot decode %v into a primitive.Symbol", vr.Type())
|
||||
}
|
||||
|
||||
symbol, err := vr.ReadSymbol()
|
||||
if err != nil {
|
||||
return err
|
||||
var symbol string
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.String:
|
||||
symbol, err = vr.ReadString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case bsontype.Symbol:
|
||||
symbol, err = vr.ReadSymbol()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case bsontype.Binary:
|
||||
data, subtype, err := vr.ReadBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld {
|
||||
return fmt.Errorf("SymbolDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", bsontype.Binary, subtype)
|
||||
}
|
||||
symbol = string(data)
|
||||
case bsontype.Null:
|
||||
if err = vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a primitive.Symbol", vrType)
|
||||
}
|
||||
|
||||
val.SetString(symbol)
|
||||
@@ -370,15 +466,21 @@ func (DefaultValueDecoders) BinaryDecodeValue(dc DecodeContext, vr bsonrw.ValueR
|
||||
return ValueDecoderError{Name: "BinaryDecodeValue", Types: []reflect.Type{tBinary}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.Binary {
|
||||
return fmt.Errorf("cannot decode %v into a Binary", vr.Type())
|
||||
var data []byte
|
||||
var subtype byte
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Binary:
|
||||
data, subtype, err = vr.ReadBinary()
|
||||
case bsontype.Null:
|
||||
err = vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a Binary", vrType)
|
||||
}
|
||||
|
||||
data, subtype, err := vr.ReadBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.Set(reflect.ValueOf(primitive.Binary{Subtype: subtype, Data: data}))
|
||||
return nil
|
||||
}
|
||||
@@ -389,12 +491,21 @@ func (DefaultValueDecoders) UndefinedDecodeValue(dc DecodeContext, vr bsonrw.Val
|
||||
return ValueDecoderError{Name: "UndefinedDecodeValue", Types: []reflect.Type{tUndefined}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.Undefined {
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Undefined:
|
||||
err = vr.ReadUndefined()
|
||||
case bsontype.Null:
|
||||
err = vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into an Undefined", vr.Type())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val.Set(reflect.ValueOf(primitive.Undefined{}))
|
||||
return vr.ReadUndefined()
|
||||
return nil
|
||||
}
|
||||
|
||||
// ObjectIDDecodeValue is the ValueDecoderFunc for primitive.ObjectID.
|
||||
@@ -403,12 +514,34 @@ func (dvd DefaultValueDecoders) ObjectIDDecodeValue(dc DecodeContext, vr bsonrw.
|
||||
return ValueDecoderError{Name: "ObjectIDDecodeValue", Types: []reflect.Type{tOID}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.ObjectID {
|
||||
return fmt.Errorf("cannot decode %v into an ObjectID", vr.Type())
|
||||
var oid primitive.ObjectID
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.ObjectID:
|
||||
oid, err = vr.ReadObjectID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case bsontype.String:
|
||||
str, err := vr.ReadString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(str) != 12 {
|
||||
return fmt.Errorf("an ObjectID string must be exactly 12 bytes long (got %v)", len(str))
|
||||
}
|
||||
byteArr := []byte(str)
|
||||
copy(oid[:], byteArr)
|
||||
case bsontype.Null:
|
||||
if err = vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into an ObjectID", vrType)
|
||||
}
|
||||
oid, err := vr.ReadObjectID()
|
||||
|
||||
val.Set(reflect.ValueOf(oid))
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
// DateTimeDecodeValue is the ValueDecoderFunc for DateTime.
|
||||
@@ -417,15 +550,20 @@ func (DefaultValueDecoders) DateTimeDecodeValue(dc DecodeContext, vr bsonrw.Valu
|
||||
return ValueDecoderError{Name: "DateTimeDecodeValue", Types: []reflect.Type{tDateTime}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.DateTime {
|
||||
return fmt.Errorf("cannot decode %v into a DateTime", vr.Type())
|
||||
var dt int64
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.DateTime:
|
||||
dt, err = vr.ReadDateTime()
|
||||
case bsontype.Null:
|
||||
err = vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a DateTime", vrType)
|
||||
}
|
||||
|
||||
dt, err := vr.ReadDateTime()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.Set(reflect.ValueOf(primitive.DateTime(dt)))
|
||||
return nil
|
||||
}
|
||||
@@ -436,8 +574,8 @@ func (DefaultValueDecoders) NullDecodeValue(dc DecodeContext, vr bsonrw.ValueRea
|
||||
return ValueDecoderError{Name: "NullDecodeValue", Types: []reflect.Type{tNull}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.Null {
|
||||
return fmt.Errorf("cannot decode %v into a Null", vr.Type())
|
||||
if vrType := vr.Type(); vrType != bsontype.Null {
|
||||
return fmt.Errorf("cannot decode %v into a Null", vrType)
|
||||
}
|
||||
|
||||
val.Set(reflect.ValueOf(primitive.Null{}))
|
||||
@@ -450,15 +588,20 @@ func (DefaultValueDecoders) RegexDecodeValue(dc DecodeContext, vr bsonrw.ValueRe
|
||||
return ValueDecoderError{Name: "RegexDecodeValue", Types: []reflect.Type{tRegex}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.Regex {
|
||||
return fmt.Errorf("cannot decode %v into a Regex", vr.Type())
|
||||
var pattern, options string
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Regex:
|
||||
pattern, options, err = vr.ReadRegex()
|
||||
case bsontype.Null:
|
||||
err = vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a Regex", vrType)
|
||||
}
|
||||
|
||||
pattern, options, err := vr.ReadRegex()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.Set(reflect.ValueOf(primitive.Regex{Pattern: pattern, Options: options}))
|
||||
return nil
|
||||
}
|
||||
@@ -469,15 +612,21 @@ func (DefaultValueDecoders) DBPointerDecodeValue(dc DecodeContext, vr bsonrw.Val
|
||||
return ValueDecoderError{Name: "DBPointerDecodeValue", Types: []reflect.Type{tDBPointer}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.DBPointer {
|
||||
return fmt.Errorf("cannot decode %v into a DBPointer", vr.Type())
|
||||
var ns string
|
||||
var pointer primitive.ObjectID
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.DBPointer:
|
||||
ns, pointer, err = vr.ReadDBPointer()
|
||||
case bsontype.Null:
|
||||
err = vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a DBPointer", vrType)
|
||||
}
|
||||
|
||||
ns, pointer, err := vr.ReadDBPointer()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.Set(reflect.ValueOf(primitive.DBPointer{DB: ns, Pointer: pointer}))
|
||||
return nil
|
||||
}
|
||||
@@ -488,15 +637,20 @@ func (DefaultValueDecoders) TimestampDecodeValue(dc DecodeContext, vr bsonrw.Val
|
||||
return ValueDecoderError{Name: "TimestampDecodeValue", Types: []reflect.Type{tTimestamp}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.Timestamp {
|
||||
return fmt.Errorf("cannot decode %v into a Timestamp", vr.Type())
|
||||
var t, incr uint32
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Timestamp:
|
||||
t, incr, err = vr.ReadTimestamp()
|
||||
case bsontype.Null:
|
||||
err = vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a Timestamp", vrType)
|
||||
}
|
||||
|
||||
t, incr, err := vr.ReadTimestamp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.Set(reflect.ValueOf(primitive.Timestamp{T: t, I: incr}))
|
||||
return nil
|
||||
}
|
||||
@@ -507,12 +661,21 @@ func (DefaultValueDecoders) MinKeyDecodeValue(dc DecodeContext, vr bsonrw.ValueR
|
||||
return ValueDecoderError{Name: "MinKeyDecodeValue", Types: []reflect.Type{tMinKey}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.MinKey {
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.MinKey:
|
||||
err = vr.ReadMinKey()
|
||||
case bsontype.Null:
|
||||
err = vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a MinKey", vr.Type())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val.Set(reflect.ValueOf(primitive.MinKey{}))
|
||||
return vr.ReadMinKey()
|
||||
return nil
|
||||
}
|
||||
|
||||
// MaxKeyDecodeValue is the ValueDecoderFunc for MaxKey.
|
||||
@@ -521,24 +684,43 @@ func (DefaultValueDecoders) MaxKeyDecodeValue(dc DecodeContext, vr bsonrw.ValueR
|
||||
return ValueDecoderError{Name: "MaxKeyDecodeValue", Types: []reflect.Type{tMaxKey}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.MaxKey {
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.MaxKey:
|
||||
err = vr.ReadMaxKey()
|
||||
case bsontype.Null:
|
||||
err = vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a MaxKey", vr.Type())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val.Set(reflect.ValueOf(primitive.MaxKey{}))
|
||||
return vr.ReadMaxKey()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Decimal128DecodeValue is the ValueDecoderFunc for primitive.Decimal128.
|
||||
func (dvd DefaultValueDecoders) Decimal128DecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if vr.Type() != bsontype.Decimal128 {
|
||||
return fmt.Errorf("cannot decode %v into a primitive.Decimal128", vr.Type())
|
||||
}
|
||||
|
||||
if !val.CanSet() || val.Type() != tDecimal {
|
||||
return ValueDecoderError{Name: "Decimal128DecodeValue", Types: []reflect.Type{tDecimal}, Received: val}
|
||||
}
|
||||
d128, err := vr.ReadDecimal128()
|
||||
|
||||
var d128 primitive.Decimal128
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Decimal128:
|
||||
d128, err = vr.ReadDecimal128()
|
||||
case bsontype.Null:
|
||||
err = vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a primitive.Decimal128", vr.Type())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val.Set(reflect.ValueOf(d128))
|
||||
return err
|
||||
}
|
||||
@@ -549,13 +731,13 @@ func (dvd DefaultValueDecoders) JSONNumberDecodeValue(dc DecodeContext, vr bsonr
|
||||
return ValueDecoderError{Name: "JSONNumberDecodeValue", Types: []reflect.Type{tJSONNumber}, Received: val}
|
||||
}
|
||||
|
||||
switch vr.Type() {
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Double:
|
||||
f64, err := vr.ReadDouble()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val.Set(reflect.ValueOf(json.Number(strconv.FormatFloat(f64, 'g', -1, 64))))
|
||||
val.Set(reflect.ValueOf(json.Number(strconv.FormatFloat(f64, 'f', -1, 64))))
|
||||
case bsontype.Int32:
|
||||
i32, err := vr.ReadInt32()
|
||||
if err != nil {
|
||||
@@ -568,8 +750,13 @@ func (dvd DefaultValueDecoders) JSONNumberDecodeValue(dc DecodeContext, vr bsonr
|
||||
return err
|
||||
}
|
||||
val.Set(reflect.ValueOf(json.Number(strconv.FormatInt(i64, 10))))
|
||||
case bsontype.Null:
|
||||
if err := vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
val.SetString("")
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a json.Number", vr.Type())
|
||||
return fmt.Errorf("cannot decode %v into a json.Number", vrType)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -577,29 +764,37 @@ func (dvd DefaultValueDecoders) JSONNumberDecodeValue(dc DecodeContext, vr bsonr
|
||||
|
||||
// URLDecodeValue is the ValueDecoderFunc for url.URL.
|
||||
func (dvd DefaultValueDecoders) URLDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if vr.Type() != bsontype.String {
|
||||
return fmt.Errorf("cannot decode %v into a *url.URL", vr.Type())
|
||||
}
|
||||
|
||||
str, err := vr.ReadString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u, err := url.Parse(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !val.CanSet() || val.Type() != tURL {
|
||||
return ValueDecoderError{Name: "URLDecodeValue", Types: []reflect.Type{tURL}, Received: val}
|
||||
}
|
||||
|
||||
val.Set(reflect.ValueOf(u).Elem())
|
||||
return nil
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.String:
|
||||
str, err := vr.ReadString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
parsedURL, err := url.Parse(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
val.Set(reflect.ValueOf(parsedURL).Elem())
|
||||
return nil
|
||||
case bsontype.Null:
|
||||
if err := vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
val.Set(reflect.ValueOf(url.URL{}))
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a *url.URL", vrType)
|
||||
}
|
||||
}
|
||||
|
||||
// TimeDecodeValue is the ValueDecoderFunc for time.Time.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use Time.DecodeValue instead.
|
||||
func (dvd DefaultValueDecoders) TimeDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if vr.Type() != bsontype.DateTime {
|
||||
return fmt.Errorf("cannot decode %v into a time.Time", vr.Type())
|
||||
@@ -619,6 +814,8 @@ func (dvd DefaultValueDecoders) TimeDecodeValue(dc DecodeContext, vr bsonrw.Valu
|
||||
}
|
||||
|
||||
// ByteSliceDecodeValue is the ValueDecoderFunc for []byte.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use ByteSliceCodec.DecodeValue instead.
|
||||
func (dvd DefaultValueDecoders) ByteSliceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if vr.Type() != bsontype.Binary && vr.Type() != bsontype.Null {
|
||||
return fmt.Errorf("cannot decode %v into a []byte", vr.Type())
|
||||
@@ -646,6 +843,8 @@ func (dvd DefaultValueDecoders) ByteSliceDecodeValue(dc DecodeContext, vr bsonrw
|
||||
}
|
||||
|
||||
// MapDecodeValue is the ValueDecoderFunc for map[string]* types.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use Map.DecodeValue instead.
|
||||
func (dvd DefaultValueDecoders) MapDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String {
|
||||
return ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
|
||||
@@ -707,14 +906,37 @@ func (dvd DefaultValueDecoders) ArrayDecodeValue(dc DecodeContext, vr bsonrw.Val
|
||||
return ValueDecoderError{Name: "ArrayDecodeValue", Kinds: []reflect.Kind{reflect.Array}, Received: val}
|
||||
}
|
||||
|
||||
switch vr.Type() {
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Array:
|
||||
case bsontype.Type(0), bsontype.EmbeddedDocument:
|
||||
if val.Type().Elem() != tE {
|
||||
return fmt.Errorf("cannot decode document into %s", val.Type())
|
||||
}
|
||||
case bsontype.Binary:
|
||||
if val.Type().Elem() != tByte {
|
||||
return fmt.Errorf("ArrayDecodeValue can only be used to decode binary into a byte array, got %v", vrType)
|
||||
}
|
||||
data, subtype, err := vr.ReadBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld {
|
||||
return fmt.Errorf("ArrayDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", bsontype.Binary, subtype)
|
||||
}
|
||||
|
||||
if len(data) > val.Len() {
|
||||
return fmt.Errorf("more elements returned in array than can fit inside %s", val.Type())
|
||||
}
|
||||
|
||||
for idx, elem := range data {
|
||||
val.Index(idx).Set(reflect.ValueOf(elem))
|
||||
}
|
||||
return nil
|
||||
case bsontype.Null:
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into an array", vr.Type())
|
||||
return fmt.Errorf("cannot decode %v into an array", vrType)
|
||||
}
|
||||
|
||||
var elemsFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) ([]reflect.Value, error)
|
||||
@@ -731,7 +953,7 @@ func (dvd DefaultValueDecoders) ArrayDecodeValue(dc DecodeContext, vr bsonrw.Val
|
||||
}
|
||||
|
||||
if len(elems) > val.Len() {
|
||||
return fmt.Errorf("more elements returned in array than can fit inside %s", val.Type())
|
||||
return fmt.Errorf("more elements returned in array than can fit inside %s, got %v elements", val.Type(), len(elems))
|
||||
}
|
||||
|
||||
for idx, elem := range elems {
|
||||
@@ -742,6 +964,8 @@ func (dvd DefaultValueDecoders) ArrayDecodeValue(dc DecodeContext, vr bsonrw.Val
|
||||
}
|
||||
|
||||
// SliceDecodeValue is the ValueDecoderFunc for slice types.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use SliceCodec.DecodeValue instead.
|
||||
func (dvd DefaultValueDecoders) SliceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Kind() != reflect.Slice {
|
||||
return ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
|
||||
@@ -851,6 +1075,8 @@ func (dvd DefaultValueDecoders) UnmarshalerDecodeValue(dc DecodeContext, vr bson
|
||||
}
|
||||
|
||||
// EmptyInterfaceDecodeValue is the ValueDecoderFunc for interface{}.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use EmptyInterfaceCodec.DecodeValue instead.
|
||||
func (dvd DefaultValueDecoders) EmptyInterfaceDecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Type() != tEmpty {
|
||||
return ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: val}
|
||||
@@ -947,27 +1173,36 @@ func (dvd DefaultValueDecoders) CodeWithScopeDecodeValue(dc DecodeContext, vr bs
|
||||
return ValueDecoderError{Name: "CodeWithScopeDecodeValue", Types: []reflect.Type{tCodeWithScope}, Received: val}
|
||||
}
|
||||
|
||||
if vr.Type() != bsontype.CodeWithScope {
|
||||
return fmt.Errorf("cannot decode %v into a primitive.CodeWithScope", vr.Type())
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.CodeWithScope:
|
||||
code, dr, err := vr.ReadCodeWithScope()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scope := reflect.New(tD).Elem()
|
||||
elems, err := dvd.decodeElemsFromDocumentReader(dc, dr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scope.Set(reflect.MakeSlice(tD, 0, len(elems)))
|
||||
scope.Set(reflect.Append(scope, elems...))
|
||||
|
||||
val.Set(reflect.ValueOf(primitive.CodeWithScope{
|
||||
Code: primitive.JavaScript(code),
|
||||
Scope: scope.Interface().(primitive.D),
|
||||
}))
|
||||
return nil
|
||||
case bsontype.Null:
|
||||
if err := vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
val.Set(reflect.ValueOf(primitive.CodeWithScope{}))
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a primitive.CodeWithScope", vrType)
|
||||
}
|
||||
|
||||
code, dr, err := vr.ReadCodeWithScope()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scope := reflect.New(tD).Elem()
|
||||
|
||||
elems, err := dvd.decodeElemsFromDocumentReader(dc, dr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
scope.Set(reflect.MakeSlice(tD, 0, len(elems)))
|
||||
scope.Set(reflect.Append(scope, elems...))
|
||||
|
||||
val.Set(reflect.ValueOf(primitive.CodeWithScope{Code: primitive.JavaScript(code), Scope: scope.Interface().(primitive.D)}))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dvd DefaultValueDecoders) decodeD(dc DecodeContext, vr bsonrw.ValueReader, _ reflect.Value) ([]reflect.Value, error) {
|
||||
|
217
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go
generated
vendored
217
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_encoders.go
generated
vendored
@@ -26,6 +26,8 @@ var defaultValueEncoders DefaultValueEncoders
|
||||
|
||||
var bvwPool = bsonrw.NewBSONValueWriterPool()
|
||||
|
||||
var errInvalidValue = errors.New("cannot encode invalid element")
|
||||
|
||||
var sliceWriterPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
sw := make(bsonrw.SliceWriter, 0, 0)
|
||||
@@ -65,48 +67,48 @@ func (dve DefaultValueEncoders) RegisterDefaultEncoders(rb *RegistryBuilder) {
|
||||
panic(errors.New("argument to RegisterDefaultEncoders must not be nil"))
|
||||
}
|
||||
rb.
|
||||
RegisterEncoder(tByteSlice, ValueEncoderFunc(dve.ByteSliceEncodeValue)).
|
||||
RegisterEncoder(tTime, ValueEncoderFunc(dve.TimeEncodeValue)).
|
||||
RegisterEncoder(tEmpty, ValueEncoderFunc(dve.EmptyInterfaceEncodeValue)).
|
||||
RegisterEncoder(tOID, ValueEncoderFunc(dve.ObjectIDEncodeValue)).
|
||||
RegisterEncoder(tDecimal, ValueEncoderFunc(dve.Decimal128EncodeValue)).
|
||||
RegisterEncoder(tJSONNumber, ValueEncoderFunc(dve.JSONNumberEncodeValue)).
|
||||
RegisterEncoder(tURL, ValueEncoderFunc(dve.URLEncodeValue)).
|
||||
RegisterEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)).
|
||||
RegisterEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)).
|
||||
RegisterEncoder(tProxy, ValueEncoderFunc(dve.ProxyEncodeValue)).
|
||||
RegisterEncoder(tJavaScript, ValueEncoderFunc(dve.JavaScriptEncodeValue)).
|
||||
RegisterEncoder(tSymbol, ValueEncoderFunc(dve.SymbolEncodeValue)).
|
||||
RegisterEncoder(tBinary, ValueEncoderFunc(dve.BinaryEncodeValue)).
|
||||
RegisterEncoder(tUndefined, ValueEncoderFunc(dve.UndefinedEncodeValue)).
|
||||
RegisterEncoder(tDateTime, ValueEncoderFunc(dve.DateTimeEncodeValue)).
|
||||
RegisterEncoder(tNull, ValueEncoderFunc(dve.NullEncodeValue)).
|
||||
RegisterEncoder(tRegex, ValueEncoderFunc(dve.RegexEncodeValue)).
|
||||
RegisterEncoder(tDBPointer, ValueEncoderFunc(dve.DBPointerEncodeValue)).
|
||||
RegisterEncoder(tTimestamp, ValueEncoderFunc(dve.TimestampEncodeValue)).
|
||||
RegisterEncoder(tMinKey, ValueEncoderFunc(dve.MinKeyEncodeValue)).
|
||||
RegisterEncoder(tMaxKey, ValueEncoderFunc(dve.MaxKeyEncodeValue)).
|
||||
RegisterEncoder(tCoreDocument, ValueEncoderFunc(dve.CoreDocumentEncodeValue)).
|
||||
RegisterEncoder(tCodeWithScope, ValueEncoderFunc(dve.CodeWithScopeEncodeValue)).
|
||||
RegisterTypeEncoder(tByteSlice, defaultByteSliceCodec).
|
||||
RegisterTypeEncoder(tTime, defaultTimeCodec).
|
||||
RegisterTypeEncoder(tEmpty, defaultEmptyInterfaceCodec).
|
||||
RegisterTypeEncoder(tOID, ValueEncoderFunc(dve.ObjectIDEncodeValue)).
|
||||
RegisterTypeEncoder(tDecimal, ValueEncoderFunc(dve.Decimal128EncodeValue)).
|
||||
RegisterTypeEncoder(tJSONNumber, ValueEncoderFunc(dve.JSONNumberEncodeValue)).
|
||||
RegisterTypeEncoder(tURL, ValueEncoderFunc(dve.URLEncodeValue)).
|
||||
RegisterTypeEncoder(tJavaScript, ValueEncoderFunc(dve.JavaScriptEncodeValue)).
|
||||
RegisterTypeEncoder(tSymbol, ValueEncoderFunc(dve.SymbolEncodeValue)).
|
||||
RegisterTypeEncoder(tBinary, ValueEncoderFunc(dve.BinaryEncodeValue)).
|
||||
RegisterTypeEncoder(tUndefined, ValueEncoderFunc(dve.UndefinedEncodeValue)).
|
||||
RegisterTypeEncoder(tDateTime, ValueEncoderFunc(dve.DateTimeEncodeValue)).
|
||||
RegisterTypeEncoder(tNull, ValueEncoderFunc(dve.NullEncodeValue)).
|
||||
RegisterTypeEncoder(tRegex, ValueEncoderFunc(dve.RegexEncodeValue)).
|
||||
RegisterTypeEncoder(tDBPointer, ValueEncoderFunc(dve.DBPointerEncodeValue)).
|
||||
RegisterTypeEncoder(tTimestamp, ValueEncoderFunc(dve.TimestampEncodeValue)).
|
||||
RegisterTypeEncoder(tMinKey, ValueEncoderFunc(dve.MinKeyEncodeValue)).
|
||||
RegisterTypeEncoder(tMaxKey, ValueEncoderFunc(dve.MaxKeyEncodeValue)).
|
||||
RegisterTypeEncoder(tCoreDocument, ValueEncoderFunc(dve.CoreDocumentEncodeValue)).
|
||||
RegisterTypeEncoder(tCodeWithScope, ValueEncoderFunc(dve.CodeWithScopeEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Bool, ValueEncoderFunc(dve.BooleanEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Int, ValueEncoderFunc(dve.IntEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Int8, ValueEncoderFunc(dve.IntEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Int16, ValueEncoderFunc(dve.IntEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Int32, ValueEncoderFunc(dve.IntEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Int64, ValueEncoderFunc(dve.IntEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint, ValueEncoderFunc(dve.UintEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint8, ValueEncoderFunc(dve.UintEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint16, ValueEncoderFunc(dve.UintEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint32, ValueEncoderFunc(dve.UintEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint64, ValueEncoderFunc(dve.UintEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Uint, defaultUIntCodec).
|
||||
RegisterDefaultEncoder(reflect.Uint8, defaultUIntCodec).
|
||||
RegisterDefaultEncoder(reflect.Uint16, defaultUIntCodec).
|
||||
RegisterDefaultEncoder(reflect.Uint32, defaultUIntCodec).
|
||||
RegisterDefaultEncoder(reflect.Uint64, defaultUIntCodec).
|
||||
RegisterDefaultEncoder(reflect.Float32, ValueEncoderFunc(dve.FloatEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Float64, ValueEncoderFunc(dve.FloatEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Array, ValueEncoderFunc(dve.ArrayEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Map, ValueEncoderFunc(dve.MapEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Slice, ValueEncoderFunc(dve.SliceEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.String, ValueEncoderFunc(dve.StringEncodeValue)).
|
||||
RegisterDefaultEncoder(reflect.Struct, &StructCodec{cache: make(map[reflect.Type]*structDescription), parser: DefaultStructTagParser}).
|
||||
RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec())
|
||||
RegisterDefaultEncoder(reflect.Map, defaultMapCodec).
|
||||
RegisterDefaultEncoder(reflect.Slice, defaultSliceCodec).
|
||||
RegisterDefaultEncoder(reflect.String, defaultStringCodec).
|
||||
RegisterDefaultEncoder(reflect.Struct, defaultStructCodec).
|
||||
RegisterDefaultEncoder(reflect.Ptr, NewPointerCodec()).
|
||||
RegisterHookEncoder(tValueMarshaler, ValueEncoderFunc(dve.ValueMarshalerEncodeValue)).
|
||||
RegisterHookEncoder(tMarshaler, ValueEncoderFunc(dve.MarshalerEncodeValue)).
|
||||
RegisterHookEncoder(tProxy, ValueEncoderFunc(dve.ProxyEncodeValue))
|
||||
}
|
||||
|
||||
// BooleanEncodeValue is the ValueEncoderFunc for bool types.
|
||||
@@ -148,6 +150,8 @@ func (dve DefaultValueEncoders) IntEncodeValue(ec EncodeContext, vw bsonrw.Value
|
||||
}
|
||||
|
||||
// UintEncodeValue is the ValueEncoderFunc for uint types.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use UIntCodec.EncodeValue instead.
|
||||
func (dve DefaultValueEncoders) UintEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
switch val.Kind() {
|
||||
case reflect.Uint8, reflect.Uint16:
|
||||
@@ -181,6 +185,8 @@ func (dve DefaultValueEncoders) FloatEncodeValue(ec EncodeContext, vw bsonrw.Val
|
||||
}
|
||||
|
||||
// StringEncodeValue is the ValueEncoderFunc for string types.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use StringCodec.EncodeValue instead.
|
||||
func (dve DefaultValueEncoders) StringEncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if val.Kind() != reflect.String {
|
||||
return ValueEncoderError{
|
||||
@@ -239,6 +245,8 @@ func (dve DefaultValueEncoders) URLEncodeValue(ec EncodeContext, vw bsonrw.Value
|
||||
}
|
||||
|
||||
// TimeEncodeValue is the ValueEncoderFunc for time.TIme.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use TimeCodec.EncodeValue instead.
|
||||
func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tTime {
|
||||
return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
|
||||
@@ -248,6 +256,8 @@ func (dve DefaultValueEncoders) TimeEncodeValue(ec EncodeContext, vw bsonrw.Valu
|
||||
}
|
||||
|
||||
// ByteSliceEncodeValue is the ValueEncoderFunc for []byte.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use ByteSliceCodec.EncodeValue instead.
|
||||
func (dve DefaultValueEncoders) ByteSliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tByteSlice {
|
||||
return ValueEncoderError{Name: "ByteSliceEncodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
|
||||
@@ -259,6 +269,8 @@ func (dve DefaultValueEncoders) ByteSliceEncodeValue(ec EncodeContext, vw bsonrw
|
||||
}
|
||||
|
||||
// MapEncodeValue is the ValueEncoderFunc for map[string]* types.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use MapCodec.EncodeValue instead.
|
||||
func (dve DefaultValueEncoders) MapEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Kind() != reflect.Map || val.Type().Key().Kind() != reflect.String {
|
||||
return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
|
||||
@@ -289,8 +301,9 @@ func (dve DefaultValueEncoders) MapEncodeValue(ec EncodeContext, vw bsonrw.Value
|
||||
// struct codec.
|
||||
func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error {
|
||||
|
||||
encoder, err := ec.LookupEncoder(val.Type().Elem())
|
||||
if err != nil {
|
||||
elemType := val.Type().Elem()
|
||||
encoder, err := ec.LookupEncoder(elemType)
|
||||
if err != nil && elemType.Kind() != reflect.Interface {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -299,19 +312,33 @@ func (dve DefaultValueEncoders) mapEncodeValue(ec EncodeContext, dw bsonrw.Docum
|
||||
if collisionFn != nil && collisionFn(key.String()) {
|
||||
return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key)
|
||||
}
|
||||
|
||||
currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.MapIndex(key))
|
||||
if lookupErr != nil && lookupErr != errInvalidValue {
|
||||
return lookupErr
|
||||
}
|
||||
|
||||
vw, err := dw.WriteDocumentElement(key.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if enc, ok := encoder.(ValueEncoder); ok {
|
||||
err = enc.EncodeValue(ec, vw, val.MapIndex(key))
|
||||
if lookupErr == errInvalidValue {
|
||||
err = vw.WriteNull()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
err = encoder.EncodeValue(ec, vw, val.MapIndex(key))
|
||||
|
||||
if enc, ok := currEncoder.(ValueEncoder); ok {
|
||||
err = enc.EncodeValue(ec, vw, currVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
err = encoder.EncodeValue(ec, vw, currVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -344,23 +371,46 @@ func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.Val
|
||||
return dw.WriteDocumentEnd()
|
||||
}
|
||||
|
||||
// If we have a []byte we want to treat it as a binary instead of as an array.
|
||||
if val.Type().Elem() == tByte {
|
||||
var byteSlice []byte
|
||||
for idx := 0; idx < val.Len(); idx++ {
|
||||
byteSlice = append(byteSlice, val.Index(idx).Interface().(byte))
|
||||
}
|
||||
return vw.WriteBinary(byteSlice)
|
||||
}
|
||||
|
||||
aw, err := vw.WriteArray()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encoder, err := ec.LookupEncoder(val.Type().Elem())
|
||||
if err != nil {
|
||||
elemType := val.Type().Elem()
|
||||
encoder, err := ec.LookupEncoder(elemType)
|
||||
if err != nil && elemType.Kind() != reflect.Interface {
|
||||
return err
|
||||
}
|
||||
|
||||
for idx := 0; idx < val.Len(); idx++ {
|
||||
currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx))
|
||||
if lookupErr != nil && lookupErr != errInvalidValue {
|
||||
return lookupErr
|
||||
}
|
||||
|
||||
vw, err := aw.WriteArrayElement()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = encoder.EncodeValue(ec, vw, val.Index(idx))
|
||||
if lookupErr == errInvalidValue {
|
||||
err = vw.WriteNull()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
err = currEncoder.EncodeValue(ec, vw, currVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -369,6 +419,8 @@ func (dve DefaultValueEncoders) ArrayEncodeValue(ec EncodeContext, vw bsonrw.Val
|
||||
}
|
||||
|
||||
// SliceEncodeValue is the ValueEncoderFunc for slice types.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use SliceCodec.EncodeValue instead.
|
||||
func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Kind() != reflect.Slice {
|
||||
return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
|
||||
@@ -402,18 +454,32 @@ func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.Val
|
||||
return err
|
||||
}
|
||||
|
||||
encoder, err := ec.LookupEncoder(val.Type().Elem())
|
||||
if err != nil {
|
||||
elemType := val.Type().Elem()
|
||||
encoder, err := ec.LookupEncoder(elemType)
|
||||
if err != nil && elemType.Kind() != reflect.Interface {
|
||||
return err
|
||||
}
|
||||
|
||||
for idx := 0; idx < val.Len(); idx++ {
|
||||
currEncoder, currVal, lookupErr := dve.lookupElementEncoder(ec, encoder, val.Index(idx))
|
||||
if lookupErr != nil && lookupErr != errInvalidValue {
|
||||
return lookupErr
|
||||
}
|
||||
|
||||
vw, err := aw.WriteArrayElement()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = encoder.EncodeValue(ec, vw, val.Index(idx))
|
||||
if lookupErr == errInvalidValue {
|
||||
err = vw.WriteNull()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
err = currEncoder.EncodeValue(ec, vw, currVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -421,7 +487,22 @@ func (dve DefaultValueEncoders) SliceEncodeValue(ec EncodeContext, vw bsonrw.Val
|
||||
return aw.WriteArrayEnd()
|
||||
}
|
||||
|
||||
func (dve DefaultValueEncoders) lookupElementEncoder(ec EncodeContext, origEncoder ValueEncoder, currVal reflect.Value) (ValueEncoder, reflect.Value, error) {
|
||||
if origEncoder != nil || (currVal.Kind() != reflect.Interface) {
|
||||
return origEncoder, currVal, nil
|
||||
}
|
||||
currVal = currVal.Elem()
|
||||
if !currVal.IsValid() {
|
||||
return nil, currVal, errInvalidValue
|
||||
}
|
||||
currEncoder, err := ec.LookupEncoder(currVal.Type())
|
||||
|
||||
return currEncoder, currVal, err
|
||||
}
|
||||
|
||||
// EmptyInterfaceEncodeValue is the ValueEncoderFunc for interface{}.
|
||||
// This method is deprecated and does not have any stability guarantees. It may be removed in the
|
||||
// future. Use EmptyInterfaceCodec.EncodeValue instead.
|
||||
func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tEmpty {
|
||||
return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val}
|
||||
@@ -440,7 +521,18 @@ func (dve DefaultValueEncoders) EmptyInterfaceEncodeValue(ec EncodeContext, vw b
|
||||
|
||||
// ValueMarshalerEncodeValue is the ValueEncoderFunc for ValueMarshaler implementations.
|
||||
func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || !val.Type().Implements(tValueMarshaler) {
|
||||
// Either val or a pointer to val must implement ValueMarshaler
|
||||
switch {
|
||||
case !val.IsValid():
|
||||
return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val}
|
||||
case val.Type().Implements(tValueMarshaler):
|
||||
// If ValueMarshaler is implemented on a concrete type, make sure that val isn't a nil pointer
|
||||
if isImplementationNil(val, tValueMarshaler) {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
case reflect.PtrTo(val.Type()).Implements(tValueMarshaler) && val.CanAddr():
|
||||
val = val.Addr()
|
||||
default:
|
||||
return ValueEncoderError{Name: "ValueMarshalerEncodeValue", Types: []reflect.Type{tValueMarshaler}, Received: val}
|
||||
}
|
||||
|
||||
@@ -455,7 +547,18 @@ func (dve DefaultValueEncoders) ValueMarshalerEncodeValue(ec EncodeContext, vw b
|
||||
|
||||
// MarshalerEncodeValue is the ValueEncoderFunc for Marshaler implementations.
|
||||
func (dve DefaultValueEncoders) MarshalerEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || !val.Type().Implements(tMarshaler) {
|
||||
// Either val or a pointer to val must implement Marshaler
|
||||
switch {
|
||||
case !val.IsValid():
|
||||
return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val}
|
||||
case val.Type().Implements(tMarshaler):
|
||||
// If Marshaler is implemented on a concrete type, make sure that val isn't a nil pointer
|
||||
if isImplementationNil(val, tMarshaler) {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
case reflect.PtrTo(val.Type()).Implements(tMarshaler) && val.CanAddr():
|
||||
val = val.Addr()
|
||||
default:
|
||||
return ValueEncoderError{Name: "MarshalerEncodeValue", Types: []reflect.Type{tMarshaler}, Received: val}
|
||||
}
|
||||
|
||||
@@ -470,7 +573,18 @@ func (dve DefaultValueEncoders) MarshalerEncodeValue(ec EncodeContext, vw bsonrw
|
||||
|
||||
// ProxyEncodeValue is the ValueEncoderFunc for Proxy implementations.
|
||||
func (dve DefaultValueEncoders) ProxyEncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || !val.Type().Implements(tProxy) {
|
||||
// Either val or a pointer to val must implement Proxy
|
||||
switch {
|
||||
case !val.IsValid():
|
||||
return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val}
|
||||
case val.Type().Implements(tProxy):
|
||||
// If Proxy is implemented on a concrete type, make sure that val isn't a nil pointer
|
||||
if isImplementationNil(val, tProxy) {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
case reflect.PtrTo(val.Type()).Implements(tProxy) && val.CanAddr():
|
||||
val = val.Addr()
|
||||
default:
|
||||
return ValueEncoderError{Name: "ProxyEncodeValue", Types: []reflect.Type{tProxy}, Received: val}
|
||||
}
|
||||
|
||||
@@ -646,3 +760,12 @@ func (dve DefaultValueEncoders) CodeWithScopeEncodeValue(ec EncodeContext, vw bs
|
||||
}
|
||||
return dw.WriteDocumentEnd()
|
||||
}
|
||||
|
||||
// isImplementationNil returns if val is a nil pointer and inter is implemented on a concrete type
|
||||
func isImplementationNil(val reflect.Value, inter reflect.Type) bool {
|
||||
vt := val.Type()
|
||||
for vt.Kind() == reflect.Ptr {
|
||||
vt = vt.Elem()
|
||||
}
|
||||
return vt.Implements(inter) && val.Kind() == reflect.Ptr && val.IsNil()
|
||||
}
|
||||
|
59
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go
generated
vendored
59
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/doc.go
generated
vendored
@@ -27,28 +27,51 @@
|
||||
//
|
||||
// Registry and RegistryBuilder
|
||||
//
|
||||
// A Registry is an immutable store for ValueEncoders, ValueDecoders, and a type map. For looking up
|
||||
// ValueEncoders and Decoders the Registry first attempts to find a ValueEncoder or ValueDecoder for
|
||||
// the type provided; if one cannot be found it then checks to see if a registered ValueEncoder or
|
||||
// ValueDecoder exists for an interface the type implements. Finally, the reflect.Kind of the type
|
||||
// is used to lookup a default ValueEncoder or ValueDecoder for that kind. If no ValueEncoder or
|
||||
// ValueDecoder can be found, an error is returned.
|
||||
// A Registry is an immutable store for ValueEncoders, ValueDecoders, and a type map. See the Registry type
|
||||
// documentation for examples of registering various custom encoders and decoders. A Registry can be constructed using a
|
||||
// RegistryBuilder, which handles three main types of codecs:
|
||||
//
|
||||
// The Registry also holds a type map. This allows users to retrieve the Go type that should be used
|
||||
// when decoding a BSON value into an empty interface. This is primarily only used for the empty
|
||||
// interface ValueDecoder.
|
||||
// 1. Type encoders/decoders - These can be registered using the RegisterTypeEncoder and RegisterTypeDecoder methods.
|
||||
// The registered codec will be invoked when encoding/decoding a value whose type matches the registered type exactly.
|
||||
// If the registered type is an interface, the codec will be invoked when encoding or decoding values whose type is the
|
||||
// interface, but not for values with concrete types that implement the interface.
|
||||
//
|
||||
// A RegistryBuilder is used to construct a Registry. The Register methods are used to associate
|
||||
// either a reflect.Type or a reflect.Kind with a ValueEncoder or ValueDecoder. A RegistryBuilder
|
||||
// returned from NewRegistryBuilder contains no registered ValueEncoders nor ValueDecoders and
|
||||
// contains an empty type map.
|
||||
// 2. Hook encoders/decoders - These can be registered using the RegisterHookEncoder and RegisterHookDecoder methods.
|
||||
// These methods only accept interface types and the registered codecs will be invoked when encoding or decoding values
|
||||
// whose types implement the interface. An example of a hook defined by the driver is bson.Marshaler. The driver will
|
||||
// call the MarshalBSON method for any value whose type implements bson.Marshaler, regardless of the value's concrete
|
||||
// type.
|
||||
//
|
||||
// The RegisterTypeMapEntry method handles associating a BSON type with a Go type. For example, if
|
||||
// you want to decode BSON int64 and int32 values into Go int instances, you would do the following:
|
||||
// 3. Type map entries - This can be used to associate a BSON type with a Go type. These type associations are used when
|
||||
// decoding into a bson.D/bson.M or a struct field of type interface{}. For example, by default, BSON int32 and int64
|
||||
// values decode as Go int32 and int64 instances, respectively, when decoding into a bson.D. The following code would
|
||||
// change the behavior so these values decode as Go int instances instead:
|
||||
//
|
||||
// var regbuilder *RegistryBuilder = ... intType := reflect.TypeOf(int(0))
|
||||
// regbuilder.RegisterTypeMapEntry(bsontype.Int64, intType).RegisterTypeMapEntry(bsontype.Int32,
|
||||
// intType)
|
||||
// intType := reflect.TypeOf(int(0))
|
||||
// registryBuilder.RegisterTypeMapEntry(bsontype.Int32, intType).RegisterTypeMapEntry(bsontype.Int64, intType)
|
||||
//
|
||||
// 4. Kind encoder/decoders - These can be registered using the RegisterDefaultEncoder and RegisterDefaultDecoder
|
||||
// methods. The registered codec will be invoked when encoding or decoding values whose reflect.Kind matches the
|
||||
// registered reflect.Kind as long as the value's type doesn't match a registered type or hook encoder/decoder first.
|
||||
// These methods should be used to change the behavior for all values for a specific kind.
|
||||
//
|
||||
// Registry Lookup Procedure
|
||||
//
|
||||
// When looking up an encoder in a Registry, the precedence rules are as follows:
|
||||
//
|
||||
// 1. A type encoder registered for the exact type of the value.
|
||||
//
|
||||
// 2. A hook encoder registered for an interface that is implemented by the value or by a pointer to the value. If the
|
||||
// value matches multiple hooks (e.g. the type implements bsoncodec.Marshaler and bsoncodec.ValueMarshaler), the first
|
||||
// one registered will be selected. Note that registries constructed using bson.NewRegistryBuilder have driver-defined
|
||||
// hooks registered for the bsoncodec.Marshaler, bsoncodec.ValueMarshaler, and bsoncodec.Proxy interfaces, so those
|
||||
// will take precedence over any new hooks.
|
||||
//
|
||||
// 3. A kind encoder registered for the value's kind.
|
||||
//
|
||||
// If all of these lookups fail to find an encoder, an error of type ErrNoEncoder is returned. The same precedence
|
||||
// rules apply for decoders, with the exception that an error of type ErrNoDecoder will be returned if no decoder is
|
||||
// found.
|
||||
//
|
||||
// DefaultValueEncoders and DefaultValueDecoders
|
||||
//
|
||||
|
125
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go
generated
vendored
Normal file
125
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/empty_interface_codec.go
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonoptions"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
var defaultEmptyInterfaceCodec = NewEmptyInterfaceCodec()
|
||||
|
||||
// EmptyInterfaceCodec is the Codec used for interface{} values.
|
||||
type EmptyInterfaceCodec struct {
|
||||
DecodeBinaryAsSlice bool
|
||||
}
|
||||
|
||||
var _ ValueCodec = &EmptyInterfaceCodec{}
|
||||
|
||||
// NewEmptyInterfaceCodec returns a EmptyInterfaceCodec with options opts.
|
||||
func NewEmptyInterfaceCodec(opts ...*bsonoptions.EmptyInterfaceCodecOptions) *EmptyInterfaceCodec {
|
||||
interfaceOpt := bsonoptions.MergeEmptyInterfaceCodecOptions(opts...)
|
||||
|
||||
codec := EmptyInterfaceCodec{}
|
||||
if interfaceOpt.DecodeBinaryAsSlice != nil {
|
||||
codec.DecodeBinaryAsSlice = *interfaceOpt.DecodeBinaryAsSlice
|
||||
}
|
||||
return &codec
|
||||
}
|
||||
|
||||
// EncodeValue is the ValueEncoderFunc for interface{}.
|
||||
func (eic EmptyInterfaceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tEmpty {
|
||||
return ValueEncoderError{Name: "EmptyInterfaceEncodeValue", Types: []reflect.Type{tEmpty}, Received: val}
|
||||
}
|
||||
|
||||
if val.IsNil() {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
encoder, err := ec.LookupEncoder(val.Elem().Type())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return encoder.EncodeValue(ec, vw, val.Elem())
|
||||
}
|
||||
|
||||
func (eic EmptyInterfaceCodec) getEmptyInterfaceDecodeType(dc DecodeContext, valueType bsontype.Type) (reflect.Type, error) {
|
||||
isDocument := valueType == bsontype.Type(0) || valueType == bsontype.EmbeddedDocument
|
||||
if isDocument && dc.Ancestor != nil {
|
||||
// Using ancestor information rather than looking up the type map entry forces consistent decoding.
|
||||
// If we're decoding into a bson.D, subdocuments should also be decoded as bson.D, even if a type map entry
|
||||
// has been registered.
|
||||
return dc.Ancestor, nil
|
||||
}
|
||||
|
||||
rtype, err := dc.LookupTypeMapEntry(valueType)
|
||||
if err == nil {
|
||||
return rtype, nil
|
||||
}
|
||||
|
||||
if isDocument {
|
||||
// For documents, fallback to looking up a type map entry for bsontype.Type(0) or bsontype.EmbeddedDocument,
|
||||
// depending on the original valueType.
|
||||
var lookupType bsontype.Type
|
||||
switch valueType {
|
||||
case bsontype.Type(0):
|
||||
lookupType = bsontype.EmbeddedDocument
|
||||
case bsontype.EmbeddedDocument:
|
||||
lookupType = bsontype.Type(0)
|
||||
}
|
||||
|
||||
rtype, err = dc.LookupTypeMapEntry(lookupType)
|
||||
if err == nil {
|
||||
return rtype, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// DecodeValue is the ValueDecoderFunc for interface{}.
|
||||
func (eic EmptyInterfaceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Type() != tEmpty {
|
||||
return ValueDecoderError{Name: "EmptyInterfaceDecodeValue", Types: []reflect.Type{tEmpty}, Received: val}
|
||||
}
|
||||
|
||||
rtype, err := eic.getEmptyInterfaceDecodeType(dc, vr.Type())
|
||||
if err != nil {
|
||||
switch vr.Type() {
|
||||
case bsontype.Null:
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return vr.ReadNull()
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
decoder, err := dc.LookupDecoder(rtype)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
elem := reflect.New(rtype).Elem()
|
||||
err = decoder.DecodeValue(dc, vr, elem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if eic.DecodeBinaryAsSlice && rtype == tBinary {
|
||||
binElem := elem.Interface().(primitive.Binary)
|
||||
if binElem.Subtype == bsontype.BinaryGeneric || binElem.Subtype == bsontype.BinaryBinaryOld {
|
||||
elem = reflect.ValueOf(binElem.Data)
|
||||
}
|
||||
}
|
||||
|
||||
val.Set(elem)
|
||||
return nil
|
||||
}
|
206
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go
generated
vendored
Normal file
206
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/map_codec.go
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonoptions"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
)
|
||||
|
||||
var defaultMapCodec = NewMapCodec()
|
||||
|
||||
// MapCodec is the Codec used for map values.
|
||||
type MapCodec struct {
|
||||
DecodeZerosMap bool
|
||||
EncodeNilAsEmpty bool
|
||||
}
|
||||
|
||||
var _ ValueCodec = &MapCodec{}
|
||||
|
||||
// NewMapCodec returns a MapCodec with options opts.
|
||||
func NewMapCodec(opts ...*bsonoptions.MapCodecOptions) *MapCodec {
|
||||
mapOpt := bsonoptions.MergeMapCodecOptions(opts...)
|
||||
|
||||
codec := MapCodec{}
|
||||
if mapOpt.DecodeZerosMap != nil {
|
||||
codec.DecodeZerosMap = *mapOpt.DecodeZerosMap
|
||||
}
|
||||
if mapOpt.EncodeNilAsEmpty != nil {
|
||||
codec.EncodeNilAsEmpty = *mapOpt.EncodeNilAsEmpty
|
||||
}
|
||||
return &codec
|
||||
}
|
||||
|
||||
// EncodeValue is the ValueEncoder for map[*]* types.
|
||||
func (mc *MapCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Kind() != reflect.Map {
|
||||
return ValueEncoderError{Name: "MapEncodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
|
||||
}
|
||||
|
||||
if val.IsNil() && !mc.EncodeNilAsEmpty {
|
||||
// If we have a nil map but we can't WriteNull, that means we're probably trying to encode
|
||||
// to a TopLevel document. We can't currently tell if this is what actually happened, but if
|
||||
// there's a deeper underlying problem, the error will also be returned from WriteDocument,
|
||||
// so just continue. The operations on a map reflection value are valid, so we can call
|
||||
// MapKeys within mapEncodeValue without a problem.
|
||||
err := vw.WriteNull()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
dw, err := vw.WriteDocument()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mc.mapEncodeValue(ec, dw, val, nil)
|
||||
}
|
||||
|
||||
// mapEncodeValue handles encoding of the values of a map. The collisionFn returns
|
||||
// true if the provided key exists, this is mainly used for inline maps in the
|
||||
// struct codec.
|
||||
func (mc *MapCodec) mapEncodeValue(ec EncodeContext, dw bsonrw.DocumentWriter, val reflect.Value, collisionFn func(string) bool) error {
|
||||
|
||||
elemType := val.Type().Elem()
|
||||
encoder, err := ec.LookupEncoder(elemType)
|
||||
if err != nil && elemType.Kind() != reflect.Interface {
|
||||
return err
|
||||
}
|
||||
|
||||
keys := val.MapKeys()
|
||||
for _, key := range keys {
|
||||
keyStr := fmt.Sprint(key)
|
||||
if collisionFn != nil && collisionFn(keyStr) {
|
||||
return fmt.Errorf("Key %s of inlined map conflicts with a struct field name", key)
|
||||
}
|
||||
|
||||
currEncoder, currVal, lookupErr := defaultValueEncoders.lookupElementEncoder(ec, encoder, val.MapIndex(key))
|
||||
if lookupErr != nil && lookupErr != errInvalidValue {
|
||||
return lookupErr
|
||||
}
|
||||
|
||||
vw, err := dw.WriteDocumentElement(keyStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if lookupErr == errInvalidValue {
|
||||
err = vw.WriteNull()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if enc, ok := currEncoder.(ValueEncoder); ok {
|
||||
err = enc.EncodeValue(ec, vw, currVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
err = encoder.EncodeValue(ec, vw, currVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return dw.WriteDocumentEnd()
|
||||
}
|
||||
|
||||
// DecodeValue is the ValueDecoder for map[string/decimal]* types.
|
||||
func (mc *MapCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if val.Kind() != reflect.Map || (!val.CanSet() && val.IsNil()) {
|
||||
return ValueDecoderError{Name: "MapDecodeValue", Kinds: []reflect.Kind{reflect.Map}, Received: val}
|
||||
}
|
||||
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Type(0), bsontype.EmbeddedDocument:
|
||||
case bsontype.Null:
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return vr.ReadNull()
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type())
|
||||
}
|
||||
|
||||
dr, err := vr.ReadDocument()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.IsNil() {
|
||||
val.Set(reflect.MakeMap(val.Type()))
|
||||
}
|
||||
|
||||
if val.Len() > 0 && mc.DecodeZerosMap {
|
||||
clearMap(val)
|
||||
}
|
||||
|
||||
eType := val.Type().Elem()
|
||||
decoder, err := dc.LookupDecoder(eType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if eType == tEmpty {
|
||||
dc.Ancestor = val.Type()
|
||||
}
|
||||
|
||||
keyType := val.Type().Key()
|
||||
keyKind := keyType.Kind()
|
||||
|
||||
for {
|
||||
key, vr, err := dr.ReadElement()
|
||||
if err == bsonrw.ErrEOD {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
k := reflect.ValueOf(key)
|
||||
if keyType != tString {
|
||||
switch keyKind {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||
reflect.Float32, reflect.Float64:
|
||||
parsed, err := strconv.ParseFloat(k.String(), 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Map key is defined to be a decimal type (%v) but got error %v", keyKind, err)
|
||||
}
|
||||
k = reflect.ValueOf(parsed)
|
||||
case reflect.String: // if keyType wraps string
|
||||
default:
|
||||
return fmt.Errorf("BSON map must have string or decimal keys. Got:%v", val.Type())
|
||||
}
|
||||
|
||||
k = k.Convert(keyType)
|
||||
}
|
||||
|
||||
elem := reflect.New(eType).Elem()
|
||||
err = decoder.DecodeValue(dc, vr, elem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.SetMapIndex(k, elem)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func clearMap(m reflect.Value) {
|
||||
var none reflect.Value
|
||||
for _, k := range m.MapKeys() {
|
||||
m.SetMapIndex(k, none)
|
||||
}
|
||||
}
|
160
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
generated
vendored
160
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go
generated
vendored
@@ -8,6 +8,7 @@ package bsoncodec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
@@ -115,15 +116,79 @@ func buildDefaultRegistry() *Registry {
|
||||
|
||||
// RegisterCodec will register the provided ValueCodec for the provided type.
|
||||
func (rb *RegistryBuilder) RegisterCodec(t reflect.Type, codec ValueCodec) *RegistryBuilder {
|
||||
rb.RegisterEncoder(t, codec)
|
||||
rb.RegisterDecoder(t, codec)
|
||||
rb.RegisterTypeEncoder(t, codec)
|
||||
rb.RegisterTypeDecoder(t, codec)
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterEncoder will register the provided ValueEncoder to the provided type.
|
||||
// RegisterTypeEncoder will register the provided ValueEncoder for the provided type.
|
||||
//
|
||||
// The type registered will be used directly, so an encoder can be registered for a type and a
|
||||
// different encoder can be registered for a pointer to that type.
|
||||
// The type will be used directly, so an encoder can be registered for a type and a different encoder can be registered
|
||||
// for a pointer to that type.
|
||||
//
|
||||
// If the given type is an interface, the encoder will be called when marshalling a type that is that interface. It
|
||||
// will not be called when marshalling a non-interface type that implements the interface.
|
||||
func (rb *RegistryBuilder) RegisterTypeEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
|
||||
rb.typeEncoders[t] = enc
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterHookEncoder will register an encoder for the provided interface type t. This encoder will be called when
|
||||
// marshalling a type if the type implements t or a pointer to the type implements t. If the provided type is not
|
||||
// an interface (i.e. t.Kind() != reflect.Interface), this method will panic.
|
||||
func (rb *RegistryBuilder) RegisterHookEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
|
||||
if t.Kind() != reflect.Interface {
|
||||
panicStr := fmt.Sprintf("RegisterHookEncoder expects a type with kind reflect.Interface, "+
|
||||
"got type %s with kind %s", t, t.Kind())
|
||||
panic(panicStr)
|
||||
}
|
||||
|
||||
for idx, encoder := range rb.interfaceEncoders {
|
||||
if encoder.i == t {
|
||||
rb.interfaceEncoders[idx].ve = enc
|
||||
return rb
|
||||
}
|
||||
}
|
||||
|
||||
rb.interfaceEncoders = append(rb.interfaceEncoders, interfaceValueEncoder{i: t, ve: enc})
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterTypeDecoder will register the provided ValueDecoder for the provided type.
|
||||
//
|
||||
// The type will be used directly, so a decoder can be registered for a type and a different decoder can be registered
|
||||
// for a pointer to that type.
|
||||
//
|
||||
// If the given type is an interface, the decoder will be called when unmarshalling into a type that is that interface.
|
||||
// It will not be called when unmarshalling into a non-interface type that implements the interface.
|
||||
func (rb *RegistryBuilder) RegisterTypeDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
|
||||
rb.typeDecoders[t] = dec
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterHookDecoder will register an decoder for the provided interface type t. This decoder will be called when
|
||||
// unmarshalling into a type if the type implements t or a pointer to the type implements t. If the provided type is not
|
||||
// an interface (i.e. t.Kind() != reflect.Interface), this method will panic.
|
||||
func (rb *RegistryBuilder) RegisterHookDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
|
||||
if t.Kind() != reflect.Interface {
|
||||
panicStr := fmt.Sprintf("RegisterHookDecoder expects a type with kind reflect.Interface, "+
|
||||
"got type %s with kind %s", t, t.Kind())
|
||||
panic(panicStr)
|
||||
}
|
||||
|
||||
for idx, decoder := range rb.interfaceDecoders {
|
||||
if decoder.i == t {
|
||||
rb.interfaceDecoders[idx].vd = dec
|
||||
return rb
|
||||
}
|
||||
}
|
||||
|
||||
rb.interfaceDecoders = append(rb.interfaceDecoders, interfaceValueDecoder{i: t, vd: dec})
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterEncoder has been deprecated and will be removed in a future major version release. Use RegisterTypeEncoder
|
||||
// or RegisterHookEncoder instead.
|
||||
func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *RegistryBuilder {
|
||||
if t == tEmpty {
|
||||
rb.typeEncoders[t] = enc
|
||||
@@ -145,10 +210,8 @@ func (rb *RegistryBuilder) RegisterEncoder(t reflect.Type, enc ValueEncoder) *Re
|
||||
return rb
|
||||
}
|
||||
|
||||
// RegisterDecoder will register the provided ValueDecoder to the provided type.
|
||||
//
|
||||
// The type registered will be used directly, so a decoder can be registered for a type and a
|
||||
// different decoder can be registered for a pointer to that type.
|
||||
// RegisterDecoder has been deprecated and will be removed in a future major version release. Use RegisterTypeDecoder
|
||||
// or RegisterHookDecoder instead.
|
||||
func (rb *RegistryBuilder) RegisterDecoder(t reflect.Type, dec ValueDecoder) *RegistryBuilder {
|
||||
if t == nil {
|
||||
rb.typeDecoders[nil] = dec
|
||||
@@ -192,11 +255,10 @@ func (rb *RegistryBuilder) RegisterDefaultDecoder(kind reflect.Kind, dec ValueDe
|
||||
// mapping is decoding situations where an empty interface is used and a default type needs to be
|
||||
// created and decoded into.
|
||||
//
|
||||
// NOTE: It is unlikely that registering a type for BSON Embedded Document is actually desired. By
|
||||
// registering a type map entry for BSON Embedded Document the type registered will be used in any
|
||||
// case where a BSON Embedded Document will be decoded into an empty interface. For example, if you
|
||||
// register primitive.M, the EmptyInterface decoder will always use primitive.M, even if an ancestor
|
||||
// was a primitive.D.
|
||||
// By default, BSON documents will decode into interface{} values as bson.D. To change the default type for BSON
|
||||
// documents, a type map entry for bsontype.EmbeddedDocument should be registered. For example, to force BSON documents
|
||||
// to decode to bson.Raw, use the following code:
|
||||
// rb.RegisterTypeMapEntry(bsontype.EmbeddedDocument, reflect.TypeOf(bson.Raw{}))
|
||||
func (rb *RegistryBuilder) RegisterTypeMapEntry(bt bsontype.Type, rt reflect.Type) *RegistryBuilder {
|
||||
rb.typeMap[bt] = rt
|
||||
return rb
|
||||
@@ -240,11 +302,17 @@ func (rb *RegistryBuilder) Build() *Registry {
|
||||
return registry
|
||||
}
|
||||
|
||||
// LookupEncoder will inspect the registry for an encoder that satisfies the
|
||||
// type provided. An encoder registered for a specific type will take
|
||||
// precedence over an encoder registered for an interface the type satisfies,
|
||||
// which takes precedence over an encoder for the reflect.Kind of the value. If
|
||||
// no encoder can be found, an error is returned.
|
||||
// LookupEncoder inspects the registry for an encoder for the given type. The lookup precendence works as follows:
|
||||
//
|
||||
// 1. An encoder registered for the exact type. If the given type represents an interface, an encoder registered using
|
||||
// RegisterTypeEncoder for the interface will be selected.
|
||||
//
|
||||
// 2. An encoder registered using RegisterHookEncoder for an interface implemented by the type or by a pointer to the
|
||||
// type.
|
||||
//
|
||||
// 3. An encoder registered for the reflect.Kind of the value.
|
||||
//
|
||||
// If no encoder is found, an error of type ErrNoEncoder is returned.
|
||||
func (r *Registry) LookupEncoder(t reflect.Type) (ValueEncoder, error) {
|
||||
encodererr := ErrNoEncoder{Type: t}
|
||||
r.mu.RLock()
|
||||
@@ -257,7 +325,7 @@ func (r *Registry) LookupEncoder(t reflect.Type) (ValueEncoder, error) {
|
||||
return enc, nil
|
||||
}
|
||||
|
||||
enc, found = r.lookupInterfaceEncoder(t)
|
||||
enc, found = r.lookupInterfaceEncoder(t, true)
|
||||
if found {
|
||||
r.mu.Lock()
|
||||
r.typeEncoders[t] = enc
|
||||
@@ -291,25 +359,38 @@ func (r *Registry) lookupTypeEncoder(t reflect.Type) (ValueEncoder, bool) {
|
||||
return enc, found
|
||||
}
|
||||
|
||||
func (r *Registry) lookupInterfaceEncoder(t reflect.Type) (ValueEncoder, bool) {
|
||||
func (r *Registry) lookupInterfaceEncoder(t reflect.Type, allowAddr bool) (ValueEncoder, bool) {
|
||||
if t == nil {
|
||||
return nil, false
|
||||
}
|
||||
for _, ienc := range r.interfaceEncoders {
|
||||
if !t.Implements(ienc.i) {
|
||||
continue
|
||||
if t.Implements(ienc.i) {
|
||||
return ienc.ve, true
|
||||
}
|
||||
if allowAddr && t.Kind() != reflect.Ptr && reflect.PtrTo(t).Implements(ienc.i) {
|
||||
// if *t implements an interface, this will catch if t implements an interface further ahead
|
||||
// in interfaceEncoders
|
||||
defaultEnc, found := r.lookupInterfaceEncoder(t, false)
|
||||
if !found {
|
||||
defaultEnc, _ = r.kindEncoders[t.Kind()]
|
||||
}
|
||||
return newCondAddrEncoder(ienc.ve, defaultEnc), true
|
||||
}
|
||||
|
||||
return ienc.ve, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// LookupDecoder will inspect the registry for a decoder that satisfies the
|
||||
// type provided. A decoder registered for a specific type will take
|
||||
// precedence over a decoder registered for an interface the type satisfies,
|
||||
// which takes precedence over a decoder for the reflect.Kind of the value. If
|
||||
// no decoder can be found, an error is returned.
|
||||
// LookupDecoder inspects the registry for an decoder for the given type. The lookup precendence works as follows:
|
||||
//
|
||||
// 1. A decoder registered for the exact type. If the given type represents an interface, a decoder registered using
|
||||
// RegisterTypeDecoder for the interface will be selected.
|
||||
//
|
||||
// 2. A decoder registered using RegisterHookDecoder for an interface implemented by the type or by a pointer to the
|
||||
// type.
|
||||
//
|
||||
// 3. A decoder registered for the reflect.Kind of the value.
|
||||
//
|
||||
// If no decoder is found, an error of type ErrNoDecoder is returned.
|
||||
func (r *Registry) LookupDecoder(t reflect.Type) (ValueDecoder, error) {
|
||||
if t == nil {
|
||||
return nil, ErrNilType
|
||||
@@ -325,7 +406,7 @@ func (r *Registry) LookupDecoder(t reflect.Type) (ValueDecoder, error) {
|
||||
return dec, nil
|
||||
}
|
||||
|
||||
dec, found = r.lookupInterfaceDecoder(t)
|
||||
dec, found = r.lookupInterfaceDecoder(t, true)
|
||||
if found {
|
||||
r.mu.Lock()
|
||||
r.typeDecoders[t] = dec
|
||||
@@ -352,13 +433,20 @@ func (r *Registry) lookupTypeDecoder(t reflect.Type) (ValueDecoder, bool) {
|
||||
return dec, found
|
||||
}
|
||||
|
||||
func (r *Registry) lookupInterfaceDecoder(t reflect.Type) (ValueDecoder, bool) {
|
||||
func (r *Registry) lookupInterfaceDecoder(t reflect.Type, allowAddr bool) (ValueDecoder, bool) {
|
||||
for _, idec := range r.interfaceDecoders {
|
||||
if !t.Implements(idec.i) && !reflect.PtrTo(t).Implements(idec.i) {
|
||||
continue
|
||||
if t.Implements(idec.i) {
|
||||
return idec.vd, true
|
||||
}
|
||||
if allowAddr && t.Kind() != reflect.Ptr && reflect.PtrTo(t).Implements(idec.i) {
|
||||
// if *t implements an interface, this will catch if t implements an interface further ahead
|
||||
// in interfaceDecoders
|
||||
defaultDec, found := r.lookupInterfaceDecoder(t, false)
|
||||
if !found {
|
||||
defaultDec, _ = r.kindDecoders[t.Kind()]
|
||||
}
|
||||
return newCondAddrDecoder(idec.vd, defaultDec), true
|
||||
}
|
||||
|
||||
return idec.vd, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
196
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go
generated
vendored
Normal file
196
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/slice_codec.go
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonoptions"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
var defaultSliceCodec = NewSliceCodec()
|
||||
|
||||
// SliceCodec is the Codec used for slice values.
|
||||
type SliceCodec struct {
|
||||
EncodeNilAsEmpty bool
|
||||
}
|
||||
|
||||
var _ ValueCodec = &MapCodec{}
|
||||
|
||||
// NewSliceCodec returns a MapCodec with options opts.
|
||||
func NewSliceCodec(opts ...*bsonoptions.SliceCodecOptions) *SliceCodec {
|
||||
sliceOpt := bsonoptions.MergeSliceCodecOptions(opts...)
|
||||
|
||||
codec := SliceCodec{}
|
||||
if sliceOpt.EncodeNilAsEmpty != nil {
|
||||
codec.EncodeNilAsEmpty = *sliceOpt.EncodeNilAsEmpty
|
||||
}
|
||||
return &codec
|
||||
}
|
||||
|
||||
// EncodeValue is the ValueEncoder for slice types.
|
||||
func (sc SliceCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Kind() != reflect.Slice {
|
||||
return ValueEncoderError{Name: "SliceEncodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
|
||||
}
|
||||
|
||||
if val.IsNil() && !sc.EncodeNilAsEmpty {
|
||||
return vw.WriteNull()
|
||||
}
|
||||
|
||||
// If we have a []byte we want to treat it as a binary instead of as an array.
|
||||
if val.Type().Elem() == tByte {
|
||||
var byteSlice []byte
|
||||
for idx := 0; idx < val.Len(); idx++ {
|
||||
byteSlice = append(byteSlice, val.Index(idx).Interface().(byte))
|
||||
}
|
||||
return vw.WriteBinary(byteSlice)
|
||||
}
|
||||
|
||||
// If we have a []primitive.E we want to treat it as a document instead of as an array.
|
||||
if val.Type().ConvertibleTo(tD) {
|
||||
d := val.Convert(tD).Interface().(primitive.D)
|
||||
|
||||
dw, err := vw.WriteDocument()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, e := range d {
|
||||
err = encodeElement(ec, dw, e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return dw.WriteDocumentEnd()
|
||||
}
|
||||
|
||||
aw, err := vw.WriteArray()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
elemType := val.Type().Elem()
|
||||
encoder, err := ec.LookupEncoder(elemType)
|
||||
if err != nil && elemType.Kind() != reflect.Interface {
|
||||
return err
|
||||
}
|
||||
|
||||
for idx := 0; idx < val.Len(); idx++ {
|
||||
currEncoder, currVal, lookupErr := defaultValueEncoders.lookupElementEncoder(ec, encoder, val.Index(idx))
|
||||
if lookupErr != nil && lookupErr != errInvalidValue {
|
||||
return lookupErr
|
||||
}
|
||||
|
||||
vw, err := aw.WriteArrayElement()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if lookupErr == errInvalidValue {
|
||||
err = vw.WriteNull()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
err = currEncoder.EncodeValue(ec, vw, currVal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return aw.WriteArrayEnd()
|
||||
}
|
||||
|
||||
// DecodeValue is the ValueDecoder for slice types.
|
||||
func (sc *SliceCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Kind() != reflect.Slice {
|
||||
return ValueDecoderError{Name: "SliceDecodeValue", Kinds: []reflect.Kind{reflect.Slice}, Received: val}
|
||||
}
|
||||
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Array:
|
||||
case bsontype.Null:
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return vr.ReadNull()
|
||||
case bsontype.Type(0), bsontype.EmbeddedDocument:
|
||||
if val.Type().Elem() != tE {
|
||||
return fmt.Errorf("cannot decode document into %s", val.Type())
|
||||
}
|
||||
case bsontype.Binary:
|
||||
if val.Type().Elem() != tByte {
|
||||
return fmt.Errorf("SliceDecodeValue can only decode a binary into a byte array, got %v", vrType)
|
||||
}
|
||||
data, subtype, err := vr.ReadBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld {
|
||||
return fmt.Errorf("SliceDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", bsontype.Binary, subtype)
|
||||
}
|
||||
|
||||
if val.IsNil() {
|
||||
val.Set(reflect.MakeSlice(val.Type(), 0, len(data)))
|
||||
}
|
||||
|
||||
val.SetLen(0)
|
||||
for _, elem := range data {
|
||||
val.Set(reflect.Append(val, reflect.ValueOf(elem)))
|
||||
}
|
||||
return nil
|
||||
case bsontype.String:
|
||||
if val.Type().Elem() != tByte {
|
||||
return fmt.Errorf("SliceDecodeValue can only decode a string into a byte array, got %v", vrType)
|
||||
}
|
||||
str, err := vr.ReadString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
byteStr := []byte(str)
|
||||
|
||||
if val.IsNil() {
|
||||
val.Set(reflect.MakeSlice(val.Type(), 0, len(byteStr)))
|
||||
}
|
||||
|
||||
val.SetLen(0)
|
||||
for _, elem := range byteStr {
|
||||
val.Set(reflect.Append(val, reflect.ValueOf(elem)))
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a slice", vrType)
|
||||
}
|
||||
|
||||
var elemsFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) ([]reflect.Value, error)
|
||||
switch val.Type().Elem() {
|
||||
case tE:
|
||||
dc.Ancestor = val.Type()
|
||||
elemsFunc = defaultValueDecoders.decodeD
|
||||
default:
|
||||
elemsFunc = defaultValueDecoders.decodeDefault
|
||||
}
|
||||
|
||||
elems, err := elemsFunc(dc, vr, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.IsNil() {
|
||||
val.Set(reflect.MakeSlice(val.Type(), 0, len(elems)))
|
||||
}
|
||||
|
||||
val.SetLen(0)
|
||||
val.Set(reflect.Append(val, elems...))
|
||||
|
||||
return nil
|
||||
}
|
94
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go
generated
vendored
Normal file
94
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/string_codec.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonoptions"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
)
|
||||
|
||||
var defaultStringCodec = NewStringCodec()
|
||||
|
||||
// StringCodec is the Codec used for struct values.
|
||||
type StringCodec struct {
|
||||
DecodeObjectIDAsHex bool
|
||||
}
|
||||
|
||||
var _ ValueCodec = &StringCodec{}
|
||||
|
||||
// NewStringCodec returns a StringCodec with options opts.
|
||||
func NewStringCodec(opts ...*bsonoptions.StringCodecOptions) *StringCodec {
|
||||
stringOpt := bsonoptions.MergeStringCodecOptions(opts...)
|
||||
return &StringCodec{*stringOpt.DecodeObjectIDAsHex}
|
||||
}
|
||||
|
||||
// EncodeValue is the ValueEncoder for string types.
|
||||
func (sc *StringCodec) EncodeValue(ectx EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if val.Kind() != reflect.String {
|
||||
return ValueEncoderError{
|
||||
Name: "StringEncodeValue",
|
||||
Kinds: []reflect.Kind{reflect.String},
|
||||
Received: val,
|
||||
}
|
||||
}
|
||||
|
||||
return vw.WriteString(val.String())
|
||||
}
|
||||
|
||||
// DecodeValue is the ValueDecoder for string types.
|
||||
func (sc *StringCodec) DecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Kind() != reflect.String {
|
||||
return ValueDecoderError{Name: "StringDecodeValue", Kinds: []reflect.Kind{reflect.String}, Received: val}
|
||||
}
|
||||
var str string
|
||||
var err error
|
||||
switch vr.Type() {
|
||||
case bsontype.String:
|
||||
str, err = vr.ReadString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case bsontype.ObjectID:
|
||||
oid, err := vr.ReadObjectID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sc.DecodeObjectIDAsHex {
|
||||
str = oid.Hex()
|
||||
} else {
|
||||
byteArray := [12]byte(oid)
|
||||
str = string(byteArray[:])
|
||||
}
|
||||
case bsontype.Symbol:
|
||||
str, err = vr.ReadSymbol()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case bsontype.Binary:
|
||||
data, subtype, err := vr.ReadBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld {
|
||||
return fmt.Errorf("SliceDecodeValue can only be used to decode subtype 0x00 or 0x02 for %s, got %v", bsontype.Binary, subtype)
|
||||
}
|
||||
str = string(data)
|
||||
case bsontype.Null:
|
||||
if err = vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a string type", vr.Type())
|
||||
}
|
||||
|
||||
val.SetString(str)
|
||||
return nil
|
||||
}
|
223
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go
generated
vendored
223
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/struct_codec.go
generated
vendored
@@ -12,7 +12,9 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonoptions"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
)
|
||||
@@ -31,24 +33,45 @@ type Zeroer interface {
|
||||
|
||||
// StructCodec is the Codec used for struct values.
|
||||
type StructCodec struct {
|
||||
cache map[reflect.Type]*structDescription
|
||||
l sync.RWMutex
|
||||
parser StructTagParser
|
||||
cache map[reflect.Type]*structDescription
|
||||
l sync.RWMutex
|
||||
parser StructTagParser
|
||||
DecodeZeroStruct bool
|
||||
DecodeDeepZeroInline bool
|
||||
EncodeOmitDefaultStruct bool
|
||||
AllowUnexportedFields bool
|
||||
}
|
||||
|
||||
var _ ValueEncoder = &StructCodec{}
|
||||
var _ ValueDecoder = &StructCodec{}
|
||||
|
||||
// NewStructCodec returns a StructCodec that uses p for struct tag parsing.
|
||||
func NewStructCodec(p StructTagParser) (*StructCodec, error) {
|
||||
func NewStructCodec(p StructTagParser, opts ...*bsonoptions.StructCodecOptions) (*StructCodec, error) {
|
||||
if p == nil {
|
||||
return nil, errors.New("a StructTagParser must be provided to NewStructCodec")
|
||||
}
|
||||
|
||||
return &StructCodec{
|
||||
structOpt := bsonoptions.MergeStructCodecOptions(opts...)
|
||||
|
||||
codec := &StructCodec{
|
||||
cache: make(map[reflect.Type]*structDescription),
|
||||
parser: p,
|
||||
}, nil
|
||||
}
|
||||
|
||||
if structOpt.DecodeZeroStruct != nil {
|
||||
codec.DecodeZeroStruct = *structOpt.DecodeZeroStruct
|
||||
}
|
||||
if structOpt.DecodeDeepZeroInline != nil {
|
||||
codec.DecodeDeepZeroInline = *structOpt.DecodeDeepZeroInline
|
||||
}
|
||||
if structOpt.EncodeOmitDefaultStruct != nil {
|
||||
codec.EncodeOmitDefaultStruct = *structOpt.EncodeOmitDefaultStruct
|
||||
}
|
||||
if structOpt.AllowUnexportedFields != nil {
|
||||
codec.AllowUnexportedFields = *structOpt.AllowUnexportedFields
|
||||
}
|
||||
|
||||
return codec, nil
|
||||
}
|
||||
|
||||
// EncodeValue handles encoding generic struct types.
|
||||
@@ -71,7 +94,31 @@ func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val r
|
||||
if desc.inline == nil {
|
||||
rv = val.Field(desc.idx)
|
||||
} else {
|
||||
rv = val.FieldByIndex(desc.inline)
|
||||
rv, err = fieldByIndexErr(val, desc.inline)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
desc.encoder, rv, err = defaultValueEncoders.lookupElementEncoder(r, desc.encoder, rv)
|
||||
|
||||
if err != nil && err != errInvalidValue {
|
||||
return err
|
||||
}
|
||||
|
||||
if err == errInvalidValue {
|
||||
if desc.omitEmpty {
|
||||
continue
|
||||
}
|
||||
vw2, err := dw.WriteDocumentElement(desc.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = vw2.WriteNull()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if desc.encoder == nil {
|
||||
@@ -80,12 +127,17 @@ func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val r
|
||||
|
||||
encoder := desc.encoder
|
||||
|
||||
iszero := sc.isZero
|
||||
if iz, ok := encoder.(CodecZeroer); ok {
|
||||
iszero = iz.IsTypeZero
|
||||
var isZero bool
|
||||
rvInterface := rv.Interface()
|
||||
if cz, ok := encoder.(CodecZeroer); ok {
|
||||
isZero = cz.IsTypeZero(rvInterface)
|
||||
} else if rv.Kind() == reflect.Interface {
|
||||
// sc.isZero will not treat an interface rv as an interface, so we need to check for the zero interface separately.
|
||||
isZero = rv.IsNil()
|
||||
} else {
|
||||
isZero = sc.isZero(rvInterface)
|
||||
}
|
||||
|
||||
if desc.omitEmpty && iszero(rv.Interface()) {
|
||||
if desc.omitEmpty && isZero {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -108,7 +160,7 @@ func (sc *StructCodec) EncodeValue(r EncodeContext, vw bsonrw.ValueWriter, val r
|
||||
return exists
|
||||
}
|
||||
|
||||
return defaultValueEncoders.mapEncodeValue(r, dw, rv, collisionFn)
|
||||
return defaultMapCodec.mapEncodeValue(r, dw, rv, collisionFn)
|
||||
}
|
||||
|
||||
return dw.WriteDocumentEnd()
|
||||
@@ -122,10 +174,17 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r
|
||||
return ValueDecoderError{Name: "StructCodec.DecodeValue", Kinds: []reflect.Kind{reflect.Struct}, Received: val}
|
||||
}
|
||||
|
||||
switch vr.Type() {
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Type(0), bsontype.EmbeddedDocument:
|
||||
case bsontype.Null:
|
||||
if err := vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a %s", vr.Type(), val.Type())
|
||||
return fmt.Errorf("cannot decode %v into a %s", vrType, val.Type())
|
||||
}
|
||||
|
||||
sd, err := sc.describeStruct(r.Registry, val.Type())
|
||||
@@ -133,13 +192,17 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r
|
||||
return err
|
||||
}
|
||||
|
||||
if sc.DecodeZeroStruct {
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
}
|
||||
if sc.DecodeDeepZeroInline && sd.inline {
|
||||
val.Set(deepZero(val.Type()))
|
||||
}
|
||||
|
||||
var decoder ValueDecoder
|
||||
var inlineMap reflect.Value
|
||||
if sd.inlineMap >= 0 {
|
||||
inlineMap = val.Field(sd.inlineMap)
|
||||
if inlineMap.IsNil() {
|
||||
inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
|
||||
}
|
||||
decoder, err = r.LookupDecoder(inlineMap.Type().Elem())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -179,7 +242,12 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r
|
||||
continue
|
||||
}
|
||||
|
||||
if inlineMap.IsNil() {
|
||||
inlineMap.Set(reflect.MakeMap(inlineMap.Type()))
|
||||
}
|
||||
|
||||
elem := reflect.New(inlineMap.Type().Elem()).Elem()
|
||||
r.Ancestor = inlineMap.Type()
|
||||
err = decoder.DecodeValue(r, vr, elem)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -192,7 +260,10 @@ func (sc *StructCodec) DecodeValue(r DecodeContext, vr bsonrw.ValueReader, val r
|
||||
if fd.inline == nil {
|
||||
field = val.Field(fd.idx)
|
||||
} else {
|
||||
field = val.FieldByIndex(fd.inline)
|
||||
field, err = getInlineField(val, fd.inline)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !field.CanSet() { // Being settable is a super set of being addressable.
|
||||
@@ -249,6 +320,23 @@ func (sc *StructCodec) isZero(i interface{}) bool {
|
||||
return v.Float() == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
return v.IsNil()
|
||||
case reflect.Struct:
|
||||
if sc.EncodeOmitDefaultStruct {
|
||||
vt := v.Type()
|
||||
if vt == tTime {
|
||||
return v.Interface().(time.Time).IsZero()
|
||||
}
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
if vt.Field(i).PkgPath != "" && !vt.Field(i).Anonymous {
|
||||
continue // Private field
|
||||
}
|
||||
fld := v.Field(i)
|
||||
if !sc.isZero(fld.Interface()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
@@ -258,6 +346,7 @@ type structDescription struct {
|
||||
fm map[string]fieldDescription
|
||||
fl []fieldDescription
|
||||
inlineMap int
|
||||
inline bool
|
||||
}
|
||||
|
||||
type fieldDescription struct {
|
||||
@@ -290,16 +379,17 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr
|
||||
|
||||
for i := 0; i < numFields; i++ {
|
||||
sf := t.Field(i)
|
||||
if sf.PkgPath != "" {
|
||||
// unexported, ignore
|
||||
if sf.PkgPath != "" && (!sc.AllowUnexportedFields || !sf.Anonymous) {
|
||||
// field is private or unexported fields aren't allowed, ignore
|
||||
continue
|
||||
}
|
||||
|
||||
encoder, err := r.LookupEncoder(sf.Type)
|
||||
sfType := sf.Type
|
||||
encoder, err := r.LookupEncoder(sfType)
|
||||
if err != nil {
|
||||
encoder = nil
|
||||
}
|
||||
decoder, err := r.LookupDecoder(sf.Type)
|
||||
decoder, err := r.LookupDecoder(sfType)
|
||||
if err != nil {
|
||||
decoder = nil
|
||||
}
|
||||
@@ -319,17 +409,24 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr
|
||||
description.truncate = stags.Truncate
|
||||
|
||||
if stags.Inline {
|
||||
switch sf.Type.Kind() {
|
||||
sd.inline = true
|
||||
switch sfType.Kind() {
|
||||
case reflect.Map:
|
||||
if sd.inlineMap >= 0 {
|
||||
return nil, errors.New("(struct " + t.String() + ") multiple inline maps")
|
||||
}
|
||||
if sf.Type.Key() != tString {
|
||||
if sfType.Key() != tString {
|
||||
return nil, errors.New("(struct " + t.String() + ") inline map must have a string keys")
|
||||
}
|
||||
sd.inlineMap = description.idx
|
||||
case reflect.Ptr:
|
||||
sfType = sfType.Elem()
|
||||
if sfType.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("(struct %s) inline fields must be a struct, a struct pointer, or a map", t.String())
|
||||
}
|
||||
fallthrough
|
||||
case reflect.Struct:
|
||||
inlinesf, err := sc.describeStruct(r, sf.Type)
|
||||
inlinesf, err := sc.describeStruct(r, sfType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -346,7 +443,7 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr
|
||||
sd.fl = append(sd.fl, fd)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("(struct %s) inline fields must be either a struct or a map", t.String())
|
||||
return nil, fmt.Errorf("(struct %s) inline fields must be a struct, a struct pointer, or a map", t.String())
|
||||
}
|
||||
continue
|
||||
}
|
||||
@@ -365,3 +462,75 @@ func (sc *StructCodec) describeStruct(r *Registry, t reflect.Type) (*structDescr
|
||||
|
||||
return sd, nil
|
||||
}
|
||||
|
||||
func fieldByIndexErr(v reflect.Value, index []int) (result reflect.Value, err error) {
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
switch r := recovered.(type) {
|
||||
case string:
|
||||
err = fmt.Errorf("%s", r)
|
||||
case error:
|
||||
err = r
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
result = v.FieldByIndex(index)
|
||||
return
|
||||
}
|
||||
|
||||
func getInlineField(val reflect.Value, index []int) (reflect.Value, error) {
|
||||
field, err := fieldByIndexErr(val, index)
|
||||
if err == nil {
|
||||
return field, nil
|
||||
}
|
||||
|
||||
// if parent of this element doesn't exist, fix its parent
|
||||
inlineParent := index[:len(index)-1]
|
||||
var fParent reflect.Value
|
||||
if fParent, err = fieldByIndexErr(val, inlineParent); err != nil {
|
||||
fParent, err = getInlineField(val, inlineParent)
|
||||
if err != nil {
|
||||
return fParent, err
|
||||
}
|
||||
}
|
||||
fParent.Set(reflect.New(fParent.Type().Elem()))
|
||||
|
||||
return fieldByIndexErr(val, index)
|
||||
}
|
||||
|
||||
// DeepZero returns recursive zero object
|
||||
func deepZero(st reflect.Type) (result reflect.Value) {
|
||||
result = reflect.Indirect(reflect.New(st))
|
||||
|
||||
if result.Kind() == reflect.Struct {
|
||||
for i := 0; i < result.NumField(); i++ {
|
||||
if f := result.Field(i); f.Kind() == reflect.Ptr {
|
||||
if f.CanInterface() {
|
||||
if ft := reflect.TypeOf(f.Interface()); ft.Elem().Kind() == reflect.Struct {
|
||||
result.Field(i).Set(recursivePointerTo(deepZero(ft.Elem())))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// recursivePointerTo calls reflect.New(v.Type) but recursively for its fields inside
|
||||
func recursivePointerTo(v reflect.Value) reflect.Value {
|
||||
v = reflect.Indirect(v)
|
||||
result := reflect.New(v.Type())
|
||||
if v.Kind() == reflect.Struct {
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
if f := v.Field(i); f.Kind() == reflect.Ptr {
|
||||
if f.Elem().Kind() == reflect.Struct {
|
||||
result.Elem().Field(i).Set(recursivePointerTo(f))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
101
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go
generated
vendored
Normal file
101
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/time_codec.go
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonoptions"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
)
|
||||
|
||||
const (
|
||||
timeFormatString = "2006-01-02T15:04:05.999Z07:00"
|
||||
)
|
||||
|
||||
var defaultTimeCodec = NewTimeCodec()
|
||||
|
||||
// TimeCodec is the Codec used for time.Time values.
|
||||
type TimeCodec struct {
|
||||
UseLocalTimeZone bool
|
||||
}
|
||||
|
||||
var _ ValueCodec = &TimeCodec{}
|
||||
|
||||
// NewTimeCodec returns a TimeCodec with options opts.
|
||||
func NewTimeCodec(opts ...*bsonoptions.TimeCodecOptions) *TimeCodec {
|
||||
timeOpt := bsonoptions.MergeTimeCodecOptions(opts...)
|
||||
|
||||
codec := TimeCodec{}
|
||||
if timeOpt.UseLocalTimeZone != nil {
|
||||
codec.UseLocalTimeZone = *timeOpt.UseLocalTimeZone
|
||||
}
|
||||
return &codec
|
||||
}
|
||||
|
||||
// DecodeValue is the ValueDecoderFunc for time.Time.
|
||||
func (tc *TimeCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() || val.Type() != tTime {
|
||||
return ValueDecoderError{Name: "TimeDecodeValue", Types: []reflect.Type{tTime}, Received: val}
|
||||
}
|
||||
|
||||
var timeVal time.Time
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.DateTime:
|
||||
dt, err := vr.ReadDateTime()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
timeVal = time.Unix(dt/1000, dt%1000*1000000)
|
||||
case bsontype.String:
|
||||
// assume strings are in the isoTimeFormat
|
||||
timeStr, err := vr.ReadString()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
timeVal, err = time.Parse(timeFormatString, timeStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case bsontype.Int64:
|
||||
i64, err := vr.ReadInt64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
timeVal = time.Unix(i64/1000, i64%1000*1000000)
|
||||
case bsontype.Timestamp:
|
||||
t, _, err := vr.ReadTimestamp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
timeVal = time.Unix(int64(t), 0)
|
||||
case bsontype.Null:
|
||||
if err := vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into a time.Time", vrType)
|
||||
}
|
||||
|
||||
if !tc.UseLocalTimeZone {
|
||||
timeVal = timeVal.UTC()
|
||||
}
|
||||
val.Set(reflect.ValueOf(timeVal))
|
||||
return nil
|
||||
}
|
||||
|
||||
// EncodeValue is the ValueEncoderFunc for time.TIme.
|
||||
func (tc *TimeCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
if !val.IsValid() || val.Type() != tTime {
|
||||
return ValueEncoderError{Name: "TimeEncodeValue", Types: []reflect.Type{tTime}, Received: val}
|
||||
}
|
||||
tt := val.Interface().(time.Time)
|
||||
return vw.WriteDateTime(tt.Unix()*1000 + int64(tt.Nanosecond()/1e6))
|
||||
}
|
1
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go
generated
vendored
1
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/types.go
generated
vendored
@@ -74,6 +74,7 @@ var tDecimal = reflect.TypeOf(primitive.Decimal128{})
|
||||
var tMinKey = reflect.TypeOf(primitive.MinKey{})
|
||||
var tMaxKey = reflect.TypeOf(primitive.MaxKey{})
|
||||
var tD = reflect.TypeOf(primitive.D{})
|
||||
var tM = reflect.TypeOf(primitive.M{})
|
||||
var tA = reflect.TypeOf(primitive.A{})
|
||||
var tE = reflect.TypeOf(primitive.E{})
|
||||
|
||||
|
150
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go
generated
vendored
Normal file
150
vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/uint_codec.go
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright (C) MongoDB, Inc. 2017-present.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
package bsoncodec
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/bsonoptions"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
)
|
||||
|
||||
var defaultUIntCodec = NewUIntCodec()
|
||||
|
||||
// UIntCodec is the Codec used for uint values.
|
||||
type UIntCodec struct {
|
||||
EncodeToMinSize bool
|
||||
}
|
||||
|
||||
var _ ValueCodec = &UIntCodec{}
|
||||
|
||||
// NewUIntCodec returns a UIntCodec with options opts.
|
||||
func NewUIntCodec(opts ...*bsonoptions.UIntCodecOptions) *UIntCodec {
|
||||
uintOpt := bsonoptions.MergeUIntCodecOptions(opts...)
|
||||
|
||||
codec := UIntCodec{}
|
||||
if uintOpt.EncodeToMinSize != nil {
|
||||
codec.EncodeToMinSize = *uintOpt.EncodeToMinSize
|
||||
}
|
||||
return &codec
|
||||
}
|
||||
|
||||
// EncodeValue is the ValueEncoder for uint types.
|
||||
func (uic *UIntCodec) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
|
||||
switch val.Kind() {
|
||||
case reflect.Uint8, reflect.Uint16:
|
||||
return vw.WriteInt32(int32(val.Uint()))
|
||||
case reflect.Uint, reflect.Uint32, reflect.Uint64:
|
||||
u64 := val.Uint()
|
||||
|
||||
// If ec.MinSize or if encodeToMinSize is true for a non-uint64 value we should write val as an int32
|
||||
useMinSize := ec.MinSize || (uic.EncodeToMinSize && val.Kind() != reflect.Uint64)
|
||||
|
||||
if u64 <= math.MaxInt32 && useMinSize {
|
||||
return vw.WriteInt32(int32(u64))
|
||||
}
|
||||
if u64 > math.MaxInt64 {
|
||||
return fmt.Errorf("%d overflows int64", u64)
|
||||
}
|
||||
return vw.WriteInt64(int64(u64))
|
||||
}
|
||||
|
||||
return ValueEncoderError{
|
||||
Name: "UintEncodeValue",
|
||||
Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
|
||||
Received: val,
|
||||
}
|
||||
}
|
||||
|
||||
// DecodeValue is the ValueDecoder for uint types.
|
||||
func (uic *UIntCodec) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if !val.CanSet() {
|
||||
return ValueDecoderError{
|
||||
Name: "UintDecodeValue",
|
||||
Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
|
||||
Received: val,
|
||||
}
|
||||
}
|
||||
|
||||
var i64 int64
|
||||
var err error
|
||||
switch vrType := vr.Type(); vrType {
|
||||
case bsontype.Int32:
|
||||
i32, err := vr.ReadInt32()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i64 = int64(i32)
|
||||
case bsontype.Int64:
|
||||
i64, err = vr.ReadInt64()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case bsontype.Double:
|
||||
f64, err := vr.ReadDouble()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !dc.Truncate && math.Floor(f64) != f64 {
|
||||
return errors.New("UintDecodeValue can only truncate float64 to an integer type when truncation is enabled")
|
||||
}
|
||||
if f64 > float64(math.MaxInt64) {
|
||||
return fmt.Errorf("%g overflows int64", f64)
|
||||
}
|
||||
i64 = int64(f64)
|
||||
case bsontype.Boolean:
|
||||
b, err := vr.ReadBoolean()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b {
|
||||
i64 = 1
|
||||
}
|
||||
case bsontype.Null:
|
||||
if err = vr.ReadNull(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("cannot decode %v into an integer type", vrType)
|
||||
}
|
||||
|
||||
switch val.Kind() {
|
||||
case reflect.Uint8:
|
||||
if i64 < 0 || i64 > math.MaxUint8 {
|
||||
return fmt.Errorf("%d overflows uint8", i64)
|
||||
}
|
||||
case reflect.Uint16:
|
||||
if i64 < 0 || i64 > math.MaxUint16 {
|
||||
return fmt.Errorf("%d overflows uint16", i64)
|
||||
}
|
||||
case reflect.Uint32:
|
||||
if i64 < 0 || i64 > math.MaxUint32 {
|
||||
return fmt.Errorf("%d overflows uint32", i64)
|
||||
}
|
||||
case reflect.Uint64:
|
||||
if i64 < 0 {
|
||||
return fmt.Errorf("%d overflows uint64", i64)
|
||||
}
|
||||
case reflect.Uint:
|
||||
if i64 < 0 || int64(uint(i64)) != i64 { // Can we fit this inside of an uint
|
||||
return fmt.Errorf("%d overflows uint", i64)
|
||||
}
|
||||
default:
|
||||
return ValueDecoderError{
|
||||
Name: "UintDecodeValue",
|
||||
Kinds: []reflect.Kind{reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint},
|
||||
Received: val,
|
||||
}
|
||||
}
|
||||
|
||||
val.SetUint(uint64(i64))
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user