@@ -23,6 +23,56 @@ const (
23
23
DELETE = "delete"
24
24
)
25
25
26
+ // DiffType represents an enum with all the supported diff types
27
+ type DiffType uint8
28
+
29
+ const (
30
+ UNSUPPORTED DiffType = iota
31
+ STRUCT
32
+ SLICE
33
+ ARRAY
34
+ STRING
35
+ BOOL
36
+ INT
37
+ UINT
38
+ FLOAT
39
+ MAP
40
+ PTR
41
+ INTERFACE
42
+ )
43
+
44
+ func (t DiffType ) String () string {
45
+ switch t {
46
+ case STRUCT :
47
+ return "STRUCT"
48
+ case SLICE :
49
+ return "SLICE"
50
+ case ARRAY :
51
+ return "ARRAY"
52
+ case STRING :
53
+ return "STRING"
54
+ case BOOL :
55
+ return "BOOL"
56
+ case INT :
57
+ return "INT"
58
+ case UINT :
59
+ return "UINT"
60
+ case FLOAT :
61
+ return "FLOAT"
62
+ case MAP :
63
+ return "MAP"
64
+ case PTR :
65
+ return "PTR"
66
+ case INTERFACE :
67
+ return "INTERFACE"
68
+ default :
69
+ return "UNSUPPORTED"
70
+ }
71
+ }
72
+
73
+ // DiffFunc represents the built-in diff functions
74
+ type DiffFunc func ([]string , reflect.Value , reflect.Value , interface {}) error
75
+
26
76
// Differ a configurable diff instance
27
77
type Differ struct {
28
78
TagName string
@@ -53,7 +103,7 @@ type Change struct {
53
103
// ValueDiffer is an interface for custom differs
54
104
type ValueDiffer interface {
55
105
Match (a , b reflect.Value ) bool
56
- Diff (cl * Changelog , path []string , a , b reflect.Value ) error
106
+ Diff (dt DiffType , df DiffFunc , cl * Changelog , path []string , a , b reflect.Value , parent interface {} ) error
57
107
InsertParentDiffer (dfunc func (path []string , a , b reflect.Value , p interface {}) error )
58
108
}
59
109
@@ -134,6 +184,35 @@ func (cl *Changelog) Filter(path []string) Changelog {
134
184
return ncl
135
185
}
136
186
187
+ func (d * Differ ) getDiffType (a , b reflect.Value ) (DiffType , DiffFunc ) {
188
+ switch {
189
+ case are (a , b , reflect .Struct , reflect .Invalid ):
190
+ return STRUCT , d .diffStruct
191
+ case are (a , b , reflect .Slice , reflect .Invalid ):
192
+ return SLICE , d .diffSlice
193
+ case are (a , b , reflect .Array , reflect .Invalid ):
194
+ return ARRAY , d .diffSlice
195
+ case are (a , b , reflect .String , reflect .Invalid ):
196
+ return STRING , d .diffString
197
+ case are (a , b , reflect .Bool , reflect .Invalid ):
198
+ return BOOL , d .diffBool
199
+ case are (a , b , reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 , reflect .Invalid ):
200
+ return INT , d .diffInt
201
+ case are (a , b , reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Invalid ):
202
+ return UINT , d .diffUint
203
+ case are (a , b , reflect .Float32 , reflect .Float64 , reflect .Invalid ):
204
+ return FLOAT , d .diffFloat
205
+ case are (a , b , reflect .Map , reflect .Invalid ):
206
+ return MAP , d .diffMap
207
+ case are (a , b , reflect .Ptr , reflect .Invalid ):
208
+ return PTR , d .diffPtr
209
+ case are (a , b , reflect .Interface , reflect .Invalid ):
210
+ return INTERFACE , d .diffInterface
211
+ default :
212
+ return UNSUPPORTED , nil
213
+ }
214
+ }
215
+
137
216
// Diff returns a changelog of all mutated values from both
138
217
func (d * Differ ) Diff (a , b interface {}) (Changelog , error ) {
139
218
// reset the state of the diff
@@ -160,11 +239,14 @@ func (d *Differ) diff(path []string, a, b reflect.Value, parent interface{}) err
160
239
return ErrTypeMismatch
161
240
}
162
241
242
+ // get the diff type and the corresponding built-int diff function to handle this type
243
+ diffType , diffFunc := d .getDiffType (a , b )
244
+
163
245
// first go through custom diff functions
164
246
if len (d .customValueDiffers ) > 0 {
165
247
for _ , vd := range d .customValueDiffers {
166
248
if vd .Match (a , b ) {
167
- err := vd .Diff (& d .cl , path , a , b )
249
+ err := vd .Diff (diffType , diffFunc , & d .cl , path , a , b , parent )
168
250
if err != nil {
169
251
return err
170
252
}
@@ -174,32 +256,11 @@ func (d *Differ) diff(path []string, a, b reflect.Value, parent interface{}) err
174
256
}
175
257
176
258
// then built-in diff functions
177
- switch {
178
- case are (a , b , reflect .Struct , reflect .Invalid ):
179
- return d .diffStruct (path , a , b )
180
- case are (a , b , reflect .Slice , reflect .Invalid ):
181
- return d .diffSlice (path , a , b )
182
- case are (a , b , reflect .Array , reflect .Invalid ):
183
- return d .diffSlice (path , a , b )
184
- case are (a , b , reflect .String , reflect .Invalid ):
185
- return d .diffString (path , a , b , parent )
186
- case are (a , b , reflect .Bool , reflect .Invalid ):
187
- return d .diffBool (path , a , b , parent )
188
- case are (a , b , reflect .Int , reflect .Int8 , reflect .Int16 , reflect .Int32 , reflect .Int64 , reflect .Invalid ):
189
- return d .diffInt (path , a , b , parent )
190
- case are (a , b , reflect .Uint , reflect .Uint8 , reflect .Uint16 , reflect .Uint32 , reflect .Uint64 , reflect .Invalid ):
191
- return d .diffUint (path , a , b , parent )
192
- case are (a , b , reflect .Float32 , reflect .Float64 , reflect .Invalid ):
193
- return d .diffFloat (path , a , b , parent )
194
- case are (a , b , reflect .Map , reflect .Invalid ):
195
- return d .diffMap (path , a , b )
196
- case are (a , b , reflect .Ptr , reflect .Invalid ):
197
- return d .diffPtr (path , a , b , parent )
198
- case are (a , b , reflect .Interface , reflect .Invalid ):
199
- return d .diffInterface (path , a , b , parent )
200
- default :
259
+ if diffType == UNSUPPORTED {
201
260
return errors .New ("unsupported type: " + a .Kind ().String ())
202
261
}
262
+
263
+ return diffFunc (path , a , b , parent )
203
264
}
204
265
205
266
func (cl * Changelog ) Add (t string , path []string , ftco ... interface {}) {
0 commit comments