How to return an &str when strings are dynamically generated?

Viewed 164

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?

1 Answers

This a know deficiency of Error::description(), which is why it is deprecated and you should not use it.

Instead, implement std::fmt::Display for your error type. Do not bother implementing description; pretend it's not there.

Related