poolsim_core/error.rs
1//! Error types and helpers for the public `poolsim-core` API.
2//!
3//! `PoolsimError` is designed to work for both library callers and service
4//! adapters:
5//!
6//! - stable machine-readable codes via [`PoolsimError::code`]
7//! - optional structured error details via [`PoolsimError::details`]
8//! - human-readable messages via `Display`
9//!
10//! This makes the same error type suitable for direct Rust usage, CLI
11//! rendering, and HTTP/WebSocket translation in `poolsim-web`.
12
13use serde_json::Value;
14use thiserror::Error;
15
16/// Error type returned by `poolsim-core` public APIs.
17#[derive(Debug, Error)]
18pub enum PoolsimError {
19 /// Invalid input payload or violated input constraints.
20 #[error("{message}")]
21 InvalidInput {
22 /// Stable machine-readable error code.
23 code: &'static str,
24 /// Human-readable error message.
25 message: String,
26 /// Optional structured details for API responses.
27 details: Option<Value>,
28 },
29
30 /// System is saturated (`rho >= 1.0`) for the requested configuration.
31 #[error("system saturated at rho={rho:.4}")]
32 Saturated {
33 /// Utilization ratio (`rho`) at failure time.
34 rho: f64,
35 },
36
37 /// Distribution fitting/sampling failure.
38 #[error("distribution error: {0}")]
39 Distribution(String),
40
41 /// Simulation runtime failure.
42 #[error("simulation error: {0}")]
43 Simulation(String),
44}
45
46impl PoolsimError {
47 /// Creates a standardized invalid-input error.
48 pub fn invalid_input(
49 code: &'static str,
50 message: impl Into<String>,
51 details: Option<Value>,
52 ) -> Self {
53 Self::InvalidInput {
54 code,
55 message: message.into(),
56 details,
57 }
58 }
59
60 /// Returns the stable machine-readable error code.
61 pub fn code(&self) -> &'static str {
62 match self {
63 Self::InvalidInput { code, .. } => code,
64 Self::Saturated { .. } => "SATURATED",
65 Self::Distribution(_) => "DISTRIBUTION_ERROR",
66 Self::Simulation(_) => "SIMULATION_ERROR",
67 }
68 }
69
70 /// Returns optional structured details associated with this error.
71 pub fn details(&self) -> Option<&Value> {
72 match self {
73 Self::InvalidInput { details, .. } => details.as_ref(),
74 _ => None,
75 }
76 }
77}