XAMPPRocky
XAMPPRocky

Reputation: 3599

How to extend the lifetimes of Strings within functions of traits that require returning &str?

Problem


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.


Example: Playground link


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

Answers (1)

Malcolm
Malcolm

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

Related Questions