mod sealed {
pub trait Sealed {}
pub struct Bit<const V: bool>;
pub trait Le {}
impl Le for (Bit<false>, Bit<false>) {}
impl Le for (Bit<false>, Bit<true>) {}
impl Le for (Bit<true>, Bit<true>) {}
}
#[derive(Debug, Clone, Copy)]
pub struct CapSet<
const SPAWN: bool,
const TIME: bool,
const RANDOM: bool,
const IO: bool,
const REMOTE: bool,
>;
impl<const SPAWN: bool, const TIME: bool, const RANDOM: bool, const IO: bool, const REMOTE: bool>
sealed::Sealed for CapSet<SPAWN, TIME, RANDOM, IO, REMOTE>
{
}
pub type All = CapSet<true, true, true, true, true>;
pub type None = CapSet<false, false, false, false, false>;
impl Default for All {
fn default() -> Self {
Self
}
}
impl Default for None {
fn default() -> Self {
Self
}
}
pub trait HasSpawn: sealed::Sealed {}
impl<const TIME: bool, const RANDOM: bool, const IO: bool, const REMOTE: bool> HasSpawn
for CapSet<true, TIME, RANDOM, IO, REMOTE>
{
}
pub trait HasTime: sealed::Sealed {}
impl<const SPAWN: bool, const RANDOM: bool, const IO: bool, const REMOTE: bool> HasTime
for CapSet<SPAWN, true, RANDOM, IO, REMOTE>
{
}
pub trait HasRandom: sealed::Sealed {}
impl<const SPAWN: bool, const TIME: bool, const IO: bool, const REMOTE: bool> HasRandom
for CapSet<SPAWN, TIME, true, IO, REMOTE>
{
}
pub trait HasIo: sealed::Sealed {}
impl<const SPAWN: bool, const TIME: bool, const RANDOM: bool, const REMOTE: bool> HasIo
for CapSet<SPAWN, TIME, RANDOM, true, REMOTE>
{
}
pub trait HasRemote: sealed::Sealed {}
impl<const SPAWN: bool, const TIME: bool, const RANDOM: bool, const IO: bool> HasRemote
for CapSet<SPAWN, TIME, RANDOM, IO, true>
{
}
pub trait SubsetOf<Super>: sealed::Sealed {}
impl<
const S1: bool,
const T1: bool,
const R1: bool,
const I1: bool,
const RE1: bool,
const S2: bool,
const T2: bool,
const R2: bool,
const I2: bool,
const RE2: bool,
> SubsetOf<CapSet<S2, T2, R2, I2, RE2>> for CapSet<S1, T1, R1, I1, RE1>
where
(sealed::Bit<S1>, sealed::Bit<S2>): sealed::Le,
(sealed::Bit<T1>, sealed::Bit<T2>): sealed::Le,
(sealed::Bit<R1>, sealed::Bit<R2>): sealed::Le,
(sealed::Bit<I1>, sealed::Bit<I2>): sealed::Le,
(sealed::Bit<RE1>, sealed::Bit<RE2>): sealed::Le,
{
}
#[cfg(test)]
mod tests {
use super::*;
fn assert_subset<Sub: SubsetOf<Super>, Super>() {}
fn assert_has_spawn<C: HasSpawn>() {}
fn assert_has_time<C: HasTime>() {}
fn assert_has_random<C: HasRandom>() {}
fn assert_has_io<C: HasIo>() {}
fn assert_has_remote<C: HasRemote>() {}
#[test]
fn subset_reflexive_all() {
assert_subset::<All, All>();
}
#[test]
fn subset_reflexive_none() {
assert_subset::<None, None>();
}
#[test]
fn subset_reflexive_mixed() {
assert_subset::<
CapSet<true, false, true, false, true>,
CapSet<true, false, true, false, true>,
>();
}
#[test]
fn none_subset_of_all() {
assert_subset::<None, All>();
}
#[test]
fn none_subset_of_any() {
assert_subset::<None, CapSet<false, true, false, false, true>>();
assert_subset::<None, CapSet<true, false, false, false, false>>();
}
#[test]
fn any_subset_of_all() {
assert_subset::<CapSet<true, false, true, false, true>, All>();
assert_subset::<CapSet<false, false, false, true, false>, All>();
}
#[test]
fn background_subset_of_grpc() {
type BackgroundCaps = CapSet<true, true, false, false, false>;
type GrpcCaps = CapSet<true, true, false, true, false>;
assert_subset::<BackgroundCaps, GrpcCaps>();
}
#[test]
fn web_subset_of_all() {
type WebCaps = CapSet<false, true, false, true, false>;
assert_subset::<WebCaps, All>();
}
#[test]
fn pure_subset_of_web() {
type WebCaps = CapSet<false, true, false, true, false>;
assert_subset::<None, WebCaps>();
}
#[test]
fn single_cap_subset_of_multi() {
assert_subset::<
CapSet<false, true, false, false, false>,
CapSet<true, true, false, true, false>,
>();
}
#[test]
fn transitive_none_background_grpc() {
type BackgroundCaps = CapSet<true, true, false, false, false>;
type GrpcCaps = CapSet<true, true, false, true, false>;
assert_subset::<None, BackgroundCaps>();
assert_subset::<BackgroundCaps, GrpcCaps>();
assert_subset::<None, GrpcCaps>();
}
#[test]
fn all_has_every_capability() {
assert_has_spawn::<All>();
assert_has_time::<All>();
assert_has_random::<All>();
assert_has_io::<All>();
assert_has_remote::<All>();
}
#[test]
fn partial_caps_have_correct_markers() {
assert_has_spawn::<CapSet<true, true, false, true, false>>();
assert_has_time::<CapSet<true, true, false, true, false>>();
assert_has_io::<CapSet<true, true, false, true, false>>();
}
#[test]
fn capset_is_zero_sized() {
assert_eq!(std::mem::size_of::<All>(), 0);
assert_eq!(std::mem::size_of::<None>(), 0);
assert_eq!(
std::mem::size_of::<CapSet<true, false, true, false, true>>(),
0
);
}
#[test]
fn capset_debug_clone_copy_default() {
let all = All::default();
let dbg = format!("{all:?}");
assert!(dbg.contains("CapSet"), "{dbg}");
let copied = all;
let cloned = all;
let _ = (copied, cloned);
let none = None::default();
let dbg_none = format!("{none:?}");
assert!(dbg_none.contains("CapSet"), "{dbg_none}");
}
#[test]
fn default_implementations_correct() {
let all = All::default();
assert_has_spawn::<All>();
assert_has_time::<All>();
assert_has_random::<All>();
assert_has_io::<All>();
assert_has_remote::<All>();
let _: All = all;
let none = None::default();
let _: None = none;
fn verify_all_has_spawn(_: impl HasSpawn) {}
verify_all_has_spawn(all); }
}