1use std::marker::PhantomData;
8
9use crate::proxy_wasm::traits::RootContext;
10
11use crate::{
12 entrypoint::Entrypoint,
13 event::{Event, RequestHeaders, ResponseHeaders},
14 middleware::{EventHandler, EventHandlerPush, EventHandlerStack},
15};
16
17#[derive(Default)]
18pub struct Plugin<E = (), T = ()> {
20 event_handlers: EventHandlerStack,
21 entrypoint: E,
22 _types: PhantomData<T>,
23}
24
25impl EventHandlerPush<RequestHeaders> for Plugin {
26 fn push<H>(&mut self, handler: H)
27 where
28 H: EventHandler<RequestHeaders> + 'static,
29 {
30 self.event_handlers.push(handler)
31 }
32}
33
34impl EventHandlerPush<ResponseHeaders> for Plugin {
35 fn push<H>(&mut self, handler: H)
36 where
37 H: EventHandler<ResponseHeaders> + 'static,
38 {
39 self.event_handlers.push(handler)
40 }
41}
42
43impl Plugin {
44 pub fn new() -> Self {
45 Self::default()
46 }
47
48 pub fn event_handler<H, S>(mut self, handler: H) -> Self
49 where
50 S: Event,
51 H: EventHandler<S> + 'static,
52 Self: EventHandlerPush<S>,
53 {
54 self.push(handler);
55 self
56 }
57
58 pub fn entrypoint<C, T, E>(self, entrypoint: E) -> Plugin<E, (C, T)>
59 where
60 E: Entrypoint<C, T>,
61 {
62 Plugin {
63 event_handlers: self.event_handlers,
64 entrypoint,
65 _types: PhantomData,
66 }
67 }
68}
69
70impl<E, C, T> Plugin<E, (C, T)>
71where
72 E: Entrypoint<C, T>,
73{
74 pub fn create_root_context(self, context_id: u32) -> Box<dyn RootContext> {
75 self.entrypoint
76 .create_root_context(self.event_handlers, context_id)
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use crate::{
83 bootstrap::Launcher,
84 client::HttpClient,
85 event::{EventData, Exchange, RequestHeaders, ResponseHeaders},
86 Configuration, Plugin,
87 };
88
89 #[test]
90 fn test_configure() {
91 Plugin::new()
92 .entrypoint(|_: Launcher| async {})
93 .create_root_context(1);
94 }
95
96 #[test]
97 fn test_filter() {
98 Plugin::new()
99 .entrypoint(|_: Exchange<RequestHeaders>| async {})
100 .create_root_context(1);
101 }
102
103 #[test]
104 fn test_configure_with_dependencies() {
105 Plugin::new()
106 .entrypoint(|_: Launcher, _: Configuration| async {})
107 .create_root_context(1);
108 }
109
110 #[test]
111 fn test_filter_with_dependencies() {
112 Plugin::new()
113 .entrypoint(|_: Launcher, _: HttpClient| async {})
114 .create_root_context(1);
115 }
116
117 #[test]
118 fn test_configure_with_event_handlers() {
119 Plugin::new()
120 .event_handler(|_: &EventData<RequestHeaders>| Ok(()))
121 .event_handler(|_: &EventData<ResponseHeaders>| Ok(()))
122 .entrypoint(|_: Launcher| async {})
123 .create_root_context(1);
124 }
125}