const HALT_PREFIX: &str = "\u{1e}tq:halt:";
pub(crate) struct Halt {
pub(crate) code: u8,
pub(crate) message: String,
}
impl Halt {
pub(super) fn raise(code: u8, message: String) -> String {
format!("{HALT_PREFIX}{code}:{message}")
}
pub(crate) fn decode(error: &str) -> Option<Self> {
let (code, message) = error.strip_prefix(HALT_PREFIX)?.split_once(':')?;
Some(Self {
code: code.parse().ok()?,
message: message.to_owned(),
})
}
}
pub(super) fn is_halt(error: &str) -> bool {
error.starts_with(HALT_PREFIX)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn only_a_well_formed_halt_decodes_as_one() {
let raised = Halt::raise(3, "stop".to_owned());
let halt = Halt::decode(&raised).expect("a raised halt decodes");
assert_eq!(halt.code, 3);
assert_eq!(halt.message, "stop");
assert!(is_halt(&raised));
assert!(Halt::decode("No more inputs").is_none());
assert!(Halt::decode(HALT_PREFIX).is_none());
assert!(Halt::decode(&format!("{HALT_PREFIX}notastatus:stop")).is_none());
}
}