Mike Schwörer
c534e998e8
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m1s
124 lines
2.7 KiB
Go
124 lines
2.7 KiB
Go
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"
|
|
)
|
|
|
|
type SecondsF64 time.Duration
|
|
|
|
func (d SecondsF64) Duration() time.Duration {
|
|
return time.Duration(d)
|
|
}
|
|
|
|
func (d SecondsF64) String() string {
|
|
return d.Duration().String()
|
|
}
|
|
|
|
func (d SecondsF64) Nanoseconds() int64 {
|
|
return d.Duration().Nanoseconds()
|
|
}
|
|
|
|
func (d SecondsF64) Microseconds() int64 {
|
|
return d.Duration().Microseconds()
|
|
}
|
|
|
|
func (d SecondsF64) Milliseconds() int64 {
|
|
return d.Duration().Milliseconds()
|
|
}
|
|
|
|
func (d SecondsF64) Seconds() float64 {
|
|
return d.Duration().Seconds()
|
|
}
|
|
|
|
func (d SecondsF64) Minutes() float64 {
|
|
return d.Duration().Minutes()
|
|
}
|
|
|
|
func (d SecondsF64) Hours() float64 {
|
|
return d.Duration().Hours()
|
|
}
|
|
|
|
func (d *SecondsF64) UnmarshalJSON(data []byte) error {
|
|
var secs float64 = 0
|
|
if err := json.Unmarshal(data, &secs); err != nil {
|
|
return err
|
|
}
|
|
*d = SecondsF64(timeext.FromSeconds(secs))
|
|
return nil
|
|
}
|
|
|
|
func (d SecondsF64) MarshalJSON() ([]byte, error) {
|
|
secs := d.Seconds()
|
|
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 secValue float64
|
|
err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&secValue)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*d = SecondsF64(int64(secValue * float64(time.Second)))
|
|
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)
|
|
}
|