#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Protection {
None,
Read,
ReadWrite,
ReadExecute,
ReadWriteExecute,
}
impl Protection {
#[must_use]
pub const fn is_readable(self) -> bool {
!matches!(self, Protection::None)
}
#[must_use]
pub const fn is_writable(self) -> bool {
matches!(self, Protection::ReadWrite | Protection::ReadWriteExecute)
}
#[must_use]
pub const fn is_executable(self) -> bool {
matches!(self, Protection::ReadExecute | Protection::ReadWriteExecute)
}
}
#[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::Protection;
#[test]
fn test_is_readable_true_for_all_but_none() {
assert!(!Protection::None.is_readable());
for prot in [
Protection::Read,
Protection::ReadWrite,
Protection::ReadExecute,
Protection::ReadWriteExecute,
] {
assert!(prot.is_readable(), "{prot:?} should be readable");
}
}
#[test]
fn test_is_writable_only_for_write_protections() {
assert!(Protection::ReadWrite.is_writable());
assert!(Protection::ReadWriteExecute.is_writable());
assert!(!Protection::None.is_writable());
assert!(!Protection::Read.is_writable());
assert!(!Protection::ReadExecute.is_writable());
}
#[test]
fn test_is_executable_only_for_execute_protections() {
assert!(Protection::ReadExecute.is_executable());
assert!(Protection::ReadWriteExecute.is_executable());
assert!(!Protection::None.is_executable());
assert!(!Protection::Read.is_executable());
assert!(!Protection::ReadWrite.is_executable());
}
}