use serde_json::Value;
use thiserror::Error;
#[derive(Debug, Clone, Copy)]
pub enum ErrorCode {
ParseError,
InvalidRequest,
MethodNotFound,
InvalidParams,
InternalError,
ServerError,
}
impl ErrorCode {
pub fn code(self) -> i64 {
match self {
Self::ParseError => -32700,
Self::InvalidRequest => -32600,
Self::MethodNotFound => -32601,
Self::InvalidParams => -32602,
Self::InternalError => -32603,
Self::ServerError => -32000,
}
}
}
impl std::fmt::Display for ErrorCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.code())
}
}
#[derive(Debug, Error)]
pub enum Error {
#[error("io error: {0}")]
Io(#[from] std::io::Error),
#[error("json error: {0}")]
Json(#[from] serde_json::Error),
#[error("rpc error {code}: {message}")]
Rpc {
code: ErrorCode,
message: String,
data: Option<Value>,
},
#[error("protocol error: {0}")]
Protocol(&'static str),
}
impl Error {
pub fn method_not_found(method: &str) -> Self {
Self::Rpc {
code: ErrorCode::MethodNotFound,
message: format!("method not found: {method}"),
data: None,
}
}
pub fn invalid_params(message: impl Into<String>) -> Self {
Self::Rpc {
code: ErrorCode::InvalidParams,
message: message.into(),
data: None,
}
}
pub fn is_method_not_found(&self) -> bool {
matches!(
self,
Error::Rpc {
code: ErrorCode::MethodNotFound,
..
}
)
}
}