use core::fmt;
#[derive(Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub enum PagerError {
ZeroSize,
SizeOverflow,
Map(i32),
Protect(i32),
NotWritable,
OutOfBounds {
offset: usize,
len: usize,
region_len: usize,
},
}
impl fmt::Display for PagerError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PagerError::ZeroSize => f.write_str("cannot map a region of zero bytes"),
PagerError::SizeOverflow => {
f.write_str("region size overflowed usize when rounded to whole pages")
}
PagerError::Map(code) => {
write!(
f,
"the operating system could not map the region (os error {code})"
)
}
PagerError::Protect(code) => write!(
f,
"the operating system could not change the region's protection (os error {code})"
),
PagerError::NotWritable => {
f.write_str("the region is not writable under its current protection")
}
PagerError::OutOfBounds {
offset,
len,
region_len,
} => write!(
f,
"a write of {len} byte(s) at offset {offset} exceeds the {region_len}-byte region"
),
}
}
}
impl core::error::Error for PagerError {}
#[cfg(test)]
#[allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
reason = "tests assert on specific outcomes; a wrong outcome should fail the test loudly"
)]
mod tests {
use super::PagerError;
#[test]
fn test_display_mentions_the_failure() {
assert!(PagerError::ZeroSize.to_string().contains("zero"));
assert!(PagerError::SizeOverflow.to_string().contains("overflow"));
assert!(PagerError::Map(12).to_string().contains("os error 12"));
assert!(PagerError::Protect(13).to_string().contains("os error 13"));
assert!(PagerError::NotWritable.to_string().contains("not writable"));
let oob = PagerError::OutOfBounds {
offset: 8,
len: 16,
region_len: 16,
};
let text = oob.to_string();
assert!(text.contains('8') && text.contains("16"));
}
#[test]
fn test_is_a_std_error() {
fn assert_error<E: core::error::Error>(_: &E) {}
assert_error(&PagerError::ZeroSize);
}
}