Skip to content

Commit c4ca5cd

Browse files
authored
Merge pull request #36 from johanneswuerbach/time
fix: support time.Time values
2 parents 5734676 + a6cda54 commit c4ca5cd

File tree

2 files changed

+64
-22
lines changed

2 files changed

+64
-22
lines changed

patch_test.go

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"strconv"
66
"strings"
7+
"time"
78

89
. "github.com/onsi/ginkgo"
910
. "github.com/onsi/gomega"
@@ -20,19 +21,20 @@ type A struct {
2021
}
2122

2223
type B struct {
23-
Str string `json:"str,omitempty"`
24-
Bool bool `json:"bool"`
25-
Int int `json:"int"`
26-
Int8 int8 `json:"int8"`
27-
Int16 int16 `json:"int16"`
28-
Int32 int32 `json:"int32"`
29-
Int64 int64 `json:"int64"`
30-
Uint uint `json:"uint"`
31-
Uint8 uint8 `json:"uint8"`
32-
Uint16 uint16 `json:"uint16"`
33-
Uint32 uint32 `json:"uint32"`
34-
Uint64 uint64 `json:"uint64"`
35-
UintPtr uintptr `json:"ptr" faker:"-"`
24+
Str string `json:"str,omitempty"`
25+
Bool bool `json:"bool"`
26+
Int int `json:"int"`
27+
Int8 int8 `json:"int8"`
28+
Int16 int16 `json:"int16"`
29+
Int32 int32 `json:"int32"`
30+
Int64 int64 `json:"int64"`
31+
Uint uint `json:"uint"`
32+
Uint8 uint8 `json:"uint8"`
33+
Uint16 uint16 `json:"uint16"`
34+
Uint32 uint32 `json:"uint32"`
35+
Uint64 uint64 `json:"uint64"`
36+
UintPtr uintptr `json:"ptr" faker:"-"`
37+
Time time.Time `json:"time"`
3638
}
3739

3840
type C struct {
@@ -156,6 +158,17 @@ var _ = Describe("JSONPatch", func() {
156158
// no change
157159
testPatch(B{Uint: 1, Uint8: 1, Uint16: 1, Uint32: 1, Uint64: 1}, B{Uint: 1, Uint8: 1, Uint16: 1, Uint32: 1, Uint64: 1})
158160
})
161+
It("time", func() {
162+
now := time.Now()
163+
// add
164+
testPatch(B{Time: now}, B{})
165+
// remove
166+
testPatch(B{}, B{Time: now})
167+
// replace
168+
testPatch(B{Time: now}, B{Time: now.Add(1 * time.Hour)})
169+
// no change
170+
testPatch(B{Time: now}, B{Time: now})
171+
})
159172
})
160173
Context("CreateJsonPatch_map", func() {
161174
It("string map", func() {

walker.go

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"sort"
77
"strconv"
88
"strings"
9+
"time"
910
)
1011

1112
const (
@@ -39,15 +40,7 @@ func (w *walker) walk(modified, current reflect.Value, pointer JSONPointer) erro
3940
case reflect.Interface:
4041
return w.processInterface(modified, current, pointer)
4142
case reflect.String:
42-
if modified.String() != current.String() {
43-
if modified.String() == "" {
44-
w.remove(pointer, current.String())
45-
} else if current.String() == "" {
46-
w.add(pointer, modified.String())
47-
} else {
48-
w.replace(pointer, modified.String(), current.String())
49-
}
50-
}
43+
return w.processString(modified, current, pointer)
5144
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
5245
if modified.Int() != current.Int() {
5346
w.replace(pointer, modified.Int(), current.Int())
@@ -80,6 +73,21 @@ func (w *walker) processInterface(modified reflect.Value, current reflect.Value,
8073
return nil
8174
}
8275

76+
// processString processes reflect.String values
77+
func (w *walker) processString(modified reflect.Value, current reflect.Value, pointer JSONPointer) error {
78+
if modified.String() != current.String() {
79+
if modified.String() == "" {
80+
w.remove(pointer, current.String())
81+
} else if current.String() == "" {
82+
w.add(pointer, modified.String())
83+
} else {
84+
w.replace(pointer, modified.String(), current.String())
85+
}
86+
}
87+
88+
return nil
89+
}
90+
8391
// processMap processes reflect.Map values
8492
func (w *walker) processMap(modified reflect.Value, current reflect.Value, pointer JSONPointer) error {
8593
// NOTE: currently only map[string]interface{} are supported
@@ -248,6 +256,19 @@ func (w *walker) processStruct(modified, current reflect.Value, pointer JSONPoin
248256
return nil
249257
}
250258

259+
if modified.Type().PkgPath() == "time" && modified.Type().Name() == "Time" {
260+
m, err := toTimeStrValue(modified)
261+
if err != nil {
262+
return err
263+
}
264+
265+
c, err := toTimeStrValue(current)
266+
if err != nil {
267+
return err
268+
}
269+
return w.processString(m, c, pointer)
270+
}
271+
251272
// process all struct fields, the order of the fields of the modified and current JSON object is identical because their types match
252273
for j := 0; j < modified.NumField(); j++ {
253274
tag := strings.Split(modified.Type().Field(j).Tag.Get(jsonTag), ",")[0]
@@ -264,6 +285,14 @@ func (w *walker) processStruct(modified, current reflect.Value, pointer JSONPoin
264285
return nil
265286
}
266287

288+
func toTimeStrValue(v reflect.Value) (reflect.Value, error) {
289+
t, err := v.Interface().(time.Time).MarshalText()
290+
if err != nil {
291+
return reflect.Value{}, err
292+
}
293+
return reflect.ValueOf(string(t)), nil
294+
}
295+
267296
// extractIgnoreSliceOrderMatchValue extracts the value which is used to match the modified and current values to ignore the slice order
268297
func extractIgnoreSliceOrderMatchValue(value reflect.Value, fieldName string) string {
269298
switch value.Kind() {

0 commit comments

Comments
 (0)