use std::fmt::{Display, Formatter};

/// A type-erased [`Error`](std::error::Error).
#[derive(Debug)]
pub struct BoxedError(Box<dyn std::error::Error + Send + Sync>);

impl Display for BoxedError {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
        self.0.fmt(f)
    }
}

pub(crate) fn transform_error<
    R: std::error::Error,
    P: std::error::Error + Send + Sync + 'static,
>(
    e: rcore::Error<R, P>,
) -> rcore::Error<R, BoxedError> {
    match e {
        rcore::Error::Request(e) => rcore::Error::Request(e),
        rcore::Error::Provider(e) => rcore::Error::Provider(BoxedError(Box::new(e))),
        rcore::Error::NotImplemented => rcore::Error::NotImplemented,
    }
}

impl std::error::Error for BoxedError {}
