use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
#[non_exhaustive]
pub enum SandboxTier {
#[default]
None,
Hardened,
Lockdown,
}
impl SandboxTier {
#[must_use]
pub fn any_isolation(self) -> bool {
!matches!(self, SandboxTier::None)
}
#[must_use]
pub fn as_str(self) -> &'static str {
match self {
SandboxTier::None => "none",
SandboxTier::Hardened => "hardened",
SandboxTier::Lockdown => "lockdown",
}
}
pub fn parse(name: &str) -> Result<Self, String> {
match name {
"none" | "standard" => Ok(SandboxTier::None),
"hardened" => Ok(SandboxTier::Hardened),
"lockdown" => Ok(SandboxTier::Lockdown),
other => Err(other.to_string()),
}
}
}
pub mod capabilities;
pub use capabilities::OsCapabilities;
#[cfg(target_os = "linux")]
pub mod linux;
#[cfg(target_os = "macos")]
pub mod macos;
#[cfg(target_os = "windows")]
pub mod windows;
#[cfg(target_os = "linux")]
pub use linux::{apply_sandbox, user_namespaces_available};
#[cfg(target_os = "macos")]
pub use macos::apply_sandbox;
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
pub fn apply_sandbox(tier: SandboxTier) -> std::io::Result<()> {
let _ = tier;
Ok(())
}
#[cfg(not(target_os = "linux"))]
#[must_use]
pub fn user_namespaces_available() -> bool {
false
}
#[cfg(test)]
mod tests {
use super::SandboxTier;
#[test]
fn apply_sandbox_none_never_panics() {
assert!(super::apply_sandbox(SandboxTier::None).is_ok());
}
#[test]
fn sandbox_tier_parse_roundtrip() {
for tier in [
SandboxTier::None,
SandboxTier::Hardened,
SandboxTier::Lockdown,
] {
let parsed = SandboxTier::parse(tier.as_str()).unwrap();
assert_eq!(parsed, tier);
}
}
#[test]
fn sandbox_tier_standard_alias_is_none() {
assert_eq!(SandboxTier::parse("standard").unwrap(), SandboxTier::None);
}
#[test]
fn sandbox_tier_any_isolation() {
assert!(!SandboxTier::None.any_isolation());
assert!(SandboxTier::Hardened.any_isolation());
assert!(SandboxTier::Lockdown.any_isolation());
}
}