1use crate::sim::types::{SignalType, SimStatusRaw};
2use thiserror::Error;
3
4#[derive(Debug, Error)]
5pub enum ProjectError {
6 #[error("library load failed: {0}")]
7 LibraryLoad(String),
8 #[error("FFI contract violation: {0}")]
9 FfiContract(String),
10 #[error("missing symbol: {0}")]
11 MissingSymbol(&'static str),
12 #[error("invalid signal metadata from project: {0}")]
13 InvalidSignalMetadata(String),
14 #[error("invalid CAN exports: {0}")]
15 InvalidCanExports(String),
16 #[error("invalid shared-state exports: {0}")]
17 InvalidSharedExports(String),
18 #[error("invalid CAN metadata from project: {0}")]
19 InvalidCanMetadata(String),
20 #[error("invalid shared-state metadata from project: {0}")]
21 InvalidSharedMetadata(String),
22 #[error("flash support error: {0}")]
23 Flash(String),
24}
25
26#[derive(Debug, Error)]
27pub enum SimError {
28 #[error("simulation state not initialized")]
29 NotInitialized,
30 #[error("invalid argument: {0}")]
31 InvalidArg(String),
32 #[error("FFI contract violation: {0}")]
33 FfiContract(String),
34 #[error("signal not found: '{0}'")]
35 InvalidSignal(String),
36 #[error("type mismatch: signal '{name}' expects {expected}, got {actual}")]
37 TypeMismatch {
38 name: String,
39 expected: SignalType,
40 actual: SignalType,
41 },
42 #[error("buffer too small")]
43 BufferTooSmall,
44 #[error("internal simulation error")]
45 Internal,
46 #[error("unknown simulation error status code: {0}")]
47 UnknownStatus(u32),
48}
49
50#[derive(Debug, Error)]
51pub enum TimeError {
52 #[error(transparent)]
53 Sim(#[from] SimError),
54 #[error("step while running is not allowed; pause first")]
55 StepWhileRunning,
56 #[error("time engine is already running")]
57 AlreadyRunning,
58 #[error("time engine is already paused")]
59 AlreadyPaused,
60 #[error("invalid speed multiplier: {0}")]
61 InvalidSpeed(f64),
62}
63
64impl TryFrom<u32> for SimError {
65 type Error = SimError;
66
67 fn try_from(value: u32) -> Result<Self, Self::Error> {
68 let status = SimStatusRaw::try_from(value).map_err(|_| SimError::UnknownStatus(value))?;
69 Ok(match status {
70 SimStatusRaw::Ok => return Err(SimError::UnknownStatus(0)),
71 SimStatusRaw::NotInitialized => SimError::NotInitialized,
72 SimStatusRaw::InvalidArg => SimError::InvalidArg("invalid ffi argument".to_string()),
73 SimStatusRaw::InvalidSignal => SimError::InvalidSignal("<unknown>".to_string()),
74 SimStatusRaw::TypeMismatch => SimError::Internal,
75 SimStatusRaw::BufferTooSmall => SimError::BufferTooSmall,
76 SimStatusRaw::Internal => SimError::Internal,
77 })
78 }
79}