Skip to main content

tightbeam/
policy.rs

1#[cfg(not(feature = "std"))]
2extern crate alloc;
3#[cfg(not(feature = "std"))]
4use alloc::sync::Arc;
5
6use crate::der::Enumerated;
7use crate::{Frame, Message};
8
9/// Transport response status codes
10#[derive(Enumerated, Default, Debug, Clone, Copy, PartialEq, Eq)]
11#[repr(u8)]
12pub enum TransitStatus {
13	#[default]
14	Request = 0,
15	Accepted = 1,
16	Busy = 2,
17	Unauthorized = 3,
18	Forbidden = 4,
19	Timeout = 5,
20}
21
22/// Policy trait a user implements to decide message acceptance.
23///
24/// Gate policies are stateless procedures that evaluate whether a message
25/// should be accepted or rejected.
26pub trait GatePolicy: Send + Sync {
27	fn evaluate(&self, message: &Frame) -> TransitStatus;
28}
29
30/// Policy trait a user implements to decide message acceptance.
31pub trait ReceptorPolicy<T: Message>: Send + Sync {
32	fn evaluate(&self, message: &T) -> TransitStatus;
33}
34
35/// Middleware wrapper for receptor policies that observes evaluations.
36///
37/// Wraps any `ReceptorPolicy` and calls a closure with the evaluation result.
38/// The middleware is transparent - it passes through the gate's decision
39/// unchanged.
40pub struct ReceptorMiddleware<T: Message, R: ReceptorPolicy<T>, F>
41where
42	F: Fn(&T, &TransitStatus) + Send + Sync,
43{
44	inner: R,
45	observer: F,
46	_phantom: core::marker::PhantomData<T>,
47}
48
49impl<T: Message, R: ReceptorPolicy<T>, F> ReceptorMiddleware<T, R, F>
50where
51	F: Fn(&T, &TransitStatus) + Send + Sync,
52{
53	/// Create a new middleware wrapper around a receptor policy.
54	///
55	/// # Arguments
56	/// * `inner` - The underlying receptor policy to wrap
57	/// * `observer` - Closure called with the message and evaluation result
58	pub fn new(inner: R, observer: F) -> Self {
59		Self { inner, observer, _phantom: core::marker::PhantomData }
60	}
61}
62
63impl<T: Message, R: ReceptorPolicy<T>, F> ReceptorPolicy<T> for ReceptorMiddleware<T, R, F>
64where
65	F: Fn(&T, &TransitStatus) + Send + Sync,
66{
67	fn evaluate(&self, message: &T) -> TransitStatus {
68		let status = self.inner.evaluate(message);
69
70		// Observe the evaluation (transparent)
71		(self.observer)(message, &status);
72
73		status
74	}
75}
76/// Default gate that always accepts.
77#[derive(Default)]
78pub struct AcceptAllGate;
79
80impl GatePolicy for AcceptAllGate {
81	fn evaluate(&self, _: &Frame) -> TransitStatus {
82		TransitStatus::Accepted
83	}
84}
85
86/// Middleware wrapper for gate policies that observes evaluations.
87///
88/// Wraps any `GatePolicy` and calls a closure with the evaluation result.
89/// The middleware is transparent - it passes through the gate's decision
90/// unchanged.
91#[derive(Debug, Clone)]
92pub struct GateMiddleware<G: GatePolicy, F>
93where
94	F: Fn(&Frame, &TransitStatus) + Send + Sync,
95{
96	inner: G,
97	observer: F,
98}
99
100impl<G: GatePolicy, F> GateMiddleware<G, F>
101where
102	F: Fn(&Frame, &TransitStatus) + Send + Sync,
103{
104	/// Create a new middleware wrapper around a gate policy.
105	///
106	/// # Arguments
107	/// * `inner` - The underlying gate policy to wrap
108	/// * `observer` - Closure called with the message and evaluation result
109	pub fn new(inner: G, observer: F) -> Self {
110		Self { inner, observer }
111	}
112}
113
114impl<G: GatePolicy, F> GatePolicy for GateMiddleware<G, F>
115where
116	F: Fn(&Frame, &TransitStatus) + Send + Sync,
117{
118	fn evaluate(&self, message: &Frame) -> TransitStatus {
119		let status = self.inner.evaluate(message);
120
121		// Observe the evaluation (transparent)
122		(self.observer)(message, &status);
123
124		status
125	}
126}