@@ -190,6 +190,53 @@ pub(crate) mod filters {
190190 }
191191 }
192192
193+ pub struct Passthrough < Tuple > {
194+ phantom : :: std:: marker:: PhantomData < Tuple > ,
195+ }
196+
197+ impl < Tuple > Passthrough < Tuple > {
198+ fn new ( ) -> Self {
199+ Passthrough {
200+ phantom : :: std:: marker:: PhantomData ,
201+ }
202+ }
203+ }
204+
205+ impl < ' leap , Tuple > Leaper < ' leap , Tuple , ( ) > for Passthrough < Tuple > {
206+ /// Estimates the number of proposed values.
207+ fn count ( & mut self , _prefix : & Tuple ) -> usize {
208+ 1
209+ }
210+ /// Populates `values` with proposed values.
211+ fn propose ( & mut self , _prefix : & Tuple , values : & mut Vec < & ' leap ( ) > ) {
212+ values. push ( & ( ) )
213+ }
214+ /// Restricts `values` to proposed values.
215+ fn intersect ( & mut self , _prefix : & Tuple , _values : & mut Vec < & ' leap ( ) > ) {
216+ // `Passthrough` never removes values (although if we're here it indicates that the user
217+ // didn't need a `Passthrough` in the first place)
218+ }
219+ }
220+
221+ /// Returns a leaper that proposes a single copy of each tuple from the main input.
222+ ///
223+ /// Use this when you don't need any "extend" leapers in a join, only "filter"s. For example,
224+ /// in the following datalog rule, all terms in the second and third predicate are bound in the
225+ /// first one (the "main input" to our leapjoin).
226+ ///
227+ /// ```prolog
228+ /// error(loan, point) :-
229+ /// origin_contains_loan_at(origin, loan, point), % main input
230+ /// origin_live_at(origin, point),
231+ /// loan_invalidated_at(loan, point).
232+ /// ```
233+ ///
234+ /// Without a passthrough leaper, neither the filter for `origin_live_at` nor the one for
235+ /// `loan_invalidated_at` would propose any tuples, and the leapjoin would panic at runtime.
236+ pub fn passthrough < Tuple > ( ) -> Passthrough < Tuple > {
237+ Passthrough :: new ( )
238+ }
239+
193240 /// A treefrog leaper based on a predicate of prefix and value.
194241 /// Use like `ValueFilter::from(|tuple, value| ...)`. The closure
195242 /// should return true if `value` ought to be retained. The
0 commit comments