use tonic::{Code, Status}; #[derive(Debug, thiserror::Error)] pub enum KenShellError { #[error("config: {0}")] Config(String), #[error("transport: {0}")] Transport(#[from] tonic::transport::Error), #[error("rpc {code:?}: {message}")] Rpc { code: Code, message: String }, #[error("timeout")] Timeout, } impl KenShellError { pub fn from_status(status: Status) -> Self { match status.code() { Code::DeadlineExceeded => Self::Timeout, code => Self::Rpc { code, message: status.message().to_string(), }, } } pub fn code(&self) -> Option { match self { Self::Rpc { code, .. } => Some(*code), Self::Timeout => Some(Code::DeadlineExceeded), _ => None, } } pub fn is_not_found(&self) -> bool { self.code() == Some(Code::NotFound) } pub fn is_unauthenticated(&self) -> bool { self.code() == Some(Code::Unauthenticated) } pub fn message(&self) -> String { match self { Self::Config(message) => message.clone(), Self::Transport(error) => error.to_string(), Self::Rpc { message, .. } => message.clone(), Self::Timeout => "deadline exceeded".to_string(), } } } impl From for KenShellError { fn from(status: Status) -> Self { Self::from_status(status) } } pub type KenShellResult = Result;