mirror of
https://github.com/kataras/iris.git
synced 2025-02-09 02:34:55 +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
|
## 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.
|
- 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).
|
- 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
|
// RequestOption declares the type of option one can pass
|
||||||
// to the Do methods(JSON, Form, ReadJSON...).
|
// to the Do methods(JSON, Form, ReadJSON...).
|
||||||
// Request options run before request constructed.
|
// 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.
|
// We always add the following request headers, unless they're removed by custom ones.
|
||||||
var defaultRequestOptions = []RequestOption{
|
var defaultRequestOptions = []RequestOption{
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
// All the builtin client options should live here, for easy discovery.
|
// 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.
|
// BaseURL registers the base URL of this client.
|
||||||
// All of its methods will prepend this url.
|
// 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