use std::str::FromStr;
use serde::Deserialize;
use serde::Serialize;
bitflags::bitflags! {
#[derive(Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
pub struct Namespace: i32 {
const CGROUP = libc::CLONE_NEWCGROUP;
const IPC = libc::CLONE_NEWIPC;
const NETWORK = libc::CLONE_NEWNET;
const MOUNT = libc::CLONE_NEWNS;
const PID = libc::CLONE_NEWPID;
const USER = libc::CLONE_NEWUSER;
const UTS = libc::CLONE_NEWUTS;
}
}
impl Default for Namespace {
fn default() -> Self {
Self::empty()
}
}
#[derive(Debug, Clone)]
pub enum ParseNamespaceError {
InvalidNamespace(String),
}
impl std::error::Error for ParseNamespaceError {}
impl core::fmt::Display for ParseNamespaceError {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
match self {
ParseNamespaceError::InvalidNamespace(ns) => {
write!(f, "Invalid namespace: {}", ns)
}
}
}
}
impl FromStr for Namespace {
type Err = ParseNamespaceError;
fn from_str(s: &str) -> Result<Self, ParseNamespaceError> {
s.split(',').try_fold(Namespace::empty(), |ns, s| match s {
"cgroup" => Ok(ns | Namespace::CGROUP),
"ipc" => Ok(ns | Namespace::IPC),
"network" => Ok(ns | Namespace::NETWORK),
"pid" => Ok(ns | Namespace::PID),
"mount" => Ok(ns | Namespace::MOUNT),
"user" => Ok(ns | Namespace::USER),
"uts" => Ok(ns | Namespace::UTS),
"" | "none" => Ok(ns),
invalid_ns => Err(ParseNamespaceError::InvalidNamespace(invalid_ns.to_owned())),
})
}
}