Skip to content

Commit 55b6219

Browse files
authored
Merge pull request globalsign#54 from joomcode/feature/primitive-5
INFRA-4180: Replace custom marshaling interfaces
2 parents 95a09a3 + 7fdcaff commit 55b6219

File tree

4 files changed

+126
-53
lines changed

4 files changed

+126
-53
lines changed

bson/bson.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,25 @@ const (
9393
BinaryUserDefined = bsontype.BinaryUserDefined
9494
)
9595

96+
// deprecated
97+
//
98+
// Use bson.ValueMarshaler
99+
//
96100
// Getter interface: a value implementing the bson.Getter interface will have its GetBSON
97101
// method called when the given value has to be marshalled, and the result
98102
// of this method will be marshaled in place of the actual object.
99103
//
100104
// If GetBSON returns return a non-nil error, the marshalling procedure
101105
// will stop and error out with the provided value.
102106
type Getter interface {
107+
// deprecated
103108
GetBSON() (interface{}, error)
104109
}
105110

111+
// deprecated
112+
//
113+
// Use bson.ValueUnmarshaler
114+
//
106115
// Setter interface: a value implementing the bson.Setter interface will receive the BSON
107116
// value via the SetBSON method during unmarshaling, and the object
108117
// itself will not be changed as usual.
@@ -131,6 +140,7 @@ type Getter interface {
131140
// }
132141
//
133142
type Setter interface {
143+
// deprecated
134144
SetBSON(raw Raw) error
135145
}
136146

bson/bson_test.go

Lines changed: 71 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ import (
3939
"testing"
4040
"time"
4141

42-
"go.mongodb.org/mongo-driver/bson/bsontype"
43-
4442
"github.com/joomcode/mgo/bson"
43+
"go.mongodb.org/mongo-driver/bson/bsontype"
44+
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
4545
. "gopkg.in/check.v1"
4646
)
4747

@@ -462,15 +462,19 @@ func (s *S) Test64bitInt(c *C) {
462462
type prefixPtr string
463463
type prefixVal string
464464

465-
func (t *prefixPtr) GetBSON() (interface{}, error) {
465+
func (t *prefixPtr) MarshalBSONValue() (bsontype.Type, []byte, error) {
466466
if t == nil {
467-
return nil, nil
467+
return bsontype.Null, nil, nil
468468
}
469-
return "foo-" + string(*t), nil
469+
return bsontype.String, bsoncore.AppendString(nil, "foo-"+string(*t)), nil
470470
}
471471

472-
func (t *prefixPtr) SetBSON(raw bson.Raw) error {
472+
func (t *prefixPtr) UnmarshalBSONValue(btype bsontype.Type, data []byte) error {
473473
var s string
474+
raw := bson.Raw{
475+
Type: btype,
476+
Value: data,
477+
}
474478
if raw.Type == 0x0A {
475479
return bson.ErrSetZero
476480
}
@@ -484,12 +488,16 @@ func (t *prefixPtr) SetBSON(raw bson.Raw) error {
484488
return nil
485489
}
486490

487-
func (t prefixVal) GetBSON() (interface{}, error) {
488-
return "foo-" + string(t), nil
491+
func (t prefixVal) MarshalBSONValue() (bsontype.Type, []byte, error) {
492+
return bsontype.String, bsoncore.AppendString(nil, "foo-"+string(t)), nil
489493
}
490494

491-
func (t *prefixVal) SetBSON(raw bson.Raw) error {
495+
func (t *prefixVal) UnmarshalBSONValue(btype bsontype.Type, data []byte) error {
492496
var s string
497+
raw := bson.Raw{
498+
Type: btype,
499+
Value: data,
500+
}
493501
if raw.Type == 0x0A {
494502
return bson.ErrSetZero
495503
}
@@ -902,8 +910,8 @@ type setterType struct {
902910
received interface{}
903911
}
904912

905-
func (o *setterType) SetBSON(raw bson.Raw) error {
906-
err := bson.RawUnmarshal(raw, &o.received)
913+
func (o *setterType) UnmarshalBSONValue(btype bsontype.Type, data []byte) error {
914+
err := bson.RawUnmarshal(bson.Raw{Type: btype, Value: data}, &o.received)
907915
if err != nil {
908916
panic("The panic:" + err.Error())
909917
}
@@ -1032,11 +1040,21 @@ type typeWithGetter struct {
10321040
err error
10331041
}
10341042

1035-
func (t *typeWithGetter) GetBSON() (interface{}, error) {
1043+
func (t *typeWithGetter) MarshalBSONValue() (bsontype.Type, []byte, error) {
10361044
if t == nil {
1037-
return "<value is nil>", nil
1045+
return bsontype.String, bsoncore.AppendString(nil, "<value is nil>"), nil
1046+
}
1047+
1048+
doc, err := bson.Marshal(struct {
1049+
V interface{} `bson:"v"`
1050+
}{
1051+
V: t.result,
1052+
})
1053+
if err != nil {
1054+
panic(err)
10381055
}
1039-
return t.result, t.err
1056+
element, _, _ := bsoncore.ReadElement(doc[4:])
1057+
return element.Value().Type, element.Value().Data, t.err
10401058
}
10411059

10421060
type docWithGetterField struct {
@@ -1081,8 +1099,8 @@ func (s *S) TestGetterErrors(c *C) {
10811099

10821100
type intGetter int64
10831101

1084-
func (t intGetter) GetBSON() (interface{}, error) {
1085-
return int64(t), nil
1102+
func (t intGetter) MarshalBSONValue() (bsontype.Type, []byte, error) {
1103+
return bsontype.Int32, bsoncore.AppendInt32(nil, int32(t)), nil
10861104
}
10871105

10881106
type typeWithIntGetter struct {
@@ -1226,30 +1244,46 @@ type unexported struct {
12261244

12271245
type getterSetterD bson.D
12281246

1229-
func (s getterSetterD) GetBSON() (interface{}, error) {
1230-
if len(s) == 0 {
1231-
return bson.D{}, nil
1247+
func (s getterSetterD) MarshalBSONValue() (bsontype.Type, []byte, error) {
1248+
var d bson.D
1249+
if len(s) != 0 {
1250+
d = bson.D(s[:len(s)-1])
1251+
}
1252+
data, err := bson.Marshal(d)
1253+
if err != nil {
1254+
panic(err)
12321255
}
1233-
return bson.D(s[:len(s)-1]), nil
1256+
return bsontype.EmbeddedDocument, data, nil
12341257
}
12351258

1236-
func (s *getterSetterD) SetBSON(raw bson.Raw) error {
1259+
func (s *getterSetterD) UnmarshalBSONValue(btype bsontype.Type, data []byte) error {
12371260
var doc bson.D
1238-
err := bson.RawUnmarshal(raw, &doc)
1261+
err := bson.RawUnmarshal(bson.Raw{
1262+
Type: btype,
1263+
Value: data,
1264+
}, &doc)
12391265
doc = append(doc, bson.DocElem{Key: "suffix", Value: true})
12401266
*s = getterSetterD(doc)
12411267
return err
12421268
}
12431269

12441270
type getterSetterInt int
12451271

1246-
func (i getterSetterInt) GetBSON() (interface{}, error) {
1247-
return bson.D{{Key: "a", Value: int(i)}}, nil
1272+
func (i getterSetterInt) MarshalBSONValue() (bsontype.Type, []byte, error) {
1273+
d := bson.D{{Key: "a", Value: int(i)}}
1274+
data, err := bson.Marshal(d)
1275+
if err != nil {
1276+
panic(err)
1277+
}
1278+
return bsontype.EmbeddedDocument, data, nil
12481279
}
12491280

1250-
func (i *getterSetterInt) SetBSON(raw bson.Raw) error {
1281+
func (i *getterSetterInt) UnmarshalBSONValue(btype bsontype.Type, data []byte) error {
12511282
var doc struct{ A int }
1252-
err := bson.RawUnmarshal(raw, &doc)
1283+
err := bson.RawUnmarshal(bson.Raw{
1284+
Type: btype,
1285+
Value: data,
1286+
}, &doc)
12531287
*i = getterSetterInt(doc.A)
12541288
return err
12551289
}
@@ -1260,17 +1294,24 @@ type ifaceType interface {
12601294

12611295
type ifaceSlice []ifaceType
12621296

1263-
func (s *ifaceSlice) SetBSON(raw bson.Raw) error {
1297+
func (s *ifaceSlice) UnmarshalBSONValue(btype bsontype.Type, data []byte) error {
12641298
var ns []int
1265-
if err := bson.RawUnmarshal(raw, &ns); err != nil {
1299+
if err := bson.RawUnmarshal(bson.Raw{
1300+
Type: btype,
1301+
Value: data,
1302+
}, &ns); err != nil {
12661303
return err
12671304
}
12681305
*s = make(ifaceSlice, ns[0])
12691306
return nil
12701307
}
12711308

1272-
func (s ifaceSlice) GetBSON() (interface{}, error) {
1273-
return []int{len(s)}, nil
1309+
func (s ifaceSlice) MarshalBSONValue() (bsontype.Type, []byte, error) {
1310+
var data []byte
1311+
idx, data := bsoncore.AppendArrayStart(data)
1312+
data = bsoncore.AppendInt32Element(data, "1", int32(len(s)))
1313+
data, _ = bsoncore.AppendArrayEnd(data, idx)
1314+
return bsontype.Array, data, nil
12741315
}
12751316

12761317
type omitEmptyAware struct {

bson/decode.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"sync"
3939
"time"
4040

41+
"go.mongodb.org/mongo-driver/bson"
4142
"go.mongodb.org/mongo-driver/bson/bsontype"
4243
"go.mongodb.org/mongo-driver/bson/primitive"
4344
)
@@ -72,12 +73,15 @@ const (
7273
)
7374

7475
var setterStyles map[reflect.Type]int
75-
var setterIface reflect.Type
76+
var setterIfaceLegacy reflect.Type
77+
var setterIfaceHipster reflect.Type
7678
var setterMutex sync.RWMutex
7779

7880
func init() {
79-
var iface Setter
80-
setterIface = reflect.TypeOf(&iface).Elem()
81+
var ifaceLegacy Setter
82+
var ifaceHipster bson.ValueUnmarshaler
83+
setterIfaceLegacy = reflect.TypeOf(&ifaceLegacy).Elem()
84+
setterIfaceHipster = reflect.TypeOf(&ifaceHipster).Elem()
8185
setterStyles = make(map[reflect.Type]int)
8286
}
8387

@@ -91,18 +95,22 @@ func setterStyle(outt reflect.Type) int {
9195

9296
setterMutex.Lock()
9397
defer setterMutex.Unlock()
94-
if outt.Implements(setterIface) {
98+
if outt.Implements(setterIfaceHipster) {
9599
style = setterType
96-
} else if reflect.PtrTo(outt).Implements(setterIface) {
100+
} else if reflect.PtrTo(outt).Implements(setterIfaceHipster) {
97101
style = setterAddr
102+
} else if outt.Implements(setterIfaceLegacy) {
103+
panic(fmt.Errorf("Type %q implements %q but not implements %q", outt.String(), setterIfaceLegacy.String(), setterIfaceHipster.String()))
104+
} else if reflect.PtrTo(outt).Implements(setterIfaceLegacy) {
105+
panic(fmt.Errorf("Type %q implements %q but not implements %q", outt.String(), setterIfaceLegacy.String(), setterIfaceHipster.String()))
98106
} else {
99107
style = setterNone
100108
}
101109
setterStyles[outt] = style
102110
return style
103111
}
104112

105-
func getSetter(outt reflect.Type, out reflect.Value) Setter {
113+
func getSetter(outt reflect.Type, out reflect.Value) bson.ValueUnmarshaler {
106114
style := setterStyle(outt)
107115
if style == setterNone {
108116
return nil
@@ -115,7 +123,7 @@ func getSetter(outt reflect.Type, out reflect.Value) Setter {
115123
} else if outt.Kind() == reflect.Ptr && out.IsNil() {
116124
out.Set(reflect.New(outt.Elem()))
117125
}
118-
return out.Interface().(Setter)
126+
return out.Interface().(bson.ValueUnmarshaler)
119127
}
120128

121129
func clearMap(m reflect.Value) {
@@ -136,7 +144,7 @@ func (d *decoder) readDocTo(out reflect.Value) {
136144
}
137145
if setter := getSetter(outt, out); setter != nil {
138146
raw := d.readRaw(ElementDocument)
139-
err := setter.SetBSON(raw)
147+
err := setter.UnmarshalBSONValue(raw.Type, raw.Value)
140148
if _, ok := err.(*TypeError); err != nil && !ok {
141149
panic(err)
142150
}
@@ -663,7 +671,8 @@ func (d *decoder) readElemTo(out reflect.Value, kind bsontype.Type) (good bool)
663671
}
664672

665673
if setter := getSetter(outt, out); setter != nil {
666-
err := setter.SetBSON(d.readRaw(kind))
674+
raw := d.readRaw(kind)
675+
err := setter.UnmarshalBSONValue(raw.Type, raw.Value)
667676
if err == ErrSetZero {
668677
out.Set(reflect.Zero(outt))
669678
return true

0 commit comments

Comments
 (0)