150 lines
3.2 KiB
Rust
150 lines
3.2 KiB
Rust
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<Self, Self::Err> {
|
|
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<u32> for Flags {
|
|
type Output = u32;
|
|
|
|
fn bitand(self, rhs: u32) -> Self::Output {
|
|
self as u32 & rhs
|
|
}
|
|
}
|
|
|
|
impl BitAnd<Flags> 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<Flags> for u32 {
|
|
fn bitand_assign(&mut self, rhs: Flags) {
|
|
*self = *self & rhs;
|
|
}
|
|
}
|
|
|
|
impl BitOr<u32> for Flags {
|
|
type Output = u32;
|
|
|
|
fn bitor(self, rhs: u32) -> Self::Output {
|
|
self as u32 | rhs
|
|
}
|
|
}
|
|
|
|
impl BitOr<Flags> 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<Flags> 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)
|
|
}
|
|
}
|