Trait for something generic, but errors could be specific for trait implementation

Let's say I have a trait for a Decoder, and I have specific decoders that implement this trait:

pub trait Decoder {
    fn do_something(&self) -> Result<(), DoSomethingError>;
}

pub enum DoSomethingError {}

pub struct SpecificDecoder1 {}

impl Decoder for SpecificDecoder1 {
    fn do_something(&self) -> Result<(), DoSomethingError> {
        todo!()
    }
}

pub struct SpecificDecoder2 {}

impl Decoder for SpecificDecoder2 {
    fn do_something(&self) -> Result<(), DoSomethingError> {
        todo!()
    }
}

each decoder could return specific errors. However, I don't want to include these specific errors in the DoSomethingError trait as some decoders could not even be available on some devices, so I don't want the mess of #cfg(feature="...") on the enum.

I thought about

pub trait DoSomethingError {}
fn do_something(&self) -> Result<(), Box<dyn DoSomethingError>> {
    Ok(self.do_another_something()?)
}

this way I can downcast the Box<dyn DoSomethingError> to a specific error if needed. However, Ok(self.do_another_something()?) wouldn't work. Remember that I don't want to store a string, I want to be able to match the error somehow, or try to match it, so I cannot create a UserDefined(String) variant on the string and convert every error to it.

If the returned error type varies by the implementor of the trait, then it should probably be an associated type instead of anything concrete.

1 Like

For example, see the associated type Error in