SawwAL
SawwAL

Reputation: 27

Cast a mp3_metadata::Genre to String

I want to cast mp3_metadata::Genre ( its an enum ) to a String , I tried to do :

impl fmt::Display for mp3_metadata::Genre {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
        // or, alternatively:
        // fmt::Debug::fmt(self, f)
    }
}

But it told me

Genre` is not defined in the current crate
impl doesn't use only types from inside the current crate

I dont know if there is a simple way to cast an enum to String without the impl (I'm a beginner in rust I don't know too much about impl) .

Upvotes: 0

Views: 70

Answers (2)

Jerboas86
Jerboas86

Reputation: 654

The orphan rules forbid you from writing an impl where both the trait and the type are defined in a different crate.

So you have two options:

  • create your own trait
  • create your own type

Create your own trait

use mp3_metadata::Genre

trait ParseEnum {
    fn stringify(&self) -> String;
}

impl ParseEnum for Genre {
    fn stringify(&self) -> String {
        use Genre::{Rock, Pop};
        match self {
            Rock => format!("Rock"),
            Pop => format!("Pop"),
            _ => format!("Other")
        }
    }
}

fn main() {
    let g = Genre::Rock;
    println!("{}", g.stringify());
}

Create your own type by using newtype pattern

see lkolbly's answer

Upvotes: 1

lkolbly
lkolbly

Reputation: 1240

If you specifically need the Display trait, you'll need to make that change upstream. However, it looks like that type implements Debug, which means you can use {:?} in println! and format! and the like (like you do in the example you posted).

You can get around this by making your own type which is a wrapper around Genre, and implementing Display for that (this is the new type idiom mentioned in the comments):

struct MyGenre(mp3_metadata::Genre);

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

Upvotes: 2

Related Questions