#[derive(Debug, PartialEq, Eq)]
pub struct FilePermissions(u8);
impl FilePermissions {
pub const NONE: FilePermissions = FilePermissions(0);
pub const READ: FilePermissions = FilePermissions(1 << 0);
pub const WRITE: FilePermissions = FilePermissions(1 << 1);
pub const EXECUTE: FilePermissions = FilePermissions(1 << 2);
pub const ALL: FilePermissions =
FilePermissions(Self::READ.0 | Self::WRITE.0 | Self::EXECUTE.0);
pub const READ_WRITE: FilePermissions = FilePermissions(Self::READ.0 | Self::WRITE.0);
pub const READ_EXECUTE: FilePermissions = FilePermissions(Self::READ.0 | Self::EXECUTE.0);
pub const WRITE_EXECUTE: FilePermissions = FilePermissions(Self::WRITE.0 | Self::EXECUTE.0);
pub fn is_any(&self, file_permissions: FilePermissions) -> bool {
(self.0 & file_permissions.0) != 0
}
pub fn is_all(&self, file_permissions: FilePermissions) -> bool {
(self.0 & file_permissions.0) == file_permissions.0
}
}
impl std::ops::BitOr for FilePermissions {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
FilePermissions(self.0 | rhs.0)
}
}
impl std::ops::BitOrAssign for FilePermissions {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
impl std::ops::BitAnd for FilePermissions {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
FilePermissions(self.0 & rhs.0)
}
}
impl std::ops::BitAndAssign for FilePermissions {
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= rhs.0;
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for FilePermissions {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct FilePermissionsVisitor;
impl<'de> serde::de::Visitor<'de> for FilePermissionsVisitor {
type Value = FilePermissions;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a string that is a combination of rwx (read, write, execute)")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let file_permissions = match v {
"r" => FilePermissions::READ,
"w" => FilePermissions::WRITE,
"x" => FilePermissions::EXECUTE,
"rw" => FilePermissions::READ_WRITE,
"rx" => FilePermissions::READ_EXECUTE,
"wx" => FilePermissions::WRITE_EXECUTE,
"rwx" => FilePermissions::ALL,
_ => return Err(serde::de::Error::custom("no valid file permissions")),
};
Ok(file_permissions)
}
}
deserializer.deserialize_str(FilePermissionsVisitor)
}
}