Add enumflags2 for DeviceCapability enum#11
Conversation
|
|
|
I originally based this PR on bitflags, but changed to enumflags2 because you can get enums in the iterator. It means less I think wayland-rs might use bitflags because it automatically supports storing unknown bits. With enumflags2, it definitely is possible by parsing |
|
As the server, we don't need to store unknown bits, because we control the meaning of the bits. As the client, we won't do anything with bits we don't know the meaning of; that's why the error for an unknown interface. As a maintainer, that means that when you advertise support for a device capability interface in the handshake, you need to add it to the enum. Nothing else really. |
Wayland-rs doesn't currently use It seems with wayland, it's valid with some enums but not others to advertise a value that is not advertised in the version of the protocol in use: https://gitlab.freedesktop.org/wayland/wayland/-/issues/497, though that's has never been clearly specified. With libei, it looks like https://gitlab.freedesktop.org/libinput/libei/-/blob/main/proto/protocol.dtd and https://gitlab.freedesktop.org/libinput/libei/-/blob/main/proto/ei-scanner do define a Though reis doesn't promise anything about avoiding API breaks (and is unlikely to ever be as much of a pain to deal with as wayland-rs API breaks), so it's not a huge problem if we have to change this in the future.
What exactly is different here? https://docs.rs/bitflags/latest/bitflags/example_generated/struct.Flags.html shows |
For the capability stuff, as the client, the opaque/dynamic masks are stored in For bitmasks in the protocol, it really depends on the definition. Probably yes. With #[enumflags2::bitflags]
#[repr(u64)]
enum MyFlag {}
struct ProtoMyFlags {
known: enumflags2::BitFlags<MyFlag>,
unknown: u64
}With a PR, You can always do this too: #[enumflags2::bitflags]
#[repr(u64)]
enum MyFlag {}
struct ProtoMyFlags(u64);
impl ProtoMyFlags {
fn iter(&self) -> enumflags2::Iter {
BitFlags::<MyFlag>::from_bits_truncate(self.0).iter()
}
fn has_flag(&self, flag: MyFlag) {
BitFlags::<MyFlag>::from_bits_truncate(self.0).contains(flag)
}
fn get_unknown(&self) -> u64 {
self.0 & !BitFlags::<MyFlag>::ALL.bits()
}
}
With flags.iter_names(|flag| match flag.bits() {
Self::A => do_thing(),
_ => unreachable!() // the compiler forces this on you!
})
fn interface_name(&self) -> Option<&'static str> {
match self.bits() {
Self::A => Some("a"),
_ => None // same thing, and here the library isn't even promising that `self` is always a single valid flag
}
}Compare to the equivalent with flags.iter(|flag| match flag {
Self::A => do_thing(),
// It's a Rust enum so we know this is exhaustive
})
fn interface_name(&self) -> &'static str {
match self {
Self::A => "a",
// same thing
}
}While writing this, I got a reply to meithecatte/enumflags2#66. |
|
Ah right. So basically I think |
8f4a39d to
049ca9d
Compare
|
Ugh.. Is there an MSRV of 1.70.0? Shouldn't it be specified in the Cargo.toml? |
Line 9 in a531810 |
ccce246 to
ae01709
Compare
|
Sorry for the delay! I wondered why Rust or Clippy didn't check the MSRV: rust-lang/compiler-team#772 Can you help fix the libei test? I don't see how I broke it |
|
Running the tests locally, it seems So that breaks with the Then there's also |
|
https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/352 has the fix for that test. |
cf12669 to
01f8ff6
Compare
|
Seems that CI doesn't run |
|
Still fails with the below?? |
|
The test passes for me with these two changes: diff --git a/src/event.rs b/src/event.rs
index e042fc0..4728acf 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -680,17 +680,17 @@ pub struct Keymap {
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum DeviceCapability {
/// Capability for relative pointer motion.
- Pointer = 1 << 0,
+ Pointer = 1 << 1,
/// Capability for absolute pointer motion.
- PointerAbsolute = 1 << 1,
+ PointerAbsolute = 1 << 2,
/// Capability for keyboard input events.
- Keyboard = 1 << 2,
+ Keyboard = 1 << 3,
/// Capability for touch input events.
- Touch = 1 << 3,
+ Touch = 1 << 4,
/// Capability for scroll input events.
- Scroll = 1 << 4,
+ Scroll = 1 << 5,
/// Capability for mouse button input events.
- Button = 1 << 5,
+ Button = 1 << 6,
}
impl DeviceCapability {
diff --git a/src/request.rs b/src/request.rs
index 4b08a3f..fb0e90c 100644
--- a/src/request.rs
+++ b/src/request.rs
@@ -27,7 +27,7 @@ pub enum RequestError {
impl fmt::Display for RequestError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- Self::InvalidCapabilities => write!(f, "invalid capabilities"),
+ Self::InvalidCapabilities => write!(f, "Invalid capabilities"),
}
}
}The use of |
| Err(err) => { | ||
| if let reis::Error::Request(reis::request::RequestError::InvalidCapabilities) = | ||
| err | ||
| { | ||
| Ok(context_state.disconnected( | ||
| connected_state, | ||
| eis::connection::DisconnectReason::Value, | ||
| &err.to_string(), | ||
| )) | ||
| } else { | ||
| Ok(context_state.protocol_error(connected_state, &err.to_string())) | ||
| } | ||
| } |
There was a problem hiding this comment.
@ids1024 What do you think of this? Is this still required with the changes you mention?
Modifying |
|
What do you think of |
The libei tests are just testing the server-side implementation (
Yeah, sounds good to have CI test that. |
I forgot I used
Ohhh now I get it... |
This removes the need for slices and `Vec`s, and makes client and server code a lot simpler to implement with `BitFlags::contains` and friends.
Notes: - Exact command done: `cargo clippy --fix --features calloop,tokio -- -W clippy::pedantic` - Undid fixes for auto-generated files, for now - Ran `cargo fmt`
Not literally everything, but almost; some things aren't perfect and a couple of enums are ignored.
dca100e to
0db1cd5
Compare
0db1cd5 to
2eb802f
Compare
|
Re-running the CI job now that libei PR is merged, it passes. |
|
Great! Is this ready for merge? |
ids1024
left a comment
There was a problem hiding this comment.
Looking over everything here again, it seems good.
See ids1024/reis#11 Fixes: 03b2f7c ("build(deps): bump reis from 0.5.0 to 0.6.0")
See ids1024/reis#11 Fixes: 03b2f7c ("build(deps): bump reis from 0.5.0 to 0.6.0")
This removes the need for slices and
Vecs, and makes client and server code a lot simpler to implement withBitFlags::containsand friends.