1use std::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum MlockStatus {
11 Locked {
16 bytes_locked: usize,
18 },
19
20 Failed {
25 errno: i32,
27 },
28
29 Unsupported,
33}
34
35impl MlockStatus {
36 #[must_use]
40 pub const fn is_locked(&self) -> bool {
41 matches!(self, Self::Locked { .. })
42 }
43
44 #[must_use]
48 pub const fn is_failed(&self) -> bool {
49 matches!(self, Self::Failed { .. })
50 }
51
52 #[must_use]
56 pub const fn is_unsupported(&self) -> bool {
57 matches!(self, Self::Unsupported)
58 }
59
60 #[must_use]
64 pub const fn bytes_locked(&self) -> usize {
65 match self {
66 Self::Locked { bytes_locked } => *bytes_locked,
67 Self::Failed { .. } | Self::Unsupported => 0,
68 }
69 }
70
71 #[must_use]
75 pub const fn failure_errno(&self) -> Option<i32> {
76 match self {
77 Self::Failed { errno } => Some(*errno),
78 Self::Locked { .. } | Self::Unsupported => None,
79 }
80 }
81}
82
83impl fmt::Display for MlockStatus {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 match self {
86 Self::Locked { bytes_locked } => {
87 if *bytes_locked >= 1024 * 1024 {
88 write!(f, "locked ({} MB)", bytes_locked / (1024 * 1024))
89 } else if *bytes_locked >= 1024 {
90 write!(f, "locked ({} KB)", bytes_locked / 1024)
91 } else {
92 write!(f, "locked ({bytes_locked} bytes)")
93 }
94 }
95 Self::Failed { errno } => {
96 write!(f, "failed (errno={errno})")
97 }
98 Self::Unsupported => {
99 write!(f, "unsupported platform")
100 }
101 }
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn test_locked_status() {
111 let status = MlockStatus::Locked {
112 bytes_locked: 4096,
113 };
114 assert!(status.is_locked());
115 assert!(!status.is_failed());
116 assert!(!status.is_unsupported());
117 assert_eq!(status.bytes_locked(), 4096);
118 assert_eq!(status.failure_errno(), None);
119 }
120
121 #[test]
122 fn test_failed_status() {
123 let status = MlockStatus::Failed { errno: 1 };
124 assert!(!status.is_locked());
125 assert!(status.is_failed());
126 assert!(!status.is_unsupported());
127 assert_eq!(status.bytes_locked(), 0);
128 assert_eq!(status.failure_errno(), Some(1));
129 }
130
131 #[test]
132 fn test_unsupported_status() {
133 let status = MlockStatus::Unsupported;
134 assert!(!status.is_locked());
135 assert!(!status.is_failed());
136 assert!(status.is_unsupported());
137 assert_eq!(status.bytes_locked(), 0);
138 assert_eq!(status.failure_errno(), None);
139 }
140
141 #[test]
142 fn test_display_locked_bytes() {
143 let status = MlockStatus::Locked { bytes_locked: 512 };
144 assert_eq!(format!("{status}"), "locked (512 bytes)");
145 }
146
147 #[test]
148 fn test_display_locked_kb() {
149 let status = MlockStatus::Locked {
150 bytes_locked: 4096,
151 };
152 assert_eq!(format!("{status}"), "locked (4 KB)");
153 }
154
155 #[test]
156 fn test_display_locked_mb() {
157 let status = MlockStatus::Locked {
158 bytes_locked: 10 * 1024 * 1024,
159 };
160 assert_eq!(format!("{status}"), "locked (10 MB)");
161 }
162
163 #[test]
164 fn test_display_failed() {
165 let status = MlockStatus::Failed { errno: 12 };
166 assert_eq!(format!("{status}"), "failed (errno=12)");
167 }
168
169 #[test]
170 fn test_display_unsupported() {
171 let status = MlockStatus::Unsupported;
172 assert_eq!(format!("{status}"), "unsupported platform");
173 }
174}