Do not wait for Rust generators

What is generator?

Generators are a pattern widely used in the Python ecosystem, like iterators, they are very useful to produce multiple values. But unlike iterators, they work by interrupting the execution of the function, and allows the caller to resume its execution later:

The yield keyword interrupts the function and produce the supplied value. Now, instead of using the next() function to resume the generator, you can use:

  • gen.send(value): the yield keyword will return value when resuming
  • gen.throw(exc): the yield keyword will throw exc when resuming
  • gen.close(): the generator won’t resume (and raise a StopIteration)

NB: This is also called a coroutine.

They are a powerful tool. In fact, they were used for concurrency before the rise of async/await!

Unfortunately, at the time of writing, this is still an unstable feature in Rust.

Introducing… genawaiter!

This crate gives you, thanks to some useful macros, the unstable feature in stable Rust:

Just like Python, the yield_! macro will interrupt the execution of the code block, the gen.resume() function will return a GeneratorState enum with the yielded value or the final return value.

If called with gen.resume_with(arg), the yield_! macro will return arg.

One last trick…

Every generators implement the trait Generator<Yield = Y, Return = R>. If, like me, you have some Python background, you’d like to return such generators, possibly make a trait with a function to return such generators, the problem here is:

  • you can’t use impl Trait in type-aliases or in trait function signatures (unstable feature)
  • you can’t return a local variable as a &dyn Trait (the variable goes out of scope, this will never be a feature thankfully)

At the moment, one solution is to move the generator into a Box<dyn Trait>:

Conclusion

You don’t need to wait to use this feature, genawaiter aims to be a “drop-in” replacement of the currently unstable feature. Once it’s generally available, it should be a matter of renaming imports.

--

--

--

CEO & Co-Founder at Link Society

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How To Step Up Your Python Coding Game With Githooks

Agile, and the failure of the Russian Waterfall battle management in Ukraine.

Browser Automation: How an efficient Selenium Cloud Platform should look like in 2020

What’s the pubspec.lock file in a Flutter Project?

A Tech Sis and Her Zuri Journey

Production Express

Express

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
David Delassus

David Delassus

CEO & Co-Founder at Link Society

More from Medium

Rust 003 — Ownership Rules

Rust WebAssembly — Sharing data between WebWorkers

Rust Language — Beginner’s Notes

Building a Single Page Application in Rust(Yew) — Part 1