diff --git a/goextVersion.go b/goextVersion.go index 97d072d..a2b2f78 100644 --- a/goextVersion.go +++ b/goextVersion.go @@ -1,5 +1,5 @@ package goext -const GoextVersion = "0.0.313" +const GoextVersion = "0.0.314" -const GoextVersionTimestamp = "2023-11-10T13:26:30+0100" +const GoextVersionTimestamp = "2023-11-10T13:37:54+0100" diff --git a/mongoext/registry.go b/mongoext/registry.go index 9548cee..e6b670f 100644 --- a/mongoext/registry.go +++ b/mongoext/registry.go @@ -18,14 +18,14 @@ func CreateGoExtBsonRegistry() *bsoncodec.Registry { rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.RFC3339NanoTime{}), rfctime.RFC3339NanoTime{}) rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.RFC3339NanoTime{}), rfctime.RFC3339NanoTime{}) - rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.RFC3339NanoTime{}), rfctime.UnixTime{}) - rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.RFC3339NanoTime{}), rfctime.UnixTime{}) + rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.UnixTime{}), rfctime.UnixTime{}) + rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.UnixTime{}), rfctime.UnixTime{}) - rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.RFC3339NanoTime{}), rfctime.UnixMilliTime{}) - rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.RFC3339NanoTime{}), rfctime.UnixMilliTime{}) + rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.UnixMilliTime{}), rfctime.UnixMilliTime{}) + rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.UnixMilliTime{}), rfctime.UnixMilliTime{}) - rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.RFC3339NanoTime{}), rfctime.UnixNanoTime{}) - rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.RFC3339NanoTime{}), rfctime.UnixNanoTime{}) + rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.UnixNanoTime{}), rfctime.UnixNanoTime{}) + rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.UnixNanoTime{}), rfctime.UnixNanoTime{}) rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.Date{}), rfctime.Date{}) rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.Date{}), rfctime.Date{}) diff --git a/rfctime/seconds.go b/rfctime/seconds.go index e185e19..a9bc57e 100644 --- a/rfctime/seconds.go +++ b/rfctime/seconds.go @@ -2,7 +2,14 @@ package rfctime import ( "encoding/json" + "errors" + "fmt" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/bson/bsoncodec" + "go.mongodb.org/mongo-driver/bson/bsonrw" + "go.mongodb.org/mongo-driver/bson/bsontype" "gogs.mikescher.com/BlackForestBytes/goext/timeext" + "reflect" "time" ) @@ -54,6 +61,63 @@ func (d SecondsF64) MarshalJSON() ([]byte, error) { return json.Marshal(secs) } +func (d *SecondsF64) UnmarshalBSONValue(bt bsontype.Type, data []byte) error { + if bt == bson.TypeNull { + // we can't set nil in UnmarshalBSONValue (so we use default(struct)) + // Use mongoext.CreateGoExtBsonRegistry if you need to unmarsh pointer values + // https://stackoverflow.com/questions/75167597 + // https://jira.mongodb.org/browse/GODRIVER-2252 + *d = SecondsF64(0) + return nil + } + if bt != bson.TypeDouble { + return errors.New(fmt.Sprintf("cannot unmarshal %v into SecondsF64", bt)) + } + var tt float64 + err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt) + if err != nil { + return err + } + *d = SecondsF64(tt) + return nil +} + +func (d SecondsF64) MarshalBSONValue() (bsontype.Type, []byte, error) { + return bson.MarshalValue(d.Seconds()) +} + +func (d SecondsF64) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error { + if val.Kind() == reflect.Ptr && val.IsNil() { + if !val.CanSet() { + return errors.New("ValueUnmarshalerDecodeValue") + } + val.Set(reflect.New(val.Type().Elem())) + } + + tp, src, err := bsonrw.Copier{}.CopyValueToBytes(vr) + if err != nil { + return err + } + + if val.Kind() == reflect.Ptr && len(src) == 0 { + val.Set(reflect.Zero(val.Type())) + return nil + } + + err = d.UnmarshalBSONValue(tp, src) + if err != nil { + return err + } + + if val.Kind() == reflect.Ptr { + val.Set(reflect.ValueOf(&d)) + } else { + val.Set(reflect.ValueOf(d)) + } + + return nil +} + func NewSecondsF64(t time.Duration) SecondsF64 { return SecondsF64(t) } diff --git a/rfctime/unix.go b/rfctime/unix.go index 91529b1..93a7b3c 100644 --- a/rfctime/unix.go +++ b/rfctime/unix.go @@ -76,7 +76,7 @@ func (t *UnixTime) UnmarshalBSONValue(bt bsontype.Type, data []byte) error { return nil } if bt != bson.TypeDateTime { - return errors.New(fmt.Sprintf("cannot unmarshal %v into RFC3339NanoTime", bt)) + return errors.New(fmt.Sprintf("cannot unmarshal %v into UnixTime", bt)) } var tt time.Time err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt) diff --git a/rfctime/unixMilli.go b/rfctime/unixMilli.go index 44e6956..679aa00 100644 --- a/rfctime/unixMilli.go +++ b/rfctime/unixMilli.go @@ -76,7 +76,7 @@ func (t *UnixMilliTime) UnmarshalBSONValue(bt bsontype.Type, data []byte) error return nil } if bt != bson.TypeDateTime { - return errors.New(fmt.Sprintf("cannot unmarshal %v into RFC3339NanoTime", bt)) + return errors.New(fmt.Sprintf("cannot unmarshal %v into UnixMilliTime", bt)) } var tt time.Time err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt) diff --git a/rfctime/unixNano.go b/rfctime/unixNano.go index 5bf5a09..aa5d6c1 100644 --- a/rfctime/unixNano.go +++ b/rfctime/unixNano.go @@ -76,7 +76,7 @@ func (t *UnixNanoTime) UnmarshalBSONValue(bt bsontype.Type, data []byte) error { return nil } if bt != bson.TypeDateTime { - return errors.New(fmt.Sprintf("cannot unmarshal %v into RFC3339NanoTime", bt)) + return errors.New(fmt.Sprintf("cannot unmarshal %v into UnixNanoTime", bt)) } var tt time.Time err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt)