I have an enum:
pub enum BoxColour {
Red,
Blue,
}
I not only want to get this value as a string, but I want the value to be converted to lower case.
This works:
impl Display for BoxColour {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(match self {
BoxColour::Red => "red",
BoxColour::Blue => "blue",
})?;
Ok(())
}
}
When the list of colours grows, this list would need to be updated.
If I use the write!
macro, it does not seem possible to manipulate the result because write!
returns an instance of ()
instead of a String
:
impl Display for BoxColour {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "{:?}", self)
}
}
This suggests that this is working through side effects and maybe we could hack the same place in memory the value is going, but even if that is possible, it probably isn't a good idea...
The strum
crate provides a derive macro for implementing Display
for an enum, and optionally lowercasing the variant names:
use strum_macros::Display;
#[derive(Display)]
// If we don't care about inner capitals, we don't need to set `serialize_all`
// and can leave parenthesis empty.
#[strum(serialize_all = "snake_case")]
pub enum BoxColour {
Red,
Blue,
LightGreen, // example of how inner capitals are treated
}
fn main() {
for c in [BoxColour::Red, BoxColor::Blue, BoxColor::LightGreen] {
println!("{}", c);
}
}
You will also need the corresponding dependency on strum
in your Cargo.toml
:
[dependencies]
strum = { version = "0.21", features = ["derive"] }
This should print:
red
blue
light_green
strum
will generate code similar to the match
with BoxColour::Red => "red",
cases that you mentioned, but without the need to update it manually.