1use crate::handler::{into_boxed_handler, BoxedHandler, Handler};
2use http::Method;
3use rustapi_openapi::Operation;
4use std::collections::HashMap;
5
6pub struct MethodRouter {
8 pub(super) handlers: HashMap<Method, BoxedHandler>,
9 pub(crate) operations: HashMap<Method, Operation>,
10 pub(crate) component_registrars: Vec<fn(&mut rustapi_openapi::OpenApiSpec)>,
11}
12
13impl Clone for MethodRouter {
14 fn clone(&self) -> Self {
15 Self {
16 handlers: self.handlers.clone(),
17 operations: self.operations.clone(),
18 component_registrars: self.component_registrars.clone(),
19 }
20 }
21}
22
23impl MethodRouter {
24 pub fn new() -> Self {
26 Self {
27 handlers: HashMap::new(),
28 operations: HashMap::new(),
29 component_registrars: Vec::new(),
30 }
31 }
32
33 fn on(
35 mut self,
36 method: Method,
37 handler: BoxedHandler,
38 operation: Operation,
39 component_registrar: fn(&mut rustapi_openapi::OpenApiSpec),
40 ) -> Self {
41 self.handlers.insert(method.clone(), handler);
42 self.operations.insert(method, operation);
43 self.component_registrars.push(component_registrar);
44 self
45 }
46
47 pub(crate) fn get_handler(&self, method: &Method) -> Option<&BoxedHandler> {
49 self.handlers.get(method)
50 }
51
52 pub(crate) fn allowed_methods(&self) -> Vec<Method> {
54 self.handlers.keys().cloned().collect()
55 }
56
57 pub(crate) fn from_boxed(handlers: HashMap<Method, BoxedHandler>) -> Self {
59 Self {
60 handlers,
61 operations: HashMap::new(), component_registrars: Vec::new(),
63 }
64 }
65
66 pub(crate) fn insert_boxed_with_operation(
70 &mut self,
71 method: Method,
72 handler: BoxedHandler,
73 operation: Operation,
74 component_registrar: fn(&mut rustapi_openapi::OpenApiSpec),
75 ) {
76 if self.handlers.contains_key(&method) {
77 panic!(
78 "Duplicate handler for method {} on the same path",
79 method.as_str()
80 );
81 }
82
83 self.handlers.insert(method.clone(), handler);
84 self.operations.insert(method, operation);
85 self.component_registrars.push(component_registrar);
86 }
87
88 pub fn get<H, T>(self, handler: H) -> Self
90 where
91 H: Handler<T>,
92 T: 'static,
93 {
94 let mut op = Operation::new();
95 H::update_operation(&mut op);
96 self.on(
97 Method::GET,
98 into_boxed_handler(handler),
99 op,
100 <H as Handler<T>>::register_components,
101 )
102 }
103
104 pub fn post<H, T>(self, handler: H) -> Self
106 where
107 H: Handler<T>,
108 T: 'static,
109 {
110 let mut op = Operation::new();
111 H::update_operation(&mut op);
112 self.on(
113 Method::POST,
114 into_boxed_handler(handler),
115 op,
116 <H as Handler<T>>::register_components,
117 )
118 }
119
120 pub fn put<H, T>(self, handler: H) -> Self
122 where
123 H: Handler<T>,
124 T: 'static,
125 {
126 let mut op = Operation::new();
127 H::update_operation(&mut op);
128 self.on(
129 Method::PUT,
130 into_boxed_handler(handler),
131 op,
132 <H as Handler<T>>::register_components,
133 )
134 }
135
136 pub fn patch<H, T>(self, handler: H) -> Self
138 where
139 H: Handler<T>,
140 T: 'static,
141 {
142 let mut op = Operation::new();
143 H::update_operation(&mut op);
144 self.on(
145 Method::PATCH,
146 into_boxed_handler(handler),
147 op,
148 <H as Handler<T>>::register_components,
149 )
150 }
151
152 pub fn delete<H, T>(self, handler: H) -> Self
154 where
155 H: Handler<T>,
156 T: 'static,
157 {
158 let mut op = Operation::new();
159 H::update_operation(&mut op);
160 self.on(
161 Method::DELETE,
162 into_boxed_handler(handler),
163 op,
164 <H as Handler<T>>::register_components,
165 )
166 }
167}
168
169impl Default for MethodRouter {
170 fn default() -> Self {
171 Self::new()
172 }
173}
174
175pub fn get<H, T>(handler: H) -> MethodRouter
177where
178 H: Handler<T>,
179 T: 'static,
180{
181 let mut op = Operation::new();
182 H::update_operation(&mut op);
183 MethodRouter::new().on(
184 Method::GET,
185 into_boxed_handler(handler),
186 op,
187 <H as Handler<T>>::register_components,
188 )
189}
190
191pub fn post<H, T>(handler: H) -> MethodRouter
193where
194 H: Handler<T>,
195 T: 'static,
196{
197 let mut op = Operation::new();
198 H::update_operation(&mut op);
199 MethodRouter::new().on(
200 Method::POST,
201 into_boxed_handler(handler),
202 op,
203 <H as Handler<T>>::register_components,
204 )
205}
206
207pub fn put<H, T>(handler: H) -> MethodRouter
209where
210 H: Handler<T>,
211 T: 'static,
212{
213 let mut op = Operation::new();
214 H::update_operation(&mut op);
215 MethodRouter::new().on(
216 Method::PUT,
217 into_boxed_handler(handler),
218 op,
219 <H as Handler<T>>::register_components,
220 )
221}
222
223pub fn patch<H, T>(handler: H) -> MethodRouter
225where
226 H: Handler<T>,
227 T: 'static,
228{
229 let mut op = Operation::new();
230 H::update_operation(&mut op);
231 MethodRouter::new().on(
232 Method::PATCH,
233 into_boxed_handler(handler),
234 op,
235 <H as Handler<T>>::register_components,
236 )
237}
238
239pub fn delete<H, T>(handler: H) -> MethodRouter
241where
242 H: Handler<T>,
243 T: 'static,
244{
245 let mut op = Operation::new();
246 H::update_operation(&mut op);
247 MethodRouter::new().on(
248 Method::DELETE,
249 into_boxed_handler(handler),
250 op,
251 <H as Handler<T>>::register_components,
252 )
253}