@@ -96,9 +96,9 @@ fun interface ValueProvider<T, R, D : Description<T>> {
9696 */
9797 fun except (filter : (ValueProvider <T , R , D >) -> Boolean ): ValueProvider <T , R , D > {
9898 return if (this is Combined ) {
99- Combined (providers.filterNot(filter))
99+ Combined (providers.map { it.unwrapIfFallback() }. filterNot(filter))
100100 } else {
101- Combined (if (filter(this )) emptyList() else listOf (this ))
101+ Combined (if (filter(unwrapIfFallback() )) emptyList() else listOf (this ))
102102 }
103103 }
104104
@@ -117,26 +117,7 @@ fun interface ValueProvider<T, R, D : Description<T>> {
117117 * Uses fallback value provider in case when 'this' one failed to generate any value.
118118 */
119119 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)
140121 }
141122
142123 /* *
@@ -152,6 +133,42 @@ fun interface ValueProvider<T, R, D : Description<T>> {
152133 return if (flag) block(this ) else this
153134 }
154135
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+
155172 /* *
156173 * Wrapper class that delegates implementation to the [providers].
157174 */
0 commit comments