mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 02:31:04 +01:00
add x/jsonx.DayTime type
This commit is contained in:
parent
b4b1f73df6
commit
5844eaef24
|
@ -28,6 +28,8 @@ The codebase for Dependency Injection, Internationalization and localization and
|
|||
|
||||
## Fixes and Improvements
|
||||
|
||||
- Add [x/jsonx: DayTime](/x/jsonx/day_time.go) for JSON marshal and unmarshal of "15:04:05" (hour, minute, second).
|
||||
|
||||
- Fix a bug of `WithoutBodyConsumptionOnUnmarshal` configurator and a minor dependency injection issue caused by the previous alpha version between 20 and 26 February of 2022.
|
||||
|
||||
- New basic [cors middleware](middleware/cors).
|
||||
|
|
|
@ -121,7 +121,7 @@ func (c *Client) emitEndRequest(ctx context.Context, resp *http.Response, err er
|
|||
// RequestOption declares the type of option one can pass
|
||||
// to the Do methods(JSON, Form, ReadJSON...).
|
||||
// Request options run before request constructed.
|
||||
type RequestOption func(*http.Request) error
|
||||
type RequestOption = func(*http.Request) error
|
||||
|
||||
// We always add the following request headers, unless they're removed by custom ones.
|
||||
var defaultRequestOptions = []RequestOption{
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
// All the builtin client options should live here, for easy discovery.
|
||||
|
||||
type Option func(*Client)
|
||||
type Option = func(*Client)
|
||||
|
||||
// BaseURL registers the base URL of this client.
|
||||
// All of its methods will prepend this url.
|
||||
|
|
100
x/jsonx/day_time.go
Normal file
100
x/jsonx/day_time.go
Normal file
|
@ -0,0 +1,100 @@
|
|||
package jsonx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// DayTimeLayout holds the time layout for the the format of "hour:minute:second", hour can be 15, meaning 3 PM.
|
||||
DayTimeLayout = "15:04:05"
|
||||
)
|
||||
|
||||
// DayTime describes a time compatible with DayTimeLayout.
|
||||
type DayTime time.Time
|
||||
|
||||
// ParseDayTime reads from "s" and returns the DayTime time.
|
||||
func ParseDayTime(s string) (DayTime, error) {
|
||||
if s == "" || s == "null" {
|
||||
return DayTime{}, nil
|
||||
}
|
||||
|
||||
tt, err := time.Parse(DayTimeLayout, s)
|
||||
if err != nil {
|
||||
return DayTime{}, err
|
||||
}
|
||||
|
||||
return DayTime(tt), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON parses the "b" into DayTime time.
|
||||
func (t *DayTime) UnmarshalJSON(b []byte) error {
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
s := strings.Trim(string(b), `"`)
|
||||
tt, err := ParseDayTime(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*t = tt
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON writes a quoted string in the DayTime time format.
|
||||
func (t DayTime) MarshalJSON() ([]byte, error) {
|
||||
if s := t.String(); s != "" {
|
||||
s = strconv.Quote(s)
|
||||
return []byte(s), nil
|
||||
}
|
||||
|
||||
return nullLiteral, nil // Note: if the front-end wants an empty string instead I must change that.
|
||||
}
|
||||
|
||||
// ToTime returns the unwrapped *t to time.Time.
|
||||
func (t *DayTime) ToTime() time.Time {
|
||||
tt := time.Time(*t)
|
||||
return tt
|
||||
}
|
||||
|
||||
// IsZero reports whether "t" is zero time.
|
||||
func (t DayTime) IsZero() bool {
|
||||
return time.Time(t).IsZero()
|
||||
}
|
||||
|
||||
// String returns the text representation of the "t" using the DayTime time layout.
|
||||
func (t DayTime) String() string {
|
||||
tt := t.ToTime()
|
||||
if tt.IsZero() {
|
||||
return ""
|
||||
}
|
||||
|
||||
return tt.Format(DayTimeLayout)
|
||||
}
|
||||
|
||||
// Scan completes the sql driver.Scanner interface.
|
||||
func (t *DayTime) Scan(src interface{}) error {
|
||||
switch v := src.(type) {
|
||||
case time.Time: // type was set to timestamp
|
||||
if v.IsZero() {
|
||||
return nil // don't set zero, ignore it.
|
||||
}
|
||||
*t = DayTime(v)
|
||||
case string:
|
||||
tt, err := ParseDayTime(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = tt
|
||||
case nil:
|
||||
*t = DayTime(time.Time{})
|
||||
default:
|
||||
return fmt.Errorf("DayTime: unknown type of: %T", v)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
52
x/jsonx/day_time_test.go
Normal file
52
x/jsonx/day_time_test.go
Normal file
|
@ -0,0 +1,52 @@
|
|||
package jsonx
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDayTime(t *testing.T) {
|
||||
tests := []struct {
|
||||
rawData string
|
||||
}{
|
||||
{
|
||||
rawData: `{"start": "8:33:00", "end": "15:00:42", "nothing": null, "empty": ""}`,
|
||||
},
|
||||
{
|
||||
rawData: `{"start": "8:33:00", "end": "15:00:42", "nothing": null, "empty": ""}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
v := struct {
|
||||
Start DayTime `json:"start"`
|
||||
End DayTime `json:"end"`
|
||||
Nothing DayTime `json:"nothing"`
|
||||
Empty DayTime `json:"empty"`
|
||||
}{}
|
||||
|
||||
err := json.Unmarshal([]byte(tt.rawData), &v)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !v.Nothing.IsZero() {
|
||||
t.Fatalf("expected 'nothing' to be zero but got: %v", v.Nothing)
|
||||
}
|
||||
|
||||
if !v.Empty.IsZero() {
|
||||
t.Fatalf("expected 'empty' to be zero but got: %v", v.Empty)
|
||||
}
|
||||
|
||||
loc := time.UTC
|
||||
|
||||
if expected, got := time.Date(0, time.January, 1, 8, 33, 0, 0, loc), v.Start.ToTime(); expected != got {
|
||||
t.Fatalf("expected 'start' to be: %v but got: %v", expected, got)
|
||||
}
|
||||
|
||||
if expected, got := time.Date(0, time.January, 1, 15, 0, 42, 0, loc), v.End.ToTime(); expected != got {
|
||||
t.Fatalf("expected 'start' to be: %v but got: %v", expected, got)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user