use crate::{EnvAccess, FsAccess, Manifold, NetAccess};
use std::path::PathBuf;
use super::args::Cli;
pub fn build_manifold(cli: &Cli) -> Manifold {
if cli.allow_all {
return Manifold::open();
}
let any_allow = cli.allow_net.is_some() || cli.allow_fs.is_some() || cli.allow_env.is_some();
let explicit_sandbox = cli.sandbox || any_allow;
if !explicit_sandbox {
return Manifold::open();
}
let mut m = Manifold::sealed();
if let Some(s) = cli.allow_net.as_deref() {
let hosts = parse_allow_list(s);
m.net = if hosts.is_empty() || has_wildcard(&hosts) {
NetAccess::OutboundFull(None)
} else {
NetAccess::OutboundFull(Some(hosts))
};
}
if let Some(s) = cli.allow_fs.as_deref() {
let paths = parse_allow_list(s);
let roots: Vec<PathBuf> = if paths.is_empty() || has_wildcard(&paths) {
vec![PathBuf::from("/")]
} else {
paths.into_iter().map(PathBuf::from).collect()
};
m.fs = FsAccess::ReadWrite(roots);
}
if let Some(s) = cli.allow_env.as_deref() {
let vars = parse_allow_list(s);
m.env = if vars.is_empty() || has_wildcard(&vars) {
EnvAccess::Full
} else {
EnvAccess::AllowList(vars)
};
}
m
}
pub fn parse_allow_list(s: &str) -> Vec<String> {
s.split(',')
.map(str::trim)
.filter(|p| !p.is_empty())
.map(String::from)
.collect()
}
pub fn has_wildcard(list: &[String]) -> bool {
list.iter().any(|s| s == "*")
}
pub fn is_implicit_open(cli: &Cli) -> bool {
if cli.allow_all {
return false;
}
let any_allow = cli.allow_net.is_some() || cli.allow_fs.is_some() || cli.allow_env.is_some();
!(cli.sandbox || any_allow)
}