use std::{ error::Error, fmt::Display, ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not}, str::FromStr, }; #[repr(u32)] pub enum Flags { ReadOnly = 1, NoSuid = 2, NoDev = 4, NoExec = 8, Synchronous = 16, Remount = 32, MandLock = 64, DirSync = 128, NoSymFollow = 256, NoAtime = 1024, NoDirAtime = 2048, Bind = 4096, Move = 8192, Rec = 16384, Silent = 32768, PosixAcl = (1 << 16), UnBindable = (1 << 17), Private = (1 << 18), Slave = (1 << 19), Shared = (1 << 20), RelAtime = (1 << 21), KerrnMount = (1 << 22), IVersion = (1 << 23), StrictAtime = (1 << 24), LazyTime = (1 << 25), NoRemoteLock = (1 << 27), NoSec = (1 << 28), Born = (1 << 29), Active = (1 << 30), NoUser = (1 << 31), } impl FromStr for Flags { type Err = ParseFlagsError; fn from_str(s: &str) -> Result { match s { "ro" => Ok(Self::ReadOnly), "nosuid" => Ok(Self::NoSuid), "nodev" => Ok(Self::NoDev), "noexec" => Ok(Self::NoExec), "sync" => Ok(Self::Synchronous), "remount" => Ok(Self::Remount), "mand" => Ok(Self::MandLock), "dirsync" => Ok(Self::DirSync), "nosymfollow" => Ok(Self::NoSymFollow), "noatime" => Ok(Self::NoAtime), "nodiratime" => Ok(Self::NoDirAtime), "bind" => Ok(Self::Bind), "silent" => Ok(Self::Silent), "acl" => Ok(Self::PosixAcl), "relatime" => Ok(Self::RelAtime), "iversion" => Ok(Self::IVersion), "strictatime" => Ok(Self::StrictAtime), "lazytime" => Ok(Self::LazyTime), "nomand" => Ok(Self::NoRemoteLock), "nouser" => Ok(Self::NoUser), _ => Err(ParseFlagsError), } } } #[derive(Debug)] pub struct ParseFlagsError; impl Display for ParseFlagsError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{self:?}") } } impl Error for ParseFlagsError {} impl BitAnd for Flags { 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: Flags) -> Self::Output { self & rhs as u32 } } impl BitAnd for Flags { 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: Flags) { *self = *self & rhs; } } impl BitOr for Flags { 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: Flags) -> Self::Output { self | rhs as u32 } } impl BitOr for Flags { 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: Flags) { *self = *self | rhs; } } impl Not for Flags { type Output = u32; fn not(self) -> Self::Output { !(self as u32) } }