#[derive(Debug, PartialEq, Eq)]
pub struct NetworkPermissions(u8);
impl NetworkPermissions {
pub const NONE: NetworkPermissions = NetworkPermissions(0);
pub const CONNECT_TCP: NetworkPermissions = NetworkPermissions(1 << 0);
pub const BIND_TCP: NetworkPermissions = NetworkPermissions(1 << 1);
pub const ALL: NetworkPermissions = NetworkPermissions(Self::CONNECT_TCP.0 | Self::BIND_TCP.0);
pub fn is_any(&self, file_permissions: NetworkPermissions) -> bool {
(self.0 & file_permissions.0) != 0
}
pub fn is_all(&self, file_permissions: NetworkPermissions) -> bool {
(self.0 & file_permissions.0) == file_permissions.0
}
}
impl std::ops::BitOr for NetworkPermissions {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
NetworkPermissions(self.0 | rhs.0)
}
}
impl std::ops::BitOrAssign for NetworkPermissions {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
impl std::ops::BitAnd for NetworkPermissions {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
NetworkPermissions(self.0 & rhs.0)
}
}
impl std::ops::BitAndAssign for NetworkPermissions {
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= rhs.0;
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for NetworkPermissions {
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 = NetworkPermissions;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a string that is a combination of cb (connect, bind)")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
let file_permissions = match v {
"c" => NetworkPermissions::CONNECT_TCP,
"b" => NetworkPermissions::BIND_TCP,
"cb" => NetworkPermissions::ALL,
_ => return Err(serde::de::Error::custom("no valid network permissions")),
};
Ok(file_permissions)
}
}
deserializer.deserialize_str(FilePermissionsVisitor)
}
}