pub(crate) const DROP: u64 = 0;
pub(crate) const ERROR: u64 = u64::MAX;
#[derive(Debug, PartialEq, Eq)]
pub(crate) enum RawOutcome {
Drop,
Error,
Emit { ptr: u32, len: u32 },
}
pub(crate) fn unpack(ret: u64) -> (u32, u32) {
((ret >> 32) as u32, (ret & 0xFFFF_FFFF) as u32)
}
pub(crate) fn classify(ret: u64) -> RawOutcome {
match ret {
DROP => RawOutcome::Drop,
ERROR => RawOutcome::Error,
other => {
let (ptr, len) = unpack(other);
RawOutcome::Emit { ptr, len }
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unpack_splits_hi_lo() {
assert_eq!(unpack(0), (0, 0));
assert_eq!(unpack((7u64 << 32) | 5), (7, 5));
assert_eq!(unpack(0xFFFF_FFFE_0000_0003), (0xFFFF_FFFE, 3));
}
#[test]
fn classify_zero_is_drop() {
assert_eq!(classify(DROP), RawOutcome::Drop);
}
#[test]
fn classify_max_is_error() {
assert_eq!(classify(ERROR), RawOutcome::Error);
}
#[test]
fn classify_other_is_emit() {
assert_eq!(
classify((1024u64 << 32) | 42),
RawOutcome::Emit { ptr: 1024, len: 42 }
);
}
#[test]
fn classify_zero_len_nonzero_ptr_is_emit_empty() {
assert_eq!(classify(64u64 << 32), RawOutcome::Emit { ptr: 64, len: 0 });
}
}