use std::fmt;
pub type StorageResult<T> = std::result::Result<T, StorageError>;
pub type ComputeResult<T> = std::result::Result<T, ComputeError>;
pub type ModelResult<T> = std::result::Result<T, ModelError>;
#[derive(Debug, Clone, PartialEq)]
pub enum StorageError {
Backend {
message: String,
},
Deserialization {
key: String,
message: String,
},
Serialization {
key: String,
message: String,
},
}
impl StorageError {
pub fn backend(message: impl Into<String>) -> Self {
StorageError::Backend { message: message.into() }
}
}
impl fmt::Display for StorageError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
StorageError::Backend { message } => {
write!(f, "Storage backend error: {}", message)
}
StorageError::Deserialization { key, message } => {
write!(f, "Failed to deserialize value for key '{}': {}", key, message)
}
StorageError::Serialization { key, message } => {
write!(f, "Failed to serialize value for key '{}': {}", key, message)
}
}
}
}
impl std::error::Error for StorageError {}
#[derive(Debug, Clone, PartialEq)]
pub enum ComputeError {
NodeOutOfBounds {
node_id: String,
got_bound: (i32, i32),
expected_bound: (i32, i32),
},
MaxIterationsExceeded {
max_iters: usize,
},
CycleDetected {
node_id: String,
},
}
impl fmt::Display for ComputeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ComputeError::NodeOutOfBounds {
node_id,
got_bound,
expected_bound,
} => write!(
f,
"Node '{}' out of bounds: got {:?}, expected {:?}",
node_id, got_bound, expected_bound
),
ComputeError::MaxIterationsExceeded { max_iters } => {
write!(f, "Max iterations exceeded during tightening: {}", max_iters)
}
ComputeError::CycleDetected { node_id } => {
write!(f, "Cycle detected in DAG at node '{}'", node_id)
}
}
}
}
impl std::error::Error for ComputeError {}
#[derive(Debug, Clone, PartialEq)]
pub enum ModelError {
EmptyConstraint,
NodeNotFound {
node_id: String,
},
NodeReferenced {
node_id: String,
referencing_nodes: Vec<String>,
},
Backend(StorageError),
}
impl From<StorageError> for ModelError {
fn from(err: StorageError) -> Self {
ModelError::Backend(err)
}
}
impl fmt::Display for ModelError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ModelError::EmptyConstraint => write!(
f,
"Constraint cannot be empty; at least one coefficient is required"
),
ModelError::NodeNotFound { node_id } => {
write!(f, "Node '{}' not found in storage", node_id)
}
ModelError::NodeReferenced {
node_id,
referencing_nodes,
} => write!(
f,
"Cannot delete node '{}'; it is referenced by nodes: {:?}",
node_id, referencing_nodes
),
ModelError::Backend(err) => write!(f, "{}", err),
}
}
}
impl std::error::Error for ModelError {}