@@ -165,58 +165,119 @@ where
165
165
}
166
166
}
167
167
168
- // Mergeable
168
+ // Shadowable
169
169
170
- /// Environment Container in which a path can be injected based on a condition .
171
- pub trait Mergable < ' sg , ' rslv , LABEL : ' sg , DATA : ' sg , DEQO > :
170
+ /// Sub trait of [EnvContainer] that validates that shadowin operations can be applied on it .
171
+ pub trait Shadowable < ' sg , ' rslv , LABEL : ' sg , DATA : ' sg , DEQO > :
172
172
EnvContainer < ' sg , ' rslv , LABEL , DATA >
173
173
where
174
174
ResolvedPath < ' sg , LABEL , DATA > : Eq + Hash + Clone ,
175
175
{
176
- /// Creates a new environment that contains path when `data_ok` is `true`, and is empty otherwise .
177
- fn merge_if (
178
- & self ,
179
- data_equiv : & ' rslv impl DataEquivalence < ' sg , DATA , Output = DEQO > ,
180
- sub_env : Self ,
176
+ /// Implementation of the shadow operation on this container .
177
+ fn shadow (
178
+ base_env : Env < ' sg , LABEL , DATA > ,
179
+ sub_env : & Env < ' sg , LABEL , DATA > ,
180
+ equiv : & ' rslv impl DataEquivalence < ' sg , DATA , Output = DEQO > ,
181
181
) -> Self ;
182
182
}
183
183
184
- impl < ' sg : ' rslv , ' rslv , LABEL : Eq + ' sg , DATA : Eq + ' sg , ENVC >
185
- Mergable < ' sg , ' rslv , LABEL , DATA , bool > for ENVC
184
+ impl < ' sg : ' rslv , ' rslv , LABEL : ' sg , DATA : ' sg , ENVC > Shadowable < ' sg , ' rslv , LABEL , DATA , bool >
185
+ for ENVC
186
186
where
187
187
ENVC : EnvContainer < ' sg , ' rslv , LABEL , DATA > ,
188
188
Env < ' sg , LABEL , DATA > : Clone ,
189
189
ResolvedPath < ' sg , LABEL , DATA > : Eq + Hash + Clone ,
190
190
{
191
- fn merge_if (
192
- & self ,
193
- data_equiv : & ' rslv impl DataEquivalence < ' sg , DATA , Output = bool > ,
194
- sub_env : Self ,
191
+ fn shadow (
192
+ base_env : Env < ' sg , LABEL , DATA > ,
193
+ sub_env : & Env < ' sg , LABEL , DATA > ,
194
+ equiv : & ' rslv impl DataEquivalence < ' sg , DATA , Output = bool > ,
195
195
) -> Self {
196
- let base_env = self ;
197
- base_env. flat_map ( move |base_env| {
198
- if !base_env. is_empty ( ) && data_equiv. always_equivalent ( ) {
199
- <ENVC as From < Env < ' sg , LABEL , DATA > > >:: from ( base_env. clone ( ) )
200
- } else {
201
- let base_env = base_env. clone ( ) ;
202
-
203
- sub_env. flat_map ( move |sub_env| {
204
- let filtered_env = sub_env
205
- . iter ( )
206
- . filter ( |p1| {
207
- !base_env
208
- . iter ( )
209
- . any ( |p2| data_equiv. data_equiv ( p1. data , p2. data ) )
210
- } )
211
- . collect :: < Vec < _ > > ( ) ;
212
-
213
- let mut new_env = base_env;
214
- for path in filtered_env {
215
- new_env. insert ( path. clone ( ) )
196
+ let filtered_env = sub_env
197
+ . iter ( )
198
+ . filter ( |p1| !base_env. iter ( ) . any ( |p2| equiv. data_equiv ( p1. data , p2. data ) ) )
199
+ . collect :: < Vec < _ > > ( ) ;
200
+
201
+ // FIXME: factor out this part?
202
+ let mut new_env = base_env;
203
+ for path in filtered_env {
204
+ new_env. insert ( path. clone ( ) )
205
+ }
206
+ new_env. into ( )
207
+ }
208
+ }
209
+
210
+ impl < ' sg : ' rslv , ' rslv , LABEL : Clone + Eq + ' sg , DATA : Eq + ' sg , E : Clone + ' rslv >
211
+ Shadowable < ' sg , ' rslv , LABEL , DATA , Result < bool , E > > for Result < Env < ' sg , LABEL , DATA > , E >
212
+ where
213
+ Env < ' sg , LABEL , DATA > : Clone ,
214
+ ResolvedPath < ' sg , LABEL , DATA > : Eq + Hash + Clone ,
215
+ {
216
+ fn shadow (
217
+ base_env : Env < ' sg , LABEL , DATA > ,
218
+ sub_env : & Env < ' sg , LABEL , DATA > ,
219
+ equiv : & ' rslv impl DataEquivalence < ' sg , DATA , Output = Result < bool , E > > ,
220
+ ) -> Self {
221
+ let sub_env = sub_env. clone ( ) ;
222
+ let filtered_env = sub_env. into_iter ( ) . try_fold (
223
+ Vec :: < ResolvedPath < ' sg , LABEL , DATA > > :: new ( ) ,
224
+ |mut filtered_env : Vec < ResolvedPath < ' sg , LABEL , DATA > > ,
225
+ p1 : ResolvedPath < ' sg , LABEL , DATA > | {
226
+ let shadowed = base_env. iter ( ) . try_fold (
227
+ /* initially, not shadowed */ false ,
228
+ |previously_shadowed : bool , p2 : & ResolvedPath < ' sg , LABEL , DATA > | {
229
+ if previously_shadowed {
230
+ Ok ( true ) // if it was shadowed, it will be
231
+ } else {
232
+ // not yet shadowed, try if current path shadows
233
+ equiv. data_equiv ( p1. data , p2. data )
234
+ }
235
+ } ,
236
+ ) ?;
237
+ // p1 is not shadowed, so add it to accumulator
238
+ if !shadowed {
239
+ filtered_env. push ( p1) ;
240
+ }
241
+
242
+ Ok ( filtered_env)
243
+ } ,
244
+ ) ?;
245
+ let mut new_env = base_env;
246
+ filtered_env
247
+ . into_iter ( )
248
+ . for_each ( |path| new_env. insert ( path) ) ;
249
+ new_env. into ( )
250
+ }
251
+ }
252
+
253
+ impl < ' sg : ' rslv , ' rslv , LABEL : Clone + Eq + ' sg , DATA : Eq + ' sg >
254
+ Shadowable < ' sg , ' rslv , LABEL , DATA , FutureWrapper < ' rslv , bool > >
255
+ for FutureWrapper < ' rslv , Env < ' sg , LABEL , DATA > >
256
+ where
257
+ Env < ' sg , LABEL , DATA > : Clone ,
258
+ ResolvedPath < ' sg , LABEL , DATA > : Eq + Hash + Clone ,
259
+ {
260
+ fn shadow (
261
+ base_env : Env < ' sg , LABEL , DATA > ,
262
+ sub_env : & Env < ' sg , LABEL , DATA > ,
263
+ equiv : & ' rslv impl DataEquivalence < ' sg , DATA , Output = FutureWrapper < ' rslv , bool > > ,
264
+ ) -> Self {
265
+ let sub_env = sub_env. clone ( ) ;
266
+ FutureWrapper :: new ( async move {
267
+ let mut filtered_env: Vec < ResolvedPath < ' sg , LABEL , DATA > > = Vec :: new ( ) ;
268
+ ' outer: for sub_path in sub_env {
269
+ for base_path in & base_env {
270
+ if equiv. data_equiv ( sub_path. data , base_path. data ) . await {
271
+ continue ' outer;
216
272
}
217
- new_env. into ( )
218
- } )
273
+ }
274
+ filtered_env. push ( sub_path. clone ( ) ) ;
275
+ }
276
+ let mut new_env = base_env;
277
+ for path in filtered_env {
278
+ new_env. insert ( path) ;
219
279
}
280
+ new_env
220
281
} )
221
282
}
222
283
}
0 commit comments