use bitflags::BitFlags; use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign}; /// Unix permission bit flags #[derive(Clone, Copy, PartialEq)] pub enum Bit { Suid = 0o4000, Sgid = 0o2000, Sticky = 0o1000, URead = 0o400, UWrite = 0o200, UExec = 0o100, GRead = 0o40, GWrite = 0o20, GExec = 0o10, ORead = 0o4, OWrite = 0o2, OExec = 0o1, } impl BitAnd for Bit { type Output = u32; fn bitand(self, rhs: u32) -> Self::Output { self as u32 & rhs } } impl BitAnd for u32 { type Output = u32; fn bitand(self, rhs: Bit) -> Self::Output { self & rhs as u32 } } impl BitAnd for Bit { type Output = u32; fn bitand(self, rhs: Self) -> Self::Output { self as u32 & rhs as u32 } } impl BitAndAssign for u32 { fn bitand_assign(&mut self, rhs: Bit) { *self = *self & rhs; } } impl BitOr for Bit { type Output = u32; fn bitor(self, rhs: u32) -> Self::Output { self as u32 | rhs } } impl BitOr for u32 { type Output = u32; fn bitor(self, rhs: Bit) -> Self::Output { self | rhs as u32 } } impl BitOr for Bit { type Output = u32; fn bitor(self, rhs: Self) -> Self::Output { self as u32 | rhs as u32 } } impl BitOrAssign for u32 { fn bitor_assign(&mut self, rhs: Bit) { *self = *self | rhs; } } impl Bit { pub fn as_char(&self, mode: u32) -> char { if mode & *self != 0 { match self { Self::Suid | Self::Sgid => 's', Self::Sticky => 't', Self::URead | Self::GRead | Self::ORead => 'r', Self::UWrite | Self::GWrite | Self::OWrite => 'w', Self::UExec if mode.contains(Self::Suid) => 's', Self::GExec if mode.contains(Self::Sgid) => 's', Self::OExec if mode.contains(Self::Sticky) => 't', Self::UExec | Self::GExec | Self::OExec => 'x', } } else { '-' } } }