use thiserror::Error;
#[derive(Error, Debug)]
pub enum RSCMError {
#[error("{0}")]
Error(String),
#[error("Extrapolation is not allowed. Target={0}, {1} interpolation range={2}")]
ExtrapolationNotAllowed(f32, String, f32),
#[error("Wrong input units. Expected {0}, got {1}")]
WrongUnits(String, String),
#[error("Unsupported grid transformation from {from} to {to}. This transformation is not defined because it would require additional physical assumptions. Consider creating a custom component that explicitly handles this disaggregation, or use an intermediate transformation.")]
UnsupportedGridTransformation { from: String, to: String },
#[error("Grid type mismatch for variable '{variable}': producer component '{producer_component}' outputs {producer_grid} but consumer component '{consumer_component}' expects {consumer_grid}. \n\nPossible resolutions:\n 1. Change {producer_component} to output {consumer_grid}\n 2. Change {consumer_component} to accept {producer_grid}\n 3. Insert a grid transformation component between them\n 4. If aggregation is acceptable, the model coupler can auto-transform from finer to coarser grids")]
GridTypeMismatch {
variable: String,
producer_component: String,
consumer_component: String,
producer_grid: String,
consumer_grid: String,
},
#[error("Missing initial value for state variable '{variable}' in component '{component}'. State variables require an initial value. Use ModelBuilder::with_initial_value(\"{variable}\", value) to provide one, or set a default in the component's parameter configuration.")]
MissingInitialValue { variable: String, component: String },
#[error("Variable '{name}' not found in state. Available variables: {available}. Ensure the variable is produced by a component or provided as exogenous input.")]
VariableNotFound { name: String, available: String },
#[error(
"Invalid region index {index} for grid type {grid_type}. Valid indices are 0..{max_index}."
)]
InvalidRegionIndex {
index: usize,
grid_type: String,
max_index: usize,
},
#[error("Circular dependency detected in component graph: {cycle}. Components cannot form cycles. Consider splitting the cycle by introducing intermediate state variables or restructuring the component dependencies.")]
CircularDependency { cycle: String },
#[error("Grid output mismatch for variable '{variable}': component tried to output {component_grid} but variable expects {expected_grid}. Ensure the component's StateValue variant matches the RequirementDefinition's grid_type.")]
GridOutputMismatch {
variable: String,
expected_grid: String,
component_grid: String,
},
}
pub type RSCMResult<T> = Result<T, RSCMError>;