I have the following error code for VM:
/// These are the different types of errors which stepping through a VM can produce.
#[derive(Debug, PartialEq)]
enum VmErrorType {
UnknownOpCode(i8),
UnknownVariable(char),
IllegalVariableName(i8),
IllegalJump(i8, usize, usize),
StackEmpty,
UnexpectedEndOfBytecode,
}
/// VmError encapsulates the VmErrorType and adds the common offset of where the error was found.
#[derive(Debug, PartialEq)]
pub struct VmError { // public so that errors can be interrogated
subtype: VmErrorType, // "type" is a reserved keyword
offset: usize,
}
impl fmt::Display for VmError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let message = match self.subtype {
VmErrorType::UnknownOpCode(opcode) => format!("unknown opcode ({opcode})"),
VmErrorType::UnknownVariable(varname) => format!("unknown variable ({varname})"),
VmErrorType::IllegalVariableName(varname) => format!("illegal variable name ({varname})"),
VmErrorType::IllegalJump(delta, src, dst) => format!("illegal jump of {delta} from {src} to {dst}"),
VmErrorType::StackEmpty => "empty stack".to_string(),
VmErrorType::UnexpectedEndOfBytecode => "unexpected end of bytecode".to_string(),
};
write!(f, "{} at offset {}", message, self.offset)
}
}
impl error::Error for VmError {
fn description(&self) -> &str {
"VmError" // FIXME: this could do with being more specific, but we have lifetime issues here
}
}
How can I return a description() as an &str when they are dynamically generated?
Is there a better way of structuring multiple error cases where some properties are error-specific while others (offset) apply to all?