use std::convert::Infallible;
use std::ops::Deref;
use tonic::Code;
pub trait IsGrpcError: std::error::Error + Sized {
fn code(&self) -> Code;
}
impl<T: IsGrpcError> IsGrpcError for Box<T> {
fn code(&self) -> Code {
self.as_ref().code()
}
}
impl IsGrpcError for Infallible {
fn code(&self) -> Code {
unreachable!()
}
}
#[derive(thiserror::Error, Debug, Clone)]
#[error(transparent)]
pub struct GrpcError<E: IsGrpcError>(#[from] E);
impl<E: IsGrpcError> From<GrpcError<E>> for tonic::Status {
fn from(error: GrpcError<E>) -> Self {
tonic::Status::new(error.code(), error.to_string())
}
}
impl<E: IsGrpcError> Deref for GrpcError<E> {
type Target = E;
fn deref(&self) -> &Self::Target {
&self.0
}
}