forked from amsokol/mongo-go-driver-protobuf
/
struct.go
64 lines (51 loc) · 1.6 KB
/
struct.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package structpbbson
import (
"go.mongodb.org/mongo-driver/bson/bsoncodec"
"go.mongodb.org/mongo-driver/bson/bsonrw"
"reflect"
)
var DefaultStructCodec = StructCodec{}
type StructCodec struct{}
func (c StructCodec) EncodeValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
if !val.IsValid() || val.Type() != ProtoStructType {
return bsoncodec.ValueEncoderError{Name: "StructCodec.EncodeValue", Types: []reflect.Type{ProtoStructType}, Received: val}
}
dw, err := vw.WriteDocument()
if err != nil {
return err
}
val = reflect.Indirect(val)
fieldsField := val.FieldByName("Fields") // the 'Fields' field
keys := fieldsField.MapKeys()
var evw bsonrw.ValueWriter
for _, key := range keys {
evw, err = dw.WriteDocumentElement(key.String())
if err != nil {
return err
}
vv := fieldsField.MapIndex(key)
if vv.IsNil() {
err = evw.WriteNull()
} else {
err = DefaultValueCodec.EncodeValue(ec, evw, vv.Elem())
}
if err != nil {
return err
}
}
return dw.WriteDocumentEnd()
}
func (c StructCodec) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
if !val.IsValid() || val.Type() != ProtoStructType {
return bsoncodec.ValueDecoderError{Name: "StructCodec.DecodeValue", Types: []reflect.Type{ProtoStructType}, Received: val}
}
fieldsField := val.FieldByName("Fields") // the 'Fields' field
if fieldsField.IsNil() {
fieldsField.Set(reflect.MakeMap(fieldsField.Type()))
}
mapDecoder, err := dc.LookupDecoder(fieldsField.Type())
if err != nil {
return err
}
return mapDecoder.DecodeValue(dc, vr, fieldsField)
}