enumify
A Rust macro that declares an enum (and a bunch of impl Froms) based on a set of types.
Examples
There are two poster child cases where the code generation of enumify can cut down on a lot of boilerplate: dispatching on an enum and abstract syntax trees.
Dispatching on an enum
When working with threads, a very common approach is to organize them like agents: the thread communicates with other threads through message-passing using asynchronous channels such as crossbeam::channel or tokio::sync::mpsc and the thread has a pre-determined set of messages that it can handle. This approach makes use of a "main loop" that may resemble the following code snippet:
while let Ok = receiver.recv
While this may look harmless and quite pleasant to look at at the surface level, the oblivious onlooker has no idea of the amount of belligerent boilerplate that was manually written in order to both declare a struct for each of the variants and then an enum Message containing a variant for each of the structs. This is motivating enough, but 9 times out of 10 there's also a barrage of impl From waiting just ahead.
enumify solves this problem by generating the repetitive part automatically. For example, declaring Message and the associated conversions is as easy declaring a struct for each of the variants:
enumify!
You can declare impls targeting the enum and the structs as if you had declared them yourself:
The automatically derived conversions make constructing a new message just as easy:
Abstract syntax trees
Working with recursive types in Rust is ever so very slightly annoying. One Box here, another Rc there and it's generally fine. The problem is that the annoyance scales linearly with the amount of wrapping that needs to be done. One of the cases where this annoyance reaches critical mass is with abstract syntax trees. Fortunately, enumify can help us here too: declaring an #[enumify(Wrapper)] attribute on top of some struct wraps the corresponding variant in the enum with the type specificed in the attribute. For example, declaring a type for the untyped lambda calculus looks similar to the following:
enumify!