Is there a way to print enum values?

EnumsRust

Enums Problem Overview


Is there an easy way to format and print enum values? I expected that they'd have a default implementation of std::fmt::Display, but that doesn't appear to be the case.

enum Suit {
    Heart,
    Diamond,
    Spade,
    Club
}

fn main() {
    let s: Suit = Suit::Heart;
    println!("{}", s);
}

Desired output: Heart

Error:

error[E0277]: the trait bound `Suit: std::fmt::Display` is not satisfied
  --> src/main.rs:10:20
   |
10 |     println!("{}", s);
   |                    ^ the trait `std::fmt::Display` is not implemented for `Suit`
   |
   = note: `Suit` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
   = note: required by `std::fmt::Display::fmt`

Enums Solutions


Solution 1 - Enums

You can derive an implementation of std::format::Debug:

#[derive(Debug)]
enum Suit {
    Heart,
    Diamond,
    Spade,
    Club
}

fn main() {
    let s = Suit::Heart;
    println!("{:?}", s);
}

It is not possible to derive Display because Display is aimed at displaying to humans and the compiler cannot automatically decide what is an appropriate style for that case. Debug is intended for programmers, so an internals-exposing view can be automatically generated.

Solution 2 - Enums

The Debug trait prints out the name of the Enumvariant.

If you need to format the output, you can implement Display for your Enum like so:

use std::fmt;

enum Suit {
    Heart,
    Diamond,
    Spade,
    Club
}

impl fmt::Display for Suit {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
       match *self {
           Suit::Heart => write!(f, "♥"),
           Suit::Diamond => write!(f, "♦"),
           Suit::Spade => write!(f, "♠"),
           Suit::Club => write!(f, "♣"),
       }
    }
}

fn main() {
    let heart = Suit::Heart;
    println!("{}", heart);
}

Solution 3 - Enums

If you want to auto-generate Display implementations for enum variants you might want to use the strum crate:

#[derive(strum_macros::Display)]
enum Suit {
    Heart,
    Diamond,
    Spade,
    Club,
}

fn main() {
    let s: Suit = Suit::Heart;
    println!("{}", s); // Prints "Heart"
}

Solution 4 - Enums

Combining both DK. and Matilda Smeds answers for a slightly cleaner version:

use std::fmt;

#[derive(Debug)]
enum Suit {
    Heart,
    Diamond,
    Spade,
    Club
}

impl fmt::Display for Suit {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
       write!(f, "{:?}", self)
    }
}

fn main() {
    let heart = Suit::Heart;
    println!("{}", heart);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDaniel LucraftView Question on Stackoverflow
Solution 1 - EnumsDK.View Answer on Stackoverflow
Solution 2 - EnumsMatilda SmedsView Answer on Stackoverflow
Solution 3 - EnumsnjamView Answer on Stackoverflow
Solution 4 - EnumsraugferView Answer on Stackoverflow