#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error(transparent)]
Engine(#[from] rs_teststand::Error),
#[error("the engine thread could not be started: {reason}")]
ThreadNotStarted {
reason: String,
},
#[error("the engine thread has stopped")]
HostStopped,
#[error("the engine thread ended before returning a result")]
ResultLost,
#[error("a message payload could not be serialized: {0}")]
Payload(#[from] serde_json::Error),
}
#[cfg(test)]
mod tests {
use super::Error;
#[test]
fn an_engine_failure_keeps_its_own_message() {
let engine = rs_teststand::Error::UnexpectedType {
expected: "a number",
actual: "a string",
};
let expected = engine.to_string();
let wrapped = Error::from(engine);
assert_eq!(wrapped.to_string(), expected);
}
#[test]
fn a_payload_failure_is_not_reported_as_an_engine_failure() {
let parsed = serde_json::from_str::<serde_json::Value>("{");
assert!(parsed.is_err(), "an unterminated object is not valid JSON");
if let Err(broken) = parsed {
let wrapped = Error::from(broken);
assert!(matches!(wrapped, Error::Payload(_)), "got {wrapped:?}");
assert!(wrapped.to_string().starts_with("a message payload"));
}
}
#[test]
fn a_stopped_host_says_so_without_blaming_the_engine() {
assert_eq!(
Error::HostStopped.to_string(),
"the engine thread has stopped"
);
}
}