pdk_classy/
middleware.rs

1// Copyright (c) 2025, Salesforce, Inc.,
2// All rights reserved.
3// For full license text, see the LICENSE.txt file
4
5//! Utils for Injecting code execution at specific events during the execution chain.
6
7use crate::{
8    event::{Event, EventData, RequestHeaders, ResponseHeaders},
9    BoxError,
10};
11
12/// Result of the [`EventHandler`].
13pub type EventHandlerResult = Result<(), BoxError>;
14
15/// The trait that must be implemented to inject code execution at specific events.
16pub trait EventHandler<S>
17where
18    S: Event,
19{
20    /// Execute the internal code.
21    fn call(&mut self, event: &EventData<S>) -> EventHandlerResult;
22}
23
24/// Implement even handler for generic functions.
25impl<F, S> EventHandler<S> for F
26where
27    F: for<'a> FnMut(&EventData<'a, S>) -> EventHandlerResult,
28    S: Event,
29{
30    fn call(&mut self, event: &EventData<S>) -> EventHandlerResult {
31        self(event)
32    }
33}
34
35/// A collection of [`EventHandler`]s
36pub trait EventHandlerPush<S>
37where
38    S: Event,
39{
40    /// Add a handle to the collection.
41    fn push<H>(&mut self, handler: H)
42    where
43        H: EventHandler<S> + 'static;
44}
45
46/// An interface to Invoke internal logic for the specified event.
47pub trait EventHandlerDispatch<S>
48where
49    S: Event + Sized,
50{
51    /// Invoke the internal logic for the specified event.
52    fn dispatch(&mut self, event: &EventData<S>) -> Result<(), BoxError>;
53}
54
55#[derive(Default)]
56/// Implementation that handles [`EventHandler`]s for [`RequestHeaders`] and [`ResponseHeaders`].
57pub struct EventHandlerStack {
58    request_headers_handlers: Vec<Box<dyn EventHandler<RequestHeaders>>>,
59    response_headers_handlers: Vec<Box<dyn EventHandler<ResponseHeaders>>>,
60}
61
62impl EventHandlerPush<RequestHeaders> for EventHandlerStack {
63    fn push<H>(&mut self, handler: H)
64    where
65        H: EventHandler<RequestHeaders> + 'static,
66    {
67        self.request_headers_handlers.push(Box::new(handler))
68    }
69}
70
71impl EventHandlerPush<ResponseHeaders> for EventHandlerStack {
72    fn push<H>(&mut self, handler: H)
73    where
74        H: EventHandler<ResponseHeaders> + 'static,
75    {
76        self.response_headers_handlers.push(Box::new(handler))
77    }
78}
79
80impl EventHandlerDispatch<RequestHeaders> for EventHandlerStack {
81    fn dispatch(&mut self, event: &EventData<RequestHeaders>) -> Result<(), BoxError> {
82        for h in &mut self.request_headers_handlers {
83            h.call(event)?;
84        }
85        Ok(())
86    }
87}
88
89impl EventHandlerDispatch<ResponseHeaders> for EventHandlerStack {
90    fn dispatch(&mut self, event: &EventData<ResponseHeaders>) -> Result<(), BoxError> {
91        for h in &mut self.response_headers_handlers {
92            h.call(event)?;
93        }
94        Ok(())
95    }
96}