...
1
2
3
4
5
6
7 package bsoncodec
8
9 import (
10 "fmt"
11 "reflect"
12
13 "go.mongodb.org/mongo-driver/bson/bsonoptions"
14 "go.mongodb.org/mongo-driver/bson/bsonrw"
15 "go.mongodb.org/mongo-driver/bson/bsontype"
16 )
17
18
19
20
21
22
23
24
25
26
27
28
29
30 type StringCodec struct {
31
32
33
34
35 DecodeObjectIDAsHex bool
36 }
37
38 var (
39 defaultStringCodec = NewStringCodec()
40
41
42
43
44 _ typeDecoder = defaultStringCodec
45 )
46
47
48
49
50
51 func NewStringCodec(opts ...*bsonoptions.StringCodecOptions) *StringCodec {
52 stringOpt := bsonoptions.MergeStringCodecOptions(opts...)
53 return &StringCodec{*stringOpt.DecodeObjectIDAsHex}
54 }
55
56
57 func (sc *StringCodec) EncodeValue(_ EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
58 if val.Kind() != reflect.String {
59 return ValueEncoderError{
60 Name: "StringEncodeValue",
61 Kinds: []reflect.Kind{reflect.String},
62 Received: val,
63 }
64 }
65
66 return vw.WriteString(val.String())
67 }
68
69 func (sc *StringCodec) decodeType(_ DecodeContext, vr bsonrw.ValueReader, t reflect.Type) (reflect.Value, error) {
70 if t.Kind() != reflect.String {
71 return emptyValue, ValueDecoderError{
72 Name: "StringDecodeValue",
73 Kinds: []reflect.Kind{reflect.String},
74 Received: reflect.Zero(t),
75 }
76 }
77
78 var str string
79 var err error
80 switch vr.Type() {
81 case bsontype.String:
82 str, err = vr.ReadString()
83 if err != nil {
84 return emptyValue, err
85 }
86 case bsontype.ObjectID:
87 oid, err := vr.ReadObjectID()
88 if err != nil {
89 return emptyValue, err
90 }
91 if sc.DecodeObjectIDAsHex {
92 str = oid.Hex()
93 } else {
94
95 byteArray := [12]byte(oid)
96 str = string(byteArray[:])
97 }
98 case bsontype.Symbol:
99 str, err = vr.ReadSymbol()
100 if err != nil {
101 return emptyValue, err
102 }
103 case bsontype.Binary:
104 data, subtype, err := vr.ReadBinary()
105 if err != nil {
106 return emptyValue, err
107 }
108 if subtype != bsontype.BinaryGeneric && subtype != bsontype.BinaryBinaryOld {
109 return emptyValue, decodeBinaryError{subtype: subtype, typeName: "string"}
110 }
111 str = string(data)
112 case bsontype.Null:
113 if err = vr.ReadNull(); err != nil {
114 return emptyValue, err
115 }
116 case bsontype.Undefined:
117 if err = vr.ReadUndefined(); err != nil {
118 return emptyValue, err
119 }
120 default:
121 return emptyValue, fmt.Errorf("cannot decode %v into a string type", vr.Type())
122 }
123
124 return reflect.ValueOf(str), nil
125 }
126
127
128 func (sc *StringCodec) DecodeValue(dctx DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
129 if !val.CanSet() || val.Kind() != reflect.String {
130 return ValueDecoderError{Name: "StringDecodeValue", Kinds: []reflect.Kind{reflect.String}, Received: val}
131 }
132
133 elem, err := sc.decodeType(dctx, vr, val.Type())
134 if err != nil {
135 return err
136 }
137
138 val.SetString(elem.String())
139 return nil
140 }
141
View as plain text