obv-mikhail / InputBot

Rust library for creating global hotkeys, and simulating inputs
MIT License
400 stars 72 forks source link

serde feature #94

Closed masonk closed 8 months ago

masonk commented 8 months ago

When using inputbot to expose global hotkeys for users, it's natural to allow the user to configure the keybinds via a configuration file. In order to do this, it's necessary to define a serialization format for KeybdKey and MouseButton, and that format should be convenient for humans to read and write.

I needed this for an app I'm writing, and I think it'd be good for the library (and for me) to upstream serialization.

However, serialization is a user-facing change, and there were several judgment calls to make. The foremost question was whether to preserve the existing Display impls and define a different "canonical" mapping for the serialization format. While I tried it both ways, ultimately I felt it'd be confusing if Display didn't roundtrip through serialization, and conversely, that it'd be strange if the serialization format required two words to represent a key. So I changed some of the Display impls, e.g. "Left Control" became "LeftControl".

The second issue is that deserialization requires exposing an error type. It might make sense for inputbot to expose an omnibus error enum, but I chose to keep it contained to just a deserialization error type in this patch. I generally don't like omnibus errors (e.g. InputBot::Error), because not every operation that can fail can fail in the same ways.

The final issue was that this patch adds a lot of dependencies to InputBot, which is a nice, lean crate. To this end, every single line of code in this patch except #![feature(error_generic_member_access)] in lib.rs is behind the "serde" feature gate. So, the only new deps are opt-in.

masonk commented 8 months ago

And one more thing - I chose to make the serialization format case-insensitive. "F1" and "f1" both deserialize to KeybdKey::F1, and so forth. I think this is more convenient for end-users, and doesn't really paint InputBot into a corner, because honestly there shouldn't be two distinct keys with a name differing only by case. But it was a judgment call that I made while upstreaming this, so I'm calling it out here.

masonk commented 8 months ago

Thanks for the suggestion! I wasn't aware of OnceLock - have been out of the Rust game for a few years.