@@ -31,7 +31,7 @@ type diffFn func(c config, lhs, rhs interface{}, visited *visited) (Differ, erro
31
31
32
32
// Diff generates a tree representing differences and similarities between two objects.
33
33
//
34
- // Diff supports maps, slices and scalars (comparables types such as int, string, etc ...).
34
+ // Diff supports maps, slices, Stream and scalars (comparables types such as int, string, etc ...).
35
35
// When an unsupported type is encountered, an ErrUnsupported error is returned.
36
36
func Diff (lhs , rhs interface {}, opts ... ConfigOpt ) (Differ , error ) {
37
37
c := defaultConfig ()
@@ -56,26 +56,38 @@ func diff(c config, lhs, rhs interface{}, visited *visited) (Differ, error) {
56
56
return types {lhs , rhs }, ErrCyclic
57
57
}
58
58
59
- if valueIsScalar (lhsVal ) && valueIsScalar (rhsVal ) {
60
- return scalar {lhs , rhs }, nil
59
+ return diffValues (c , lhsVal , rhsVal , visited )
60
+ }
61
+
62
+ func diffValues (c config , lhs , rhs reflect.Value , visited * visited ) (Differ , error ) {
63
+ if valueIsStream (lhs ) && valueIsStream (rhs ) {
64
+ return newStream (c , lhs .Interface (), rhs .Interface (), visited )
65
+ }
66
+
67
+ if valueIsScalar (lhs ) && valueIsScalar (rhs ) {
68
+ return scalar {lhs .Interface (), rhs .Interface ()}, nil
61
69
}
62
- if lhsVal .Kind () != rhsVal .Kind () {
63
- return types {lhs , rhs }, nil
70
+ if lhs .Kind () != rhs .Kind () {
71
+ return types {lhs . Interface () , rhs . Interface () }, nil
64
72
}
65
73
66
- switch lhsVal .Kind () {
74
+ switch lhs .Kind () {
67
75
case reflect .Slice , reflect .Array :
68
- return c .sliceFn (c , lhs , rhs , visited )
76
+ return c .sliceFn (c , lhs . Interface () , rhs . Interface () , visited )
69
77
case reflect .Map :
70
- return newMap (c , lhs , rhs , visited )
78
+ return newMap (c , lhs . Interface () , rhs . Interface () , visited )
71
79
case reflect .Struct :
72
- return newStruct (c , lhs , rhs , visited )
80
+ return newStruct (c , lhs . Interface () , rhs . Interface () , visited )
73
81
}
74
82
75
- return types {lhs , rhs }, & ErrUnsupported {lhsVal .Type (), rhsVal .Type ()}
83
+ return types {lhs . Interface () , rhs . Interface () }, & ErrUnsupported {lhs .Type (), rhs .Type ()}
76
84
}
77
85
78
86
func indirectValueOf (i interface {}) (reflect.Value , interface {}) {
87
+ if _ , ok := i .(Stream ); ok {
88
+ return reflect .ValueOf (i ), i
89
+ }
90
+
79
91
v := reflect .Indirect (reflect .ValueOf (i ))
80
92
if ! v .IsValid () || ! v .CanInterface () {
81
93
return reflect .ValueOf (i ), i
@@ -84,6 +96,16 @@ func indirectValueOf(i interface{}) (reflect.Value, interface{}) {
84
96
return v , v .Interface ()
85
97
}
86
98
99
+ func valueIsStream (v reflect.Value ) bool {
100
+ if ! v .IsValid () || ! v .CanInterface () {
101
+ return false
102
+ }
103
+
104
+ _ , ok := v .Interface ().(Stream )
105
+
106
+ return ok
107
+ }
108
+
87
109
func valueIsScalar (v reflect.Value ) bool {
88
110
switch v .Kind () {
89
111
default :
@@ -122,9 +144,7 @@ func IsExcess(d Differ) bool {
122
144
switch d .(type ) {
123
145
default :
124
146
return false
125
- case mapExcess :
126
- return true
127
- case sliceExcess :
147
+ case mapExcess , sliceExcess , streamExcess :
128
148
return true
129
149
}
130
150
}
@@ -134,9 +154,7 @@ func IsMissing(d Differ) bool {
134
154
switch d .(type ) {
135
155
default :
136
156
return false
137
- case mapMissing :
138
- return true
139
- case sliceMissing :
157
+ case mapMissing , sliceMissing , streamMissing :
140
158
return true
141
159
}
142
160
}
@@ -176,6 +194,13 @@ func IsSlice(d Differ) bool {
176
194
return ok
177
195
}
178
196
197
+ // IsStream returns true if d is a diff between towo slices
198
+ func IsStream (d Differ ) bool {
199
+ _ , ok := d .(stream )
200
+
201
+ return ok
202
+ }
203
+
179
204
type lhsGetter interface {
180
205
LHS () interface {}
181
206
}
0 commit comments