use vyre_foundation::ir::Program;
pub(crate) mod private {
pub trait Sealed {}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum EnforceVerdict {
Allow,
Deny {
policy: &'static str,
detail: String,
},
}
pub trait EnforceGate: private::Sealed + Send + Sync {
fn name(&self) -> &'static str;
fn evaluate(&self, program: &Program) -> EnforceVerdict;
}
pub struct Chain<A, B> {
first: A,
second: B,
}
impl<A: EnforceGate, B: EnforceGate> private::Sealed for Chain<A, B> {}
impl<A: EnforceGate, B: EnforceGate> Chain<A, B> {
pub fn new(first: A, second: B) -> Self {
Self { first, second }
}
}
impl<A: EnforceGate, B: EnforceGate> EnforceGate for Chain<A, B> {
fn name(&self) -> &'static str {
"chain"
}
fn evaluate(&self, program: &Program) -> EnforceVerdict {
match self.first.evaluate(program) {
EnforceVerdict::Allow => self.second.evaluate(program),
deny => deny,
}
}
}