-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"All" Predicate for tuples #75
Comments
I'll have to think about this. Maybe start with it in your crate, get runtime with it, and we can see about moving it to |
Here's an initial implementation of the macro. pub fn doit<I, P: IntoBoxPredicate<I>> (p: P) -> Box<dyn Predicate<I> + Send> {
p.into_box()
}
doit(eq(5));
doit((eq(5), eq(6)));
doit((eq(5), eq(6), eq(-1))); Here's one implementation of such a trait. Stick it in predicates-core/src/core.rs to make the above snippet work: struct TuplePredicate2<T0, T1>(T0, T1);
impl<T0, T1> std::fmt::Display for TuplePredicate2<T0, T1> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
unimplemented!()
}
}
impl<T0, T1> reflection::PredicateReflection for TuplePredicate2<T0, T1> {}
impl<I0, I1, T0, T1> Predicate<(I0, I1)> for TuplePredicate2<T0, T1>
where T0: Predicate<I0> + Send + Sync + 'static,
T1: Predicate<I1> + Send + Sync + 'static,
{
fn eval(&self, variable: &(I0, I1)) -> bool {
self.0.eval(&variable.0) && self.1.eval(&variable.1)
}
}
struct TuplePredicate3<T0, T1, T2>(T0, T1, T2);
impl<T0, T1, T2> std::fmt::Display for TuplePredicate3<T0, T1, T2> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
unimplemented!()
}
}
impl<T0, T1, T2> reflection::PredicateReflection for TuplePredicate3<T0, T1, T2> {}
impl<I0, I1, I2, T0, T1, T2> Predicate<(I0, I1, I2)> for TuplePredicate3<T0, T1, T2>
where T0: Predicate<I0> + Send + Sync + 'static,
T1: Predicate<I1> + Send + Sync + 'static,
T2: Predicate<I2> + Send + Sync + 'static,
{
fn eval(&self, variable: &(I0, I1, I2)) -> bool {
self.0.eval(&variable.0) && self.1.eval(&variable.1) && self.2.eval(&variable.2)
}
}
pub trait IntoBoxPredicate<I> {
fn into_box(self) -> Box<dyn Predicate<I> + Send>;
}
impl<I, P> IntoBoxPredicate<I> for P
where I: Send + 'static,
P: Predicate<I> + Send + Sync + 'static,
{
fn into_box(self) -> Box<dyn Predicate<I> + Send> {
Box::new(self)
}
}
impl<I0, I1, T0, T1> IntoBoxPredicate<(I0, I1)> for (T0, T1)
where I0: Send + 'static,
I1: Send + 'static,
T0: Predicate<I0> + Send + Sync + 'static,
T1: Predicate<I1> + Send + Sync + 'static,
{
fn into_box(self) -> Box<dyn Predicate<(I0, I1)> + Send> {
Box::new(TuplePredicate2(self.0, self.1))
}
}
impl<I0, I1, I2, T0, T1, T2> IntoBoxPredicate<(I0, I1, I2)> for (T0, T1, T2)
where I0: Send + 'static,
I1: Send + 'static,
I2: Send + 'static,
T0: Predicate<I0> + Send + Sync + 'static,
T1: Predicate<I1> + Send + Sync + 'static,
T2: Predicate<I2> + Send + Sync + 'static,
{
fn into_box(self) -> Box<dyn Predicate<(I0, I1, I2)> + Send> {
Box::new(TuplePredicate3(self.0, self.1, self.2))
}
} But there's a catch: such a trait may only be implemented in the same trait that defines |
Neat and interesting to see where you are using This doesn't have to live in I think I'd still prefer to see this grow close to its use and see how it matures and find out how generally applicable this will be. |
Yes, I can define impl<I, P> IntoBoxPredicate<I> for P where P: Predicate<I> {...}
impl<I> IntoBoxPredicate<I> for AnythingElse<I> {...} That will fail to compile, because it's a potential conflicting trait implementation violation. The problem is that the compiler thinks that a future version of The only potential solution I see that lies within my crate would be to separately impl impl<I> IntoBoxPredicate<I> for EqPredicate<I> {...}
impl<I> IntoBoxPredicate<I> for BooleanPredicate<I> {...}
... That's obviously a PITA. It's also functionally inferior, because it won't cover any If I get ambitious, I might fork predicates-rs to demonstrate how this would work. But for now, it's easier just to use my |
I'm building on top of |
I totally forgot about this issue until taminomara reminded me. This feature isn't actually nearly as important now as it was prior to Mockall 0.1.0. Just a minor convenience now. |
Sorry, I lost track of this. Why is I would expect an upstream implementation for tuples to implement |
If I understand this correctly, |
Ok, the way the comment was written, it sounded like it was suggesting to upstream I can see going either route and would be game for adding it if someone wants to. |
For my application I have need of a predicate that works on tuples. The
function
predicate is more cumbersome than I would like. Ideally, the predicate would apply a different predicate to every member of the tuple, and return the AND of all its children. It would be a macro, and usage would be something like this:Do you think that such a macro would be of general use? If not I'll add it to my crate alone. If so, I'll make a PR for predicates-rs.
The text was updated successfully, but these errors were encountered: