Мне было просто интересно, каковы лучшие практики в отношении создания пользовательского кодировщика для поддержки драйверов Go Mongo.Ниже приведена моя текущая реализация пользовательского обработчика для данных Binary, OID и Date, которые извлекаются из базы данных и кодируются в JSON.
var CustomRegistry = createCustomRegistry().Build()
var tBinary = reflect.TypeOf(primitive.Binary{})
var tOID = reflect.TypeOf(primitive.ObjectID{})
var tDateTime = reflect.TypeOf(primitive.DateTime(0))
func createCustomRegistry() *bsoncodec.RegistryBuilder {
var primitiveCodecs bson.PrimitiveCodecs
rb := bsoncodec.NewRegistryBuilder()
bsoncodec.DefaultValueEncoders{}.RegisterDefaultEncoders(rb)
bsoncodec.DefaultValueDecoders{}.RegisterDefaultDecoders(rb)
rb.RegisterEncoder(tBinary, bsoncodec.ValueEncoderFunc(binaryEncodeCustomValue))
rb.RegisterEncoder(tOID, bsoncodec.ValueEncoderFunc(objectIDEncodeValue))
rb.RegisterEncoder(tDateTime, bsoncodec.ValueEncoderFunc(dateTimeEncodeValue))
primitiveCodecs.RegisterPrimitiveCodecs(rb)
return rb
}
func binaryEncodeCustomValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
if !val.IsValid() || val.Type() != tBinary {
return bsoncodec.ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val}
}
in := val.Interface().(primitive.Binary)
out := make([]byte, base64.StdEncoding.EncodedLen(len(in.Data)))
base64.StdEncoding.Encode(out, in.Data)
s, err := util.BinaryToCSUUID(in.Data)
if err != nil {
return bsoncodec.ValueEncoderError{Name: "BinaryEncodeValue", Types: []reflect.Type{tBinary}, Received: val}
}
return vw.WriteString(s)
}
func objectIDEncodeValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
if !val.IsValid() || val.Type() != tOID {
return bsoncodec.ValueEncoderError{Name: "ObjectIDEncodeValue", Types: []reflect.Type{tOID}, Received: val}
}
s := val.Interface().(primitive.ObjectID).Hex()
return vw.WriteString(s)
}
func dateTimeEncodeValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
const jdateFormat = "2006-01-02T15:04:05.999Z"
if !val.IsValid() || val.Type() != tDateTime {
return bsoncodec.ValueEncoderError{Name: "DateTimeEncodeValue", Types: []reflect.Type{tDateTime}, Received: val}
}
ints := val.Int()
t := time.Unix(0, ints*1000000)
return vw.WriteString(t.Format(jdateFormat))
}
Я вызываю приведенный выше код, используя следующую функцию:
data, writeErr := bson.MarshalExtJSONWithRegistry(CustomRegistry, result, false, false)
Я не нашел много документации о том, как это должно быть обработано.Есть ли лучший способ сделать это?