Skip to main content

ferrox/
error.rs

1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum FerroxError {
5    #[error("solver returned infeasible")]
6    Infeasible,
7    #[error("solver returned unbounded")]
8    Unbounded,
9    #[error("model invalid: {0}")]
10    ModelInvalid(String),
11    #[error("solver error")]
12    SolverError,
13    #[error("serialization error: {0}")]
14    Serde(#[from] serde_json::Error),
15    #[error("no pending request")]
16    NoPendingRequest,
17}
18
19pub type Result<T> = std::result::Result<T, FerroxError>;
20
21#[cfg(test)]
22#[allow(clippy::unnecessary_wraps)]
23mod tests {
24    use super::*;
25
26    #[test]
27    fn display_formats_known_variants() {
28        assert_eq!(
29            FerroxError::Infeasible.to_string(),
30            "solver returned infeasible"
31        );
32        assert_eq!(
33            FerroxError::Unbounded.to_string(),
34            "solver returned unbounded"
35        );
36        assert!(
37            FerroxError::ModelInvalid("bad".into())
38                .to_string()
39                .contains("bad")
40        );
41        assert_eq!(FerroxError::SolverError.to_string(), "solver error");
42        assert_eq!(
43            FerroxError::NoPendingRequest.to_string(),
44            "no pending request"
45        );
46    }
47
48    #[test]
49    fn from_serde_json_error() {
50        let bad: serde_json::Error = serde_json::from_str::<i32>("not json").unwrap_err();
51        let err: FerroxError = bad.into();
52        assert!(matches!(err, FerroxError::Serde(_)));
53        assert!(err.to_string().contains("serialization"));
54    }
55
56    #[test]
57    fn result_alias_resolves() {
58        fn ok() -> Result<i32> {
59            Ok(7)
60        }
61        assert_eq!(ok().unwrap(), 7);
62    }
63}