use crate::hir::types::Span;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum HirError {
Malformed { code: &'static str, message: String },
IncompatibleProtocol { expected: String, received: String },
UnsupportedNode { kind: String, span: Option<Span> },
Invalid {
code: &'static str,
message: String,
span: Option<Span>,
},
}
impl HirError {
pub fn code(&self) -> &'static str {
match self {
HirError::Malformed { code, .. } => code,
HirError::IncompatibleProtocol { .. } => "incompatible-protocol",
HirError::UnsupportedNode { .. } => "unsupported-node",
HirError::Invalid { code, .. } => code,
}
}
pub fn message(&self) -> String {
match self {
HirError::Malformed { message, .. } => message.clone(),
HirError::IncompatibleProtocol { expected, received } => {
format!("incompatible protocol: expected {expected}, received {received}")
}
HirError::UnsupportedNode { kind, .. } => {
format!("unsupported node kind '{kind}'")
}
HirError::Invalid { message, .. } => message.clone(),
}
}
pub fn span(&self) -> Option<&Span> {
match self {
HirError::UnsupportedNode { span, .. } => span.as_ref(),
HirError::Invalid { span, .. } => span.as_ref(),
_ => None,
}
}
}
impl std::fmt::Display for HirError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.code(), self.message())
}
}
impl std::error::Error for HirError {}
impl From<serde_json::Error> for HirError {
fn from(error: serde_json::Error) -> Self {
HirError::Malformed {
code: "malformed-payload",
message: error.to_string(),
}
}
}
pub(crate) fn invalid(
code: &'static str,
message: impl Into<String>,
span: Option<Span>,
) -> HirError {
HirError::Invalid {
code,
message: message.into(),
span,
}
}