Reputation: 3599
I am trying to implement the std::error::Error
trait on a enum. Some elements of the enum are Enum Variants, and I would like to generate a different error message containing the data from the variant. However with the implementation below the formatted String
that Deref
to &str
don't live long enough.
The general solution is to return a String
. However, this is not an option here as the returned type must be &str
as specified by the Error
trait.
It is important to note that the variants may not contain usize, and might instead be another enum, or struct etc.
use std::fmt;
use std::fmt::{Display, Formatter};
use std::error;
#[derive(Debug)]
enum EnumError {
A,
B(usize),
C(usize),
D,
}
impl error::Error for EnumError {
fn description(&self) -> &str {
use EnumError::*;
match *self {
A => "A happened",
B(value) => &*format!("B happened info: {:?}", value),
C(value) => &*format!("B happened info: {:?}", value),
D => "D happened",
}
}
}
impl Display for EnumError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
use std::error::Error;
write!(f, "{}", self.description())
}
}
fn main() {}
Upvotes: 2
Views: 76
Reputation: 41510
The string you create needs to be owned by something. When you create a local string in the method, you have to transfer its ownership to the caller. But since you have to return &str
, this is not an option.
The way around it would be to store the string in the struct itself. You can declare the enum value as B(usize, String)
, put the description there when you create it, and then return it with
B(_, ref descr) => descr
To be frank, description is not supposed to be a terribly detailed message, it just needs to give a general description of what kind of error this is, this is why it returns &str
. I didn't see instances of writing any dynamic data into the description in the standard library, usually it's just a static string. Display
implementation is a different matter though, in there you can be much more verbose.
Upvotes: 4