Closed nicklaw5 closed 6 years ago
For a little more context, this is how I currently approach encoding the User object when using Go's native marshaller:
type User struct {
ID uint64 `json:"id"`
Username string `json:"username"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `json:"deleted_at"`
}
func (u *User) MarshalJSON() ([]byte, error) {
type UserAlias User
return json.Marshal(&struct {
*UserAlias
CreatedAt interface{} `json:"created_at"`
UpdatedAt interface{} `json:"updated_at"`
DeletedAt interface{} `json:"deleted_at"`
}{
UserAlias: (*UserAlias)(u),
CreatedAt: nullifyTime(u.CreatedAt),
UpdatedAt: nullifyTime(u.UpdatedAt),
DeletedAt: nullifyTime(u.DeletedAt),
})
}
func nullifyTime(t interface{}) interface{} {
if reflect.ValueOf(t).Kind() == reflect.Ptr {
if t.(*time.Time) == nil {
return nil
}
return t.(*time.Time).Format(time.RFC3339)
}
if t.(time.Time).IsZero() {
return nil
}
return t.(time.Time).Format(time.RFC3339)
}
Which once encode would result in the following example output:
{"id":2,"username":"nicklaw5","created_at":"2018-07-14T05:46:43+10:00","updated_at":"2018-07-14T05:46:43+10:00","deleted_at":null}
For time we do it this way:
// Decoding
func (u *User) UnmarshalJSONObject(dec *Decoder, k string) error {
switch k {
"createdAt":
var str string
if err := dec.String(&str); err != nil {
return err
}
if t, err := time.Parse(time.RFC3339 , str); err != nil {
return err
} else {
u.CreatedAt = t
}
}
return nil
}
// Encoding
func (u *User) MarshalJSONObject(enc *gojay.Encoder) {
enc.StringKey("createdAt", u.CreatedAt.Format(time.RFC3339))
}
But we could easily add some methods like:
// Decoding
dec.Time(t, time.RFC3339) // where t is a *time.Time
// Encoding
enc.TimeKey(t, time.RFC3339) // where t is a *time.Time
What do you think?
I think some methods would be ideal, as time properties are very common attributes in relaying information between services. Perhaps make the formatting optional however.
Ok will add those in the next release.
Will also add something like dec.SQLNullString()
and enc.SQLNullStringKey("k", *sql.NullString)
and all nullable
types of the sql
package.
Will try to release this in the coming days.
Will be added in next 1.2.0 version to be released tomorrow.
It would be nice if there was an example showing the best approach for encoding and decoding time.Time values. I have searched this repository but can't find any reference on how to accomplish this.
Say I have the following object that maps to a SQL database table, how would I go about encoding/decoding the timestamp fields?