Handling Rust enum variants with kinded crateSerhii Potapov August 07, 2023 #rust #traits #macro #enum
Over the weekend, I delved into crafting a tiny procedural macro library called kinded. The idea behind this venture originated from my need to support another procedural macro library of mine, nutype.
In this article, I will walk you through the concept and application of the
The Use Case: Building a Beverage Selection UI
Imagine you're developing a beverage ordering application. Users can choose from a variety of drinks, some of which might have additional customization options. For instance, you offer various types of coffee and tear, each with different flavors. To create a smooth user experience, you want to present users with a selection of drink categories first and then prompt them for specific details based on their selection.
Drink enum captures the different types of beverages available:
However, building the UI becomes a bit tricky. You want to display a list of drink categories to users before they provide additional details for their chosen drink. To do this, you need to extract just the kind of each variant without dealing with the associated data.
So we introduce
DrinkKind type, which is just a plain twin of
Drink without extra data attached to variants:
We may also want to have ability to convert
And ability to iterate over all variants of
The problem with the solution
The solution above will work. But if you have 20 of such enums, the boilerplate work multiplies.
Also the maintenance cost is doubled: if you want to add a new drink (e.g.
Mate 🧉), you'd need extend
And do not forget to update
DrinkKind::all() implementation! The compiler won't ask you to do it.
The boilerplate can be eliminated with help of kinded crate and its
Kinded derive macro:
This generates exactly the same code (and a bit more), that wrote manually in the previous step.
Listing drink variants
So now we can list all the possible drink variants as the following:
for drink_kind in all
TapWater Coffee Tea
TapWater does not look very human friendly. We'd rather like to see
Tap Water instead.
It's possible to customize implementation of
Display crate for
display = option.
TapWater variant is displayed as
Tap Water. At the moment of writing, the library supports 9 different casing strategies like
What about parsing?
FromStr is also generated for free and is capable to parse all possible spelling of the variants.
let alt_spellings = ; for alt_spelling in alt_spellings
Closing the Beverage Select UI
Once the user selects a drink category, you can further retrieve the associated data from the original
Drink enum based on the choice:
kinded library simplifies the handling of enums with associated data by generating a kind type
that abstracts away the data, making it easier to build user interfaces and handle various enum variants and to write parsers.
To learn more about the
kinded library please check the following links:
Back to top