#[derive(Debug)]
pub struct RootCapability {
_private: (),
}
impl RootCapability {
#[doc(hidden)]
#[must_use]
pub const fn __acquire_for_main() -> Self {
Self { _private: () }
}
#[must_use]
pub fn fs_scope(&self, root: &'static str, mode: FsMode) -> FsCap {
FsCap { root, mode }
}
#[must_use]
pub fn net_scope(&self, host: &'static str) -> NetCap {
NetCap { host }
}
#[must_use]
pub fn env_scope(&self, vars: &'static [&'static str]) -> EnvCap {
EnvCap { vars }
}
#[must_use]
pub fn clock(&self) -> ClockCap {
ClockCap { _private: () }
}
#[must_use]
pub fn random(&self) -> RandomCap {
RandomCap { _private: () }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FsMode {
Read,
Write,
ReadWrite,
}
#[derive(Debug)]
pub struct FsCap {
root: &'static str,
mode: FsMode,
}
impl FsCap {
#[must_use]
pub const fn root(&self) -> &'static str {
self.root
}
#[must_use]
pub const fn mode(&self) -> FsMode {
self.mode
}
}
#[derive(Debug)]
pub struct NetCap {
host: &'static str,
}
impl NetCap {
#[must_use]
pub const fn host(&self) -> &'static str {
self.host
}
}
#[derive(Debug)]
pub struct EnvCap {
vars: &'static [&'static str],
}
impl EnvCap {
#[must_use]
pub const fn vars(&self) -> &'static [&'static str] {
self.vars
}
}
#[derive(Debug)]
pub struct ClockCap {
_private: (),
}
#[derive(Debug)]
pub struct RandomCap {
_private: (),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_root_derives_fs_capability() {
let root = RootCapability::__acquire_for_main();
let fs = root.fs_scope("/tmp", FsMode::Read);
assert_eq!(fs.root(), "/tmp");
assert_eq!(fs.mode(), FsMode::Read);
}
#[test]
fn test_root_derives_net_capability() {
let root = RootCapability::__acquire_for_main();
let net = root.net_scope("api.example.com");
assert_eq!(net.host(), "api.example.com");
}
#[test]
fn test_root_derives_env_capability() {
let root = RootCapability::__acquire_for_main();
let env = root.env_scope(&["PATH", "HOME"]);
assert_eq!(env.vars(), &["PATH", "HOME"]);
}
#[test]
fn test_capabilities_are_distinct_types() {
let root = RootCapability::__acquire_for_main();
let _fs: FsCap = root.fs_scope("/", FsMode::ReadWrite);
let _net: NetCap = root.net_scope("localhost");
let _env: EnvCap = root.env_scope(&[]);
let _clock: ClockCap = root.clock();
let _rand: RandomCap = root.random();
}
#[test]
fn test_fs_mode_equality() {
assert_eq!(FsMode::Read, FsMode::Read);
assert_ne!(FsMode::Read, FsMode::Write);
assert_ne!(FsMode::Read, FsMode::ReadWrite);
}
}