use bitflags::bitflags;
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct CapRights: u8 {
const READ = 0x01;
const WRITE = 0x02;
const GRANT = 0x04;
const REVOKE = 0x08;
const EXECUTE = 0x10;
const PROVE = 0x20;
const GRANT_ONCE = 0x40;
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum CapType {
Partition = 0,
Region = 1,
CommEdge = 2,
Device = 3,
Scheduler = 4,
WitnessLog = 5,
Proof = 6,
Vcpu = 7,
Coherence = 8,
Context = 9,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct CapabilityId(u64);
impl CapabilityId {
pub const ROOT: Self = Self(0);
#[must_use]
pub const fn new(id: u64) -> Self {
Self(id)
}
#[must_use]
pub const fn as_u64(self) -> u64 {
self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct CapToken {
id: u64,
cap_type: CapType,
rights: CapRights,
epoch: u32,
}
impl CapToken {
#[must_use]
pub const fn new(id: u64, cap_type: CapType, rights: CapRights, epoch: u32) -> Self {
Self {
id,
cap_type,
rights,
epoch,
}
}
#[must_use]
pub const fn id(self) -> u64 {
self.id
}
#[must_use]
pub const fn cap_type(self) -> CapType {
self.cap_type
}
#[must_use]
pub const fn rights(self) -> CapRights {
self.rights
}
#[must_use]
pub const fn epoch(self) -> u32 {
self.epoch
}
#[must_use]
pub const fn has_rights(self, required: CapRights) -> bool {
self.rights.contains(required)
}
#[must_use]
#[allow(clippy::cast_possible_truncation)]
pub const fn truncated_hash(self) -> u32 {
let mut h = self.id as u32;
h ^= (self.id >> 32) as u32;
h ^= self.epoch;
h ^= (self.rights.bits() as u32) << 24;
h
}
}
#[derive(Debug, Clone, Copy)]
pub struct Capability {
pub id: CapabilityId,
pub object_id: u64,
pub object_type: CapType,
pub rights: CapRights,
pub badge: u32,
pub epoch: u32,
pub parent: CapabilityId,
pub delegation_depth: u8,
}
pub const MAX_DELEGATION_DEPTH: u8 = 8;