#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::sync::Arc;
use crate::der::Enumerated;
use crate::{Frame, Message};
#[derive(Enumerated, Default, Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum TransitStatus {
#[default]
Request = 0,
Accepted = 1,
Busy = 2,
Unauthorized = 3,
Forbidden = 4,
Timeout = 5,
}
pub trait GatePolicy: Send + Sync {
fn evaluate(&self, message: &Frame) -> TransitStatus;
}
pub trait ReceptorPolicy<T: Message>: Send + Sync {
fn evaluate(&self, message: &T) -> TransitStatus;
}
pub struct ReceptorMiddleware<T: Message, R: ReceptorPolicy<T>, F>
where
F: Fn(&T, &TransitStatus) + Send + Sync,
{
inner: R,
observer: F,
_phantom: core::marker::PhantomData<T>,
}
impl<T: Message, R: ReceptorPolicy<T>, F> ReceptorMiddleware<T, R, F>
where
F: Fn(&T, &TransitStatus) + Send + Sync,
{
pub fn new(inner: R, observer: F) -> Self {
Self { inner, observer, _phantom: core::marker::PhantomData }
}
}
impl<T: Message, R: ReceptorPolicy<T>, F> ReceptorPolicy<T> for ReceptorMiddleware<T, R, F>
where
F: Fn(&T, &TransitStatus) + Send + Sync,
{
fn evaluate(&self, message: &T) -> TransitStatus {
let status = self.inner.evaluate(message);
(self.observer)(message, &status);
status
}
}
#[derive(Default)]
pub struct AcceptAllGate;
impl GatePolicy for AcceptAllGate {
fn evaluate(&self, _: &Frame) -> TransitStatus {
TransitStatus::Accepted
}
}
#[derive(Debug, Clone)]
pub struct GateMiddleware<G: GatePolicy, F>
where
F: Fn(&Frame, &TransitStatus) + Send + Sync,
{
inner: G,
observer: F,
}
impl<G: GatePolicy, F> GateMiddleware<G, F>
where
F: Fn(&Frame, &TransitStatus) + Send + Sync,
{
pub fn new(inner: G, observer: F) -> Self {
Self { inner, observer }
}
}
impl<G: GatePolicy, F> GatePolicy for GateMiddleware<G, F>
where
F: Fn(&Frame, &TransitStatus) + Send + Sync,
{
fn evaluate(&self, message: &Frame) -> TransitStatus {
let status = self.inner.evaluate(message);
(self.observer)(message, &status);
status
}
}