Reputation: 1471
Is it possible to reference a variant of a enum, by another variant of the same enum in Rust?
Some imaginary code:
enum Message{
Text(String),
Secret(Self::Text)
}
Upvotes: 2
Views: 1716
Reputation: 3397
Yes, it is possible! The Box
type can wrap other types, allowing you to have self-referential types. This is needed in scenarios like linked lists.
I don't believe that you can specify that it wraps a specific variant though, so this is slightly different than what you asked for.
Here's an example with a little demonstration of hiding the secret!
use std::fmt;
enum Message {
Text(String),
Secret(Box<Self>)
}
impl fmt::Display for Message {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let contents = match self {
Message::Text(message) => message.to_string(),
Message::Secret(_) => "(hidden)".to_string(),
};
write!(f, "{}", contents)
}
}
fn main() {
let message = Message::Text("Hello world".to_string());
let secret = Message::Secret(Box::new(Message::Text("Don't read me!".to_string())));
println!("Message: {}", message);
println!("Secret: {}", secret);
}
Here's a playground link using the same code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=292286f473550a38fd24924dfafe7bfe
Upvotes: 4
Reputation: 10136
Unfortunately, you can't. Message
is a type, but Message::Text
is not, and can't be used where types are used.
In this case the trivial solution is to just have Secret
hold a String
. However, assuming your real use case is a bit more complicated, the general strategy is to pull it out into another struct:
enum Message {
Text(MessageData),
Secret(MessageData),
}
struct MessageData {
foo: Bar,
// lots of other fields
}
Upvotes: 6