Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
qingyang-hu committed May 20, 2024
1 parent 7938e90 commit b2a1c15
Show file tree
Hide file tree
Showing 30 changed files with 521 additions and 798 deletions.
6 changes: 1 addition & 5 deletions bson/array_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ import (
// arrayCodec is the Codec used for bsoncore.Array values.
type arrayCodec struct{}

var (
defaultArrayCodec = &arrayCodec{}
)

// EncodeValue is the ValueEncoder for bsoncore.Array values.
func (ac *arrayCodec) EncodeValue(_ EncoderRegistry, vw ValueWriter, val reflect.Value) error {
if !val.IsValid() || val.Type() != tCoreArray {
Expand All @@ -30,7 +26,7 @@ func (ac *arrayCodec) EncodeValue(_ EncoderRegistry, vw ValueWriter, val reflect
}

// DecodeValue is the ValueDecoder for bsoncore.Array values.
func (ac *arrayCodec) DecodeValue(_ DecodeContext, vr ValueReader, val reflect.Value) error {
func (ac *arrayCodec) DecodeValue(_ DecoderRegistry, vr ValueReader, val reflect.Value) error {
if !val.CanSet() || val.Type() != tCoreArray {
return ValueDecoderError{Name: "CoreArrayDecodeValue", Types: []reflect.Type{tCoreArray}, Received: val}
}
Expand Down
42 changes: 13 additions & 29 deletions bson/bsoncodec.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,6 @@ func (vde ValueDecoderError) Error() string {
type DecodeContext struct {
*Registry

// ancestor is the type of a containing document. This is mainly used to determine what type
// should be used when decoding an embedded document into an empty interface. For example, if
// Ancestor is a bson.M, BSON embedded document values being decoded into an empty interface
// will be decoded into a bson.M.
ancestor reflect.Type

// defaultDocumentType specifies the Go type to decode top-level and nested BSON documents into. In particular, the
// usage for this field is restricted to data typed as "interface{}" or "map[string]interface{}". If DocumentType is
// set to a type that a BSON document cannot be unmarshaled into (e.g. "string"), unmarshalling will result in an
Expand Down Expand Up @@ -138,28 +132,28 @@ type DecoderRegistry interface {
// ValueDecoder. A DecodeContext instance is provided and serves similar functionality to the
// EncodeContext.
type ValueDecoder interface {
DecodeValue(DecodeContext, ValueReader, reflect.Value) error
DecodeValue(DecoderRegistry, ValueReader, reflect.Value) error
}

// ValueDecoderFunc is an adapter function that allows a function with the correct signature to be
// used as a ValueDecoder.
type ValueDecoderFunc func(DecodeContext, ValueReader, reflect.Value) error
type ValueDecoderFunc func(DecoderRegistry, ValueReader, reflect.Value) error

// DecodeValue implements the ValueDecoder interface.
func (fn ValueDecoderFunc) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
return fn(dc, vr, val)
func (fn ValueDecoderFunc) DecodeValue(reg DecoderRegistry, vr ValueReader, val reflect.Value) error {
return fn(reg, vr, val)
}

// typeDecoder is the interface implemented by types that can handle the decoding of a value given its type.
type typeDecoder interface {
decodeType(DecodeContext, ValueReader, reflect.Type) (reflect.Value, error)
decodeType(DecoderRegistry, ValueReader, reflect.Type) (reflect.Value, error)
}

// typeDecoderFunc is an adapter function that allows a function with the correct signature to be used as a typeDecoder.
type typeDecoderFunc func(DecodeContext, ValueReader, reflect.Type) (reflect.Value, error)
type typeDecoderFunc func(DecoderRegistry, ValueReader, reflect.Type) (reflect.Value, error)

func (fn typeDecoderFunc) decodeType(dc DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
return fn(dc, vr, t)
func (fn typeDecoderFunc) decodeType(reg DecoderRegistry, vr ValueReader, t reflect.Type) (reflect.Value, error) {
return fn(reg, vr, t)
}

// decodeAdapter allows two functions with the correct signatures to be used as both a ValueDecoder and typeDecoder.
Expand All @@ -171,24 +165,14 @@ type decodeAdapter struct {
var _ ValueDecoder = decodeAdapter{}
var _ typeDecoder = decodeAdapter{}

func decodeTypeOrValueWithInfo(vd ValueDecoder, dc DecodeContext, vr ValueReader, t reflect.Type, convert bool) (reflect.Value, error) {
if td := vd.(typeDecoder); td != nil {
val, err := td.decodeType(dc, vr, t)
if err == nil && convert && val.Type() != t {
// This conversion step is necessary for slices and maps. If a user declares variables like:
//
// type myBool bool
// var m map[string]myBool
//
// and tries to decode BSON bytes into the map, the decoding will fail if this conversion is not present
// because we'll try to assign a value of type bool to one of type myBool.
val = val.Convert(t)
}
return val, err
func decodeTypeOrValueWithInfo(vd ValueDecoder, reg DecoderRegistry, vr ValueReader, t reflect.Type) (reflect.Value, error) {
td, ok := vd.(typeDecoder)
if ok && td != nil {
return td.decodeType(reg, vr, t)
}

val := reflect.New(t).Elem()
err := vd.DecodeValue(dc, vr, val)
err := vd.DecodeValue(reg, vr, val)
return val, err
}

Expand Down
4 changes: 2 additions & 2 deletions bson/bsoncodec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type llCodec struct {
err error
}

func (llc *llCodec) EncodeValue(_ *Registry, _ ValueWriter, i interface{}) error {
func (llc *llCodec) EncodeValue(_ EncoderRegistry, _ ValueWriter, i interface{}) error {
if llc.err != nil {
return llc.err
}
Expand All @@ -27,7 +27,7 @@ func (llc *llCodec) EncodeValue(_ *Registry, _ ValueWriter, i interface{}) error
return nil
}

func (llc *llCodec) DecodeValue(_ DecodeContext, _ ValueReader, val reflect.Value) error {
func (llc *llCodec) DecodeValue(_ DecoderRegistry, _ ValueReader, val reflect.Value) error {
if llc.err != nil {
return llc.err
}
Expand Down
10 changes: 3 additions & 7 deletions bson/byte_slice_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ type byteSliceCodec struct {
encodeNilAsEmpty bool
}

var (
defaultByteSliceCodec = &byteSliceCodec{}
)

// EncodeValue is the ValueEncoder for []byte.
func (bsc *byteSliceCodec) EncodeValue(_ EncoderRegistry, vw ValueWriter, val reflect.Value) error {
if !val.IsValid() || val.Type() != tByteSlice {
Expand All @@ -33,7 +29,7 @@ func (bsc *byteSliceCodec) EncodeValue(_ EncoderRegistry, vw ValueWriter, val re
return vw.WriteBinary(val.Interface().([]byte))
}

func (bsc *byteSliceCodec) decodeType(_ DecodeContext, vr ValueReader, t reflect.Type) (reflect.Value, error) {
func (bsc *byteSliceCodec) decodeType(_ DecoderRegistry, vr ValueReader, t reflect.Type) (reflect.Value, error) {
if t != tByteSlice {
return emptyValue, ValueDecoderError{
Name: "ByteSliceDecodeValue",
Expand Down Expand Up @@ -81,12 +77,12 @@ func (bsc *byteSliceCodec) decodeType(_ DecodeContext, vr ValueReader, t reflect
}

// DecodeValue is the ValueDecoder for []byte.
func (bsc *byteSliceCodec) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
func (bsc *byteSliceCodec) DecodeValue(reg DecoderRegistry, vr ValueReader, val reflect.Value) error {
if !val.CanSet() || val.Type() != tByteSlice {
return ValueDecoderError{Name: "ByteSliceDecodeValue", Types: []reflect.Type{tByteSlice}, Received: val}
}

elem, err := bsc.decodeType(dc, vr, tByteSlice)
elem, err := bsc.decodeType(reg, vr, tByteSlice)
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions bson/cond_addr_codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ type condAddrDecoder struct {
var _ ValueDecoder = (*condAddrDecoder)(nil)

// DecodeValue is the ValueDecoderFunc for a value that may be addressable.
func (cad *condAddrDecoder) DecodeValue(dc DecodeContext, vr ValueReader, val reflect.Value) error {
func (cad *condAddrDecoder) DecodeValue(reg DecoderRegistry, vr ValueReader, val reflect.Value) error {
if val.CanAddr() {
return cad.canAddrDec.DecodeValue(dc, vr, val)
return cad.canAddrDec.DecodeValue(reg, vr, val)
}
if cad.elseDec != nil {
return cad.elseDec.DecodeValue(dc, vr, val)
return cad.elseDec.DecodeValue(reg, vr, val)
}
return ErrNoDecoder{Type: val.Type()}
}
4 changes: 2 additions & 2 deletions bson/cond_addr_codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ func TestCondAddrCodec(t *testing.T) {
})
t.Run("addressDecode", func(t *testing.T) {
invoked := 0
decode1 := ValueDecoderFunc(func(DecodeContext, ValueReader, reflect.Value) error {
decode1 := ValueDecoderFunc(func(DecoderRegistry, ValueReader, reflect.Value) error {
invoked = 1
return nil
})
decode2 := ValueDecoderFunc(func(DecodeContext, ValueReader, reflect.Value) error {
decode2 := ValueDecoderFunc(func(DecoderRegistry, ValueReader, reflect.Value) error {
invoked = 2
return nil
})
Expand Down
Loading

0 comments on commit b2a1c15

Please sign in to comment.