use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MlockStatus {
Locked {
bytes_locked: usize,
},
Failed {
errno: i32,
},
Unsupported,
}
impl MlockStatus {
#[must_use]
pub const fn is_locked(&self) -> bool {
matches!(self, Self::Locked { .. })
}
#[must_use]
pub const fn is_failed(&self) -> bool {
matches!(self, Self::Failed { .. })
}
#[must_use]
pub const fn is_unsupported(&self) -> bool {
matches!(self, Self::Unsupported)
}
#[must_use]
pub const fn bytes_locked(&self) -> usize {
match self {
Self::Locked { bytes_locked } => *bytes_locked,
Self::Failed { .. } | Self::Unsupported => 0,
}
}
#[must_use]
pub const fn failure_errno(&self) -> Option<i32> {
match self {
Self::Failed { errno } => Some(*errno),
Self::Locked { .. } | Self::Unsupported => None,
}
}
}
impl fmt::Display for MlockStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Locked { bytes_locked } => {
if *bytes_locked >= 1024 * 1024 {
write!(f, "locked ({} MB)", bytes_locked / (1024 * 1024))
} else if *bytes_locked >= 1024 {
write!(f, "locked ({} KB)", bytes_locked / 1024)
} else {
write!(f, "locked ({bytes_locked} bytes)")
}
}
Self::Failed { errno } => {
write!(f, "failed (errno={errno})")
}
Self::Unsupported => {
write!(f, "unsupported platform")
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_locked_status() {
let status = MlockStatus::Locked {
bytes_locked: 4096,
};
assert!(status.is_locked());
assert!(!status.is_failed());
assert!(!status.is_unsupported());
assert_eq!(status.bytes_locked(), 4096);
assert_eq!(status.failure_errno(), None);
}
#[test]
fn test_failed_status() {
let status = MlockStatus::Failed { errno: 1 };
assert!(!status.is_locked());
assert!(status.is_failed());
assert!(!status.is_unsupported());
assert_eq!(status.bytes_locked(), 0);
assert_eq!(status.failure_errno(), Some(1));
}
#[test]
fn test_unsupported_status() {
let status = MlockStatus::Unsupported;
assert!(!status.is_locked());
assert!(!status.is_failed());
assert!(status.is_unsupported());
assert_eq!(status.bytes_locked(), 0);
assert_eq!(status.failure_errno(), None);
}
#[test]
fn test_display_locked_bytes() {
let status = MlockStatus::Locked { bytes_locked: 512 };
assert_eq!(format!("{status}"), "locked (512 bytes)");
}
#[test]
fn test_display_locked_kb() {
let status = MlockStatus::Locked {
bytes_locked: 4096,
};
assert_eq!(format!("{status}"), "locked (4 KB)");
}
#[test]
fn test_display_locked_mb() {
let status = MlockStatus::Locked {
bytes_locked: 10 * 1024 * 1024,
};
assert_eq!(format!("{status}"), "locked (10 MB)");
}
#[test]
fn test_display_failed() {
let status = MlockStatus::Failed { errno: 12 };
assert_eq!(format!("{status}"), "failed (errno=12)");
}
#[test]
fn test_display_unsupported() {
let status = MlockStatus::Unsupported;
assert_eq!(format!("{status}"), "unsupported platform");
}
}