|
- package exts
-
- import (
- "fmt"
- "time"
- "unsafe"
-
- jsoniter "github.com/json-iterator/go"
- "github.com/modern-go/reflect2"
- )
-
- type DurationExt struct {
- jsoniter.DummyExtension
- }
-
- func NewDuration() *DurationExt {
- return &DurationExt{}
- }
-
- func (e *DurationExt) CreateDecoder(typ reflect2.Type) jsoniter.ValDecoder {
- if typ == reflect2.TypeOf(time.Duration(0)) {
- return &DurationDecoder{
- isPointer: false,
- }
- }
-
- if typ == reflect2.TypeOf((*time.Duration)(nil)) {
- return &DurationDecoder{
- isPointer: true,
- }
- }
-
- return nil
- }
-
- type DurationDecoder struct {
- isPointer bool
- }
-
- func (e *DurationDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
- nextType := iter.WhatIsNext()
- if nextType == jsoniter.StringValue {
- str := iter.ReadString()
- dt, err := time.ParseDuration(str)
- if err != nil {
- iter.Error = err
- return
- }
-
- if e.isPointer {
- p := (**time.Duration)(ptr)
- *p = &dt
- } else {
- p := (*time.Duration)(ptr)
- *p = dt
- }
-
- } else if nextType == jsoniter.NilValue {
- iter.ReadNil()
-
- if e.isPointer {
- p := (**time.Duration)(ptr)
- *p = nil
- } else {
- p := (*time.Duration)(ptr)
- *p = time.Duration(0)
- }
-
- } else {
- iter.Error = fmt.Errorf("unsupported type %v", nextType)
- return
- }
-
- }
-
- var _ jsoniter.Extension = &DurationExt{}
|