use std::fmt;
use linkrs_core::error::QueryError;
#[derive(Debug, Clone)]
pub enum PlanBuildError {
UnsupportedNode {
node_type: String,
node_id: i64,
detail: String,
},
MissingRequiredValue {
node_type: String,
node_id: i64,
field: String,
detail: String,
},
CapabilityUnavailable { capability: String, detail: String },
InvalidTransactionMode {
required: String,
actual: String,
detail: String,
},
ExpressionBinding {
node_type: String,
node_id: i64,
expression: String,
detail: String,
},
}
impl PlanBuildError {
pub fn unsupported(
node_type: impl Into<String>,
node_id: i64,
detail: impl Into<String>,
) -> Self {
Self::UnsupportedNode {
node_type: node_type.into(),
node_id,
detail: detail.into(),
}
}
pub fn missing_value(
node_type: impl Into<String>,
node_id: i64,
field: impl Into<String>,
detail: impl Into<String>,
) -> Self {
Self::MissingRequiredValue {
node_type: node_type.into(),
node_id,
field: field.into(),
detail: detail.into(),
}
}
pub fn capability(capability: impl Into<String>, detail: impl Into<String>) -> Self {
Self::CapabilityUnavailable {
capability: capability.into(),
detail: detail.into(),
}
}
pub fn expression(
node_type: impl Into<String>,
node_id: i64,
expression: impl Into<String>,
detail: impl Into<String>,
) -> Self {
Self::ExpressionBinding {
node_type: node_type.into(),
node_id,
expression: expression.into(),
detail: detail.into(),
}
}
}
impl fmt::Display for PlanBuildError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::UnsupportedNode {
node_type,
node_id,
detail,
} => {
write!(
f,
"Unsupported node '{}' (id={}): {}",
node_type, node_id, detail
)
}
Self::MissingRequiredValue {
node_type,
node_id,
field,
detail,
} => {
write!(
f,
"Missing required value '{}' for node '{}' (id={}): {}",
field, node_type, node_id, detail
)
}
Self::CapabilityUnavailable { capability, detail } => {
write!(
f,
"Capability '{}' is not available: {}",
capability, detail
)
}
Self::InvalidTransactionMode {
required,
actual,
detail,
} => {
write!(
f,
"Transaction mode mismatch: required '{}', actual '{}': {}",
required, actual, detail
)
}
Self::ExpressionBinding {
node_type,
node_id,
expression,
detail,
} => {
write!(
f,
"Expression binding error in node '{}' (id={}): '{}' - {}",
node_type, node_id, expression, detail
)
}
}
}
}
impl std::error::Error for PlanBuildError {}
impl From<PlanBuildError> for QueryError {
fn from(e: PlanBuildError) -> Self {
QueryError::execution(e.to_string())
}
}