Async #Rust is actually awesome!  

The last few days I've built a prototype(!) of a global "Hotkey" system e.g.:

Press & Hold `LCtrl + Space`
=> an async stream starts and only finishes if:
- another key is pressed or
- one of the Hotkeys is released

If it is not clear by now: this is a state-machine, which fits _perfectly_ into Rust's #async model!

And the best part: This is actually _the first time_ I've ever touched async #RustLang! Such a pleasant experience!

1/?

#AsyncRust

For this to work, I had to transform a sync callback with the keypress events (from `device_query` crate) to an async stream.
This can be done with a channel:
- use send (blocking-variant) from within the callback
- use async receiver in your stream impl

In the following post, I'll list some crates that have helped me achieve this...

2/?

First, the async runtime:

My advice: If you're new to async Rust, start with a single-threaded-by-default runtime like `smol`:
https://docs.rs/smol/latest/smol/

Tokio's multi-threading by default and its frequent recommendation (especially to newcomers) is, IMHO, one of the biggest mistakes the Rust community has made!

Smol has everything you commonly need:
- channel
- Stream adapters
- (very flexible) executor
- etc.

3/?

smol - Rust

A small and fast async runtime.

Second: Pinning helpers!

When doing async #Rust, there will be a point, where you'll get the ominous "Doesn't implement Unpin" error and "You need to pin your value".

First, learn about Pinning:
https://doc.rust-lang.org/std/pin/

Like, _really_ learn and understand it:
https://fasterthanli.me/articles/pin-and-suffering

And then use smol's pin! macro and the `pin_project` crate:
https://docs.rs/pin-project/latest/pin_project/

I might continue this thread with more insights I gain during this little project - stay tuned! 🙂

4/4?

#RustLang #AsyncRust

std::pin - Rust

Types that pin data to a location in memory.