@@ -96,9 +96,9 @@ fun interface ValueProvider<T, R, D : Description<T>> {
96
96
*/
97
97
fun except (filter : (ValueProvider <T , R , D >) -> Boolean ): ValueProvider <T , R , D > {
98
98
return if (this is Combined ) {
99
- Combined (providers.filterNot(filter))
99
+ Combined (providers.map { it.unwrapIfFallback() }. filterNot(filter))
100
100
} else {
101
- Combined (if (filter(this )) emptyList() else listOf (this ))
101
+ Combined (if (filter(unwrapIfFallback() )) emptyList() else listOf (this ))
102
102
}
103
103
}
104
104
@@ -117,26 +117,7 @@ fun interface ValueProvider<T, R, D : Description<T>> {
117
117
* Uses fallback value provider in case when 'this' one failed to generate any value.
118
118
*/
119
119
fun withFallback (fallback : ValueProvider <T , R , D >) : ValueProvider <T , R , D > {
120
- val thisProvider = this
121
- return object : ValueProvider <T , R , D > {
122
- override fun enrich (description : D , type : T , scope : Scope ) {
123
- thisProvider.enrich(description, type, scope)
124
- // Enriching scope by fallback value provider in this point is not quite right,
125
- // but it doesn't look as a problem right now.
126
- fallback.enrich(description, type, scope)
127
- }
128
-
129
- override fun generate (description : D , type : T ): Sequence <Seed <T , R >> {
130
- val default = if (thisProvider.accept(type)) thisProvider.generate(description, type) else emptySequence()
131
- return if (default.iterator().hasNext()) {
132
- default
133
- } else if (fallback.accept(type)) {
134
- fallback.generate(description, type)
135
- } else {
136
- emptySequence()
137
- }
138
- }
139
- }
120
+ return Fallback (this , fallback)
140
121
}
141
122
142
123
/* *
@@ -152,6 +133,42 @@ fun interface ValueProvider<T, R, D : Description<T>> {
152
133
return if (flag) block(this ) else this
153
134
}
154
135
136
+ /* *
137
+ * Checks if current provider has fallback and return the initial provider.
138
+ *
139
+ * If the initial provider is also fallback, then it is unwrapped too.
140
+ *
141
+ * @return unwrapped provider or this if it is not fallback
142
+ */
143
+ fun unwrapIfFallback (): ValueProvider <T , R , D > {
144
+ return if (this is Fallback <T , R , D >) { provider.unwrapIfFallback() } else { this }
145
+ }
146
+
147
+ private class Fallback <T , R , D : Description <T >>(
148
+ val provider : ValueProvider <T , R , D >,
149
+ val fallback : ValueProvider <T , R , D >,
150
+ ): ValueProvider<T, R, D> {
151
+
152
+ override fun enrich (description : D , type : T , scope : Scope ) {
153
+ provider.enrich(description, type, scope)
154
+ // Enriching scope by fallback value provider in this point is not quite right,
155
+ // but it doesn't look as a problem right now.
156
+ fallback.enrich(description, type, scope)
157
+ }
158
+
159
+ override fun generate (description : D , type : T ): Sequence <Seed <T , R >> {
160
+ val default = if (provider.accept(type)) provider.generate(description, type) else emptySequence()
161
+ return if (default.iterator().hasNext()) {
162
+ default
163
+ } else if (fallback.accept(type)) {
164
+ fallback.generate(description, type)
165
+ } else {
166
+ emptySequence()
167
+ }
168
+ }
169
+
170
+ }
171
+
155
172
/* *
156
173
* Wrapper class that delegates implementation to the [providers].
157
174
*/
0 commit comments