-
Notifications
You must be signed in to change notification settings - Fork 81
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
Adding meta queries to support combinations of queries as queries. #291
base: develop
Are you sure you want to change the base?
Conversation
- `AndQuery` - `OrQuery` - `NotQuery` - `AnyQuery` - `AllQuery`
I'm not entirely sure I'm convinced by the ergonomics of this or why this being raised as a PR without first raising an issue to discuss the feature request. |
I'm personally using these with an extension trait to make it more ergonomic. Apologies for not raising an issue first. I've raise #294 just now. |
where | ||
X: XConn, | ||
{ | ||
fn and(self, other: impl Query<X>) -> AndQuery<Self, impl Query<X>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to replace the impl Query<X>
with a specific type Q: Query<X>
here, but the compiler complains with
error[E0283]: type annotations needed
--> src/hooks.rs:127:47
|
127 | Titles(ZOOM_TILE_TITLES.to_vec()).not()
| ^^^
|
= note: cannot satisfy `_: XConn`
= help: the trait `XConn` is implemented for `Conn<C>`
note: required by a bound in `QueryExt::not`
--> src/hooks.rs:63:8
|
63 | X: XConn,
| ^^^^^ required by this bound in `QueryExt::not`
...
79 | fn not(self) -> NotQuery<Self>
| --- required by a bound in this associated function
help: try using a fully qualified path to specify the expected types
|
127 | <Titles as QueryExt<X>>::not(Titles(ZOOM_TILE_TITLES.to_vec()))
| +++++++++++++++++++++++++++++ ~
Which would make it much less ergonomic to use.
It looks like the structs you are defining aren't being given a consistent set of derives? They should all really be deriving the same common set of Debug, Copy, Clone, PartialEq and Eq. The compiler issue you're showing here is down to the structs you've defined not having any trait bounds I suspect? Taking the #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct NotQuery<Q>(pub Q); Here /// A query to be run against client windows for identifying specific windows
/// or programs.
pub trait Query<X: XConn> {
/// Run this query for a given window ID.
fn run(&self, id: Xid, x: &X) -> Result<bool>;
/// The negation of this query
fn not(self) -> NotQuery<X, Self>
where
Self: Sized,
{
NotQuery {
inner: self,
_phantom: std::marker::PhantomData,
}
}
}
/// The logical negation of `Q`.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct NotQuery<X: XConn, Q: Query<X>> {
inner: Q,
_phantom: std::marker::PhantomData<X>,
}
impl<X, Q> Query<X> for NotQuery<X, Q>
where
X: XConn,
Q: Query<X>,
{
fn run(&self, id: Xid, x: &X) -> Result<bool> {
Ok(!self.inner.run(id, x)?)
}
} Exposing the inner All that said, I'm still not convinced that I fully see the utility of the |
Adding structs:
AndQuery
OrQuery
NotQuery
AnyQuery
AllQuery