use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum Error {
BinaryUnavailable(String),
Handshake(String),
SessionEnded {
diagnostics: Option<Diagnostics>,
},
Protocol(String),
Refused {
code: String,
message: String,
},
TurnInProgress,
SlowConsumer,
TooLarge,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
#[non_exhaustive]
pub struct Diagnostics {
pub exit_code: Option<i32>,
pub signal: Option<i32>,
pub stderr_tail: Vec<String>,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::BinaryUnavailable(why) => write!(f, "no harness binary: {why}"),
Error::Handshake(why) => write!(f, "the session did not start: {why}"),
Error::SessionEnded { diagnostics } => {
f.write_str("the session ended unexpectedly")?;
if let Some(d) = diagnostics {
if let Some(code) = d.exit_code {
write!(f, " (exit {code})")?;
}
if let Some(signal) = d.signal {
write!(f, " (signal {signal})")?;
}
if let Some(last) = d.stderr_tail.last() {
write!(f, ": {last}")?;
}
}
Ok(())
}
Error::Protocol(why) => write!(f, "protocol error: {why}"),
Error::Refused { code, message } => write!(f, "refused ({code}): {message}"),
Error::TurnInProgress => f.write_str("a turn is still running"),
Error::SlowConsumer => f.write_str(
"the session was ended: more than 10,000 events of a turn were left unread",
),
Error::TooLarge => f.write_str("the command is over the session's 8 MiB line limit"),
}
}
}
impl std::error::Error for Error {}