use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Strategy {
Unshare,
Bubblewrap,
Firejail,
RlimitsOnly,
None,
}
impl Strategy {
pub fn name(self) -> &'static str {
match self {
Self::Unshare => "unshare",
Self::Bubblewrap => "bubblewrap",
Self::Firejail => "firejail",
Self::RlimitsOnly => "rlimits-only",
Self::None => "none",
}
}
pub fn has_pid_isolation(self) -> bool {
matches!(self, Self::Unshare | Self::Bubblewrap | Self::Firejail)
}
pub fn has_network_isolation(self) -> bool {
matches!(self, Self::Unshare | Self::Bubblewrap | Self::Firejail)
}
pub fn has_fs_isolation(self) -> bool {
matches!(self, Self::Bubblewrap | Self::Firejail)
}
pub fn has_mount_namespace(self) -> bool {
matches!(self, Self::Unshare | Self::Bubblewrap | Self::Firejail)
}
}
impl std::fmt::Display for Strategy {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.name())
}
}
impl TryFrom<&str> for Strategy {
type Error = &'static str;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value.trim().to_ascii_lowercase().as_str() {
"unshare" => Ok(Self::Unshare),
"bubblewrap" | "bwrap" => Ok(Self::Bubblewrap),
"firejail" => Ok(Self::Firejail),
"rlimits-only" | "rlimits_only" | "rlimits" => Ok(Self::RlimitsOnly),
"none" => Ok(Self::None),
_ => Err(
"unknown strategy. Fix: use one of `unshare`, `bubblewrap`, `firejail`, `rlimits-only`, or `none`.",
),
}
}
}
impl TryFrom<String> for Strategy {
type Error = &'static str;
fn try_from(value: String) -> Result<Self, Self::Error> {
Self::try_from(value.as_str())
}
}