0

I'm implementing FizzBuzz in Rust. I went from the simplest version to using an enum and I can't resolve it. I've read enums are very potent so I tried to use them to their fullest.

Here is my implementation:

use std::fmt;

fn main() {
    for i in 1..100 {
        println!("{}", fizzbuzz(i))
    }
}

fn fizzbuzz(value: i32) -> Answer {
    use crate::Answer::*;
    return match (value % 3, value % 5) {
        (0, 0) => FizzBuzz,
        (0, _) => Fizz,
        (_, 0) => Buzz,
        (_, _) => Nothing(value),
    };
}

enum Answer {
    FizzBuzz,
    Fizz,
    Buzz,
    Nothing(i32),
}

impl fmt::Display for Answer {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use crate::Answer::*;
        match self {
            FizzBuzz => write!(f, "FizzBuzz"),
            Fizz => write!(f, "Fizz"),
            Buzz => write!(f, "Buzz"),
            Nothing() => write!(f, "number passed to NoBuzz"),
        }
    }
}

I have 2 problems:

  • how to use the name of actual enum in match self block? In Java, I could use just FizzBuzz.name() and it would print "FizzBuzz" - is it possible in Rust?

  • is it possible to print that value I passed to Nothing in fizzbuzz function?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
doublemc
  • 3,021
  • 5
  • 34
  • 61
  • 1
    `return match { ... };`: don't do that, that's very unidiomatic. Instead remove `return` and the `;`. – hellow Jan 06 '19 at 20:43
  • Someone's marked this as a duplicate, but neither of the questions it points to actually address the issue on how to *return* the Enum value from a function without getting a `Cannot move` error... – c z Feb 22 '22 at 12:07

1 Answers1

2

You can derive a printable representation for debugging purposes with #[derive(Debug)]. This would let you print it out using println!("{:?}", self)

Example:

#[derive(Debug)]
enum Answer {
    FizzBuzz,
    Fizz,
    Buzz,
    Nothing(i32),
}
match self {
    Nothing(_) -> /* ... */,
    other -> println!("{:?}", other),
}

However, it's much more appropriate to write a Display instance yourself. You'll have to do the translation (Fizz -> "Fizz", etc) yourself, but then it will be in a centralized location and you can pass it to formatters like you've been doing.

To get the value out of the Nothing, you simply need to pattern match on it and give it a name. Instead of

Nothing(_) => // Do something generic

consider

Nothing(n) => // Do something that involves the number n
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
  • 3
    "However, it's much more appropriate to write a Display instance yourself."→ Nah, [there are crates to do that for you](https://github.com/victorporof/rust-enum-str-derive)! – mcarton Jan 06 '19 at 20:47