1#![allow(clippy::missing_errors_doc)]
7
8use nabled_core::errors::{IntoNabledError, NabledError, ShapeError};
9
10pub mod context;
11pub mod control_loop;
12pub mod estimation;
13pub mod manipulation;
14pub mod pipeline;
15pub mod sim;
16
17#[derive(Debug, Clone, PartialEq)]
18pub enum SimError {
19 DimensionMismatch,
20 InvalidInput(String),
21 Model(nabled_model::ModelError),
22 Kinematics(nabled_kinematics::KinematicsError),
23 Dynamics(nabled_dynamics::DynamicsError),
24 Control(nabled_control::ControlError),
25 Sensor(nabled_sensor::SensorError),
26 Stats(nabled_ml::stats::StatsError),
27}
28
29impl std::fmt::Display for SimError {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 match self {
32 SimError::DimensionMismatch => write!(f, "input dimensions are incompatible"),
33 SimError::InvalidInput(message) => write!(f, "invalid input: {message}"),
34 SimError::Model(err) => write!(f, "{err}"),
35 SimError::Kinematics(err) => write!(f, "{err}"),
36 SimError::Dynamics(err) => write!(f, "{err}"),
37 SimError::Control(err) => write!(f, "{err}"),
38 SimError::Sensor(err) => write!(f, "{err}"),
39 SimError::Stats(err) => write!(f, "{err}"),
40 }
41 }
42}
43
44impl std::error::Error for SimError {
45 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
46 match self {
47 SimError::Model(err) => Some(err),
48 SimError::Kinematics(err) => Some(err),
49 SimError::Dynamics(err) => Some(err),
50 SimError::Control(err) => Some(err),
51 SimError::Sensor(err) => Some(err),
52 SimError::Stats(err) => Some(err),
53 SimError::DimensionMismatch | SimError::InvalidInput(_) => None,
54 }
55 }
56}
57
58impl IntoNabledError for SimError {
59 fn into_nabled_error(self) -> NabledError {
60 match self {
61 SimError::DimensionMismatch => NabledError::Shape(ShapeError::DimensionMismatch),
62 SimError::InvalidInput(message) => NabledError::InvalidInput(message),
63 SimError::Model(err) => err.into_nabled_error(),
64 SimError::Kinematics(err) => err.into_nabled_error(),
65 SimError::Dynamics(err) => err.into_nabled_error(),
66 SimError::Control(err) => err.into_nabled_error(),
67 SimError::Sensor(err) => err.into_nabled_error(),
68 SimError::Stats(err) => err.into_nabled_error(),
69 }
70 }
71}
72
73impl From<nabled_model::ModelError> for SimError {
74 fn from(value: nabled_model::ModelError) -> Self { Self::Model(value) }
75}
76
77impl From<nabled_kinematics::KinematicsError> for SimError {
78 fn from(value: nabled_kinematics::KinematicsError) -> Self { Self::Kinematics(value) }
79}
80
81impl From<nabled_dynamics::DynamicsError> for SimError {
82 fn from(value: nabled_dynamics::DynamicsError) -> Self { Self::Dynamics(value) }
83}
84
85impl From<nabled_control::ControlError> for SimError {
86 fn from(value: nabled_control::ControlError) -> Self { Self::Control(value) }
87}
88
89impl From<nabled_sensor::SensorError> for SimError {
90 fn from(value: nabled_sensor::SensorError) -> Self { Self::Sensor(value) }
91}
92
93impl From<nabled_ml::stats::StatsError> for SimError {
94 fn from(value: nabled_ml::stats::StatsError) -> Self { Self::Stats(value) }
95}
96
97#[cfg(test)]
98mod tests {
99 use std::error::Error;
100
101 use nabled_core::errors::{IntoNabledError, NabledError, ShapeError};
102
103 use super::*;
104
105 #[test]
106 fn sim_error_display_source_from_and_into_nabled() {
107 assert_eq!(SimError::DimensionMismatch.to_string(), "input dimensions are incompatible");
108 assert_eq!(
109 SimError::InvalidInput("bad grid".to_string()).to_string(),
110 "invalid input: bad grid"
111 );
112 assert!(SimError::DimensionMismatch.source().is_none());
113 assert!(SimError::InvalidInput("x".to_string()).source().is_none());
114
115 let model_err = nabled_model::ModelError::EmptyModel;
116 let sim_model: SimError = model_err.clone().into();
117 assert!(matches!(sim_model, SimError::Model(_)));
118 assert_eq!(sim_model.to_string(), model_err.to_string());
119 assert!(sim_model.source().is_some());
120
121 let kin_err = nabled_kinematics::KinematicsError::EmptyChain;
122 let sim_kin: SimError = kin_err.into();
123 assert!(matches!(sim_kin, SimError::Kinematics(_)));
124 assert_eq!(sim_kin.to_string(), "kinematic chain cannot be empty");
125
126 let dyn_err = nabled_dynamics::DynamicsError::NotImplemented;
127 let sim_dyn: SimError = dyn_err.into();
128 assert!(matches!(sim_dyn, SimError::Dynamics(_)));
129
130 let ctrl_err = nabled_control::ControlError::SingularSystem;
131 let sim_ctrl: SimError = ctrl_err.into();
132 assert!(matches!(sim_ctrl, SimError::Control(_)));
133
134 let sensor_err = nabled_sensor::SensorError::NumericalInstability;
135 let sim_sensor: SimError = sensor_err.into();
136 assert!(matches!(sim_sensor, SimError::Sensor(_)));
137
138 let stats_err = nabled_ml::stats::StatsError::InsufficientSamples;
139 let sim_stats: SimError = stats_err.into();
140 assert!(matches!(sim_stats, SimError::Stats(_)));
141
142 assert!(matches!(
143 SimError::DimensionMismatch.into_nabled_error(),
144 NabledError::Shape(ShapeError::DimensionMismatch)
145 ));
146 assert!(matches!(
147 SimError::InvalidInput("x".to_string()).into_nabled_error(),
148 NabledError::InvalidInput(_)
149 ));
150 assert!(matches!(
151 SimError::Model(nabled_model::ModelError::EmptyModel).into_nabled_error(),
152 NabledError::Shape(ShapeError::EmptyInput)
153 ));
154 assert!(matches!(
155 SimError::Kinematics(nabled_kinematics::KinematicsError::ConvergenceFailed)
156 .into_nabled_error(),
157 NabledError::ConvergenceFailed
158 ));
159 assert!(matches!(
160 SimError::Dynamics(nabled_dynamics::DynamicsError::DimensionMismatch)
161 .into_nabled_error(),
162 NabledError::Shape(ShapeError::DimensionMismatch)
163 ));
164 assert!(matches!(
165 SimError::Control(nabled_control::ControlError::SingularSystem).into_nabled_error(),
166 NabledError::SingularMatrix
167 ));
168 assert!(matches!(
169 SimError::Sensor(nabled_sensor::SensorError::EmptyInput).into_nabled_error(),
170 NabledError::Shape(ShapeError::EmptyInput)
171 ));
172 assert!(matches!(
173 SimError::Stats(nabled_ml::stats::StatsError::NumericalInstability).into_nabled_error(),
174 NabledError::NumericalInstability
175 ));
176 }
177}