Skip to content

Instantly share code, notes, and snippets.

@enjoylife
Last active March 1, 2019 23:36
Show Gist options
  • Save enjoylife/eba1d2599af01cf4439782b9efc3caf8 to your computer and use it in GitHub Desktop.
Save enjoylife/eba1d2599af01cf4439782b9efc3caf8 to your computer and use it in GitHub Desktop.
One of the more common things one writes/needs during day to day development in a Go based repo is utility types which handle edge cases in, what are usually rest api's or weird 3rd party interfaces.
package util
import (
"fmt"
"strconv"
"strings"
"time"
)
// string: {"timestamp": "1436150027000"} number: {"timestamp": 1436150027000}
// the given code will process both samples listed where epoch time in milliseconds is stored as either string or number
type epochTime time.Time
func (t epochTime) MarshalJSON() ([]byte, error) {
return []byte(strconv.FormatInt(time.Time(t).Unix(), 10)), nil
}
func (t *epochTime) UnmarshalJSON(s []byte) (err error) {
r := strings.Replace(string(s), `"`, ``, -1)
q, err := strconv.ParseInt(r, 10, 64)
if err != nil {
return err
}
*(*time.Time)(t) = time.Unix(q/1000, 0)
return
}
func (t epochTime) String() string { return time.Time(t).String() }
type convertibleBoolean bool
func (bit *convertibleBoolean) UnmarshalJSON(data []byte) error {
asString := string(data)
b, err := strconv.ParseBool(asString)
if err != nil {
return fmt.Errorf("boolean unmarshal error: invalid input %s: %s", asString, err)
}
*bit = convertibleBoolean(b)
return nil
}
// Duration is a utility type used for easy usage of time.Duration but from a config
// It defines the needed methods by the config.Provider, to parse out a string into a time.Duration
// enabling you to do
// key:
// dur: 5s # which will turn into a time.Duration of 5s
// then wherever you need to use it, simply cast to time.Duration(dur)
type Duration time.Duration
// UnmarshalYAML reads the duration value into a valid yaml
func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error {
// implement unmarshaling here
var tmp string
if err := unmarshal(&tmp); err != nil {
return err
}
pd, err := time.ParseDuration(tmp)
if err != nil {
return err
}
*d = Duration(pd)
return nil
}
// MarshalYAML writes the duration value into a valid yaml
func (d Duration) MarshalYAML() (interface{}, error) {
td := time.Duration(d)
return td.String(), nil
}
// String returns the string representation of the duration.
func (d Duration) String() string { return time.Duration(d).String() }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment