1use thiserror::Error as ThisError;
9
10#[derive(Debug, ThisError)]
12#[non_exhaustive]
13pub enum Error {
14 #[error(transparent)]
16 Core(#[from] powerio::Error),
17
18 #[cfg(feature = "matrix")]
20 #[error(transparent)]
21 Matrix(#[from] powerio_matrix::Error),
22
23 #[error(transparent)]
25 Io(#[from] std::io::Error),
26
27 #[error("case has no generators; DC-OPF requires an `mpc.gen` block")]
28 NoGenerators,
29
30 #[error(
31 "generator {gen_index} has an unsupported cost model (model {model}, ncost {ncost}); need polynomial model 2 with degree ≤ 2"
32 )]
33 UnsupportedCostModel {
34 gen_index: usize,
35 model: u8,
36 ncost: usize,
37 },
38}
39
40impl Error {
41 #[must_use]
46 pub fn category(&self) -> powerio::ErrorCategory {
47 use powerio::ErrorCategory as C;
48 match self {
49 Error::Core(inner) => inner.category(),
50 #[cfg(feature = "matrix")]
51 Error::Matrix(inner) => inner.category(),
52 Error::Io(_) => C::Io,
53 Error::NoGenerators | Error::UnsupportedCostModel { .. } => C::Data,
55 }
56 }
57}
58
59pub type Result<T> = std::result::Result<T, Error>;
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use powerio::ErrorCategory::{Data, Parse};
66
67 #[test]
68 fn category_pins_the_intended_buckets() {
69 assert_eq!(Error::NoGenerators.category(), Data);
70 assert_eq!(
71 Error::UnsupportedCostModel {
72 gen_index: 0,
73 model: 1,
74 ncost: 4
75 }
76 .category(),
77 Data
78 );
79 }
80
81 #[test]
82 fn a_wrapped_hub_error_keeps_its_own_category_and_message() {
83 let wrapped: Error = powerio::Error::MissingField("gen").into();
84 assert_eq!(wrapped.category(), Parse);
85 assert_eq!(
86 wrapped.to_string(),
87 powerio::Error::MissingField("gen").to_string()
88 );
89 }
90}