Skip to main content

a3s_boot/routing/route/
pipeline.rs

1use super::definition::RouteDefinition;
2use crate::pipeline::{
3    ExecutionInterceptorAdapter, PipelineComponent, PipelineComponents, PipelineOverrides,
4};
5use crate::{
6    body_validator, body_validator_with_options, params_validator, params_validator_with_options,
7    query_validator, query_validator_with_options, BootErrorKind, ExceptionFilter,
8    ExecutionInterceptor, Guard, Interceptor, Middleware, Pipe, Validate, ValidationOptions,
9    ValidationSchema,
10};
11use serde::{de::DeserializeOwned, Serialize};
12use std::sync::Arc;
13
14impl RouteDefinition {
15    pub(crate) fn with_pipeline_prefix(mut self, pipeline: &PipelineComponents) -> Self {
16        self.middleware = prepend_arc(&pipeline.middleware, self.middleware);
17        self.pipes = prepend_component(&pipeline.pipes, self.pipes);
18        self.guards = prepend_component(&pipeline.guards, self.guards);
19        self.interceptors = prepend_component(&pipeline.interceptors, self.interceptors);
20        self.filters = prepend_component(&pipeline.filters, self.filters);
21        if !self.validation_disabled {
22            self.validation_enabled = pipeline.validation_enabled || self.validation_enabled;
23            self.validation_options = pipeline.validation_options.merge(self.validation_options);
24        }
25        self
26    }
27
28    pub fn with_pipe<P>(mut self, pipe: P) -> Self
29    where
30        P: Pipe,
31    {
32        self.pipes.push(PipelineComponent::<dyn Pipe>::new(pipe));
33        self
34    }
35
36    pub fn with_middleware<M>(mut self, middleware: M) -> Self
37    where
38        M: Middleware,
39    {
40        self.middleware.push(Arc::new(middleware));
41        self
42    }
43
44    pub(crate) fn with_middleware_prefix_arc(mut self, middleware: &[Arc<dyn Middleware>]) -> Self {
45        self.middleware = prepend_arc(middleware, self.middleware);
46        self
47    }
48
49    pub(crate) fn insert_middleware_prefix_at(
50        mut self,
51        index: usize,
52        middleware: Arc<dyn Middleware>,
53    ) -> Self {
54        self.middleware
55            .insert(index.min(self.middleware.len()), middleware);
56        self
57    }
58
59    pub fn with_guard<G>(mut self, guard: G) -> Self
60    where
61        G: Guard,
62    {
63        self.guards.push(PipelineComponent::<dyn Guard>::new(guard));
64        self
65    }
66
67    pub(crate) fn insert_pipe_prefix_at(
68        mut self,
69        index: usize,
70        pipe: PipelineComponent<dyn Pipe>,
71    ) -> Self {
72        self.pipes.insert(index.min(self.pipes.len()), pipe);
73        self
74    }
75
76    pub(crate) fn insert_guard_prefix_at(
77        mut self,
78        index: usize,
79        guard: PipelineComponent<dyn Guard>,
80    ) -> Self {
81        self.guards.insert(index.min(self.guards.len()), guard);
82        self
83    }
84
85    pub fn with_interceptor<I>(mut self, interceptor: I) -> Self
86    where
87        I: Interceptor,
88    {
89        self.interceptors
90            .push(PipelineComponent::<dyn Interceptor>::new(interceptor));
91        self
92    }
93
94    pub(crate) fn insert_interceptor_prefix_at(
95        mut self,
96        index: usize,
97        interceptor: PipelineComponent<dyn Interceptor>,
98    ) -> Self {
99        self.interceptors
100            .insert(index.min(self.interceptors.len()), interceptor);
101        self
102    }
103
104    pub fn with_execution_interceptor<I>(self, interceptor: I) -> Self
105    where
106        I: ExecutionInterceptor,
107    {
108        self.with_interceptor(ExecutionInterceptorAdapter::new(interceptor))
109    }
110
111    pub(crate) fn with_pipeline_overrides(mut self, overrides: &PipelineOverrides) -> Self {
112        overrides.apply_to_pipes(&mut self.pipes);
113        overrides.apply_to_guards(&mut self.guards);
114        overrides.apply_to_interceptors(&mut self.interceptors);
115        overrides.apply_to_filters(&mut self.filters);
116        self
117    }
118
119    pub fn with_filter<F>(mut self, filter: F) -> Self
120    where
121        F: ExceptionFilter,
122    {
123        self.filters
124            .push(PipelineComponent::<dyn ExceptionFilter>::new(filter));
125        self
126    }
127
128    pub(crate) fn insert_filter_prefix_at(
129        mut self,
130        index: usize,
131        filter: PipelineComponent<dyn ExceptionFilter>,
132    ) -> Self {
133        self.filters.insert(index.min(self.filters.len()), filter);
134        self
135    }
136
137    pub fn with_catch_filter<I, F>(self, kinds: I, filter: F) -> Self
138    where
139        I: IntoIterator<Item = BootErrorKind>,
140        F: ExceptionFilter,
141    {
142        self.with_filter(crate::catch_errors(kinds, filter))
143    }
144
145    pub fn with_validation(mut self) -> Self {
146        self.validation_enabled = true;
147        self.validation_disabled = false;
148        self
149    }
150
151    pub fn with_validation_options(mut self, options: ValidationOptions) -> Self {
152        self.validation_enabled = true;
153        self.validation_disabled = false;
154        self.validation_options = self.validation_options.merge(options);
155        self
156    }
157
158    pub fn without_validation(mut self) -> Self {
159        self.validation_enabled = false;
160        self.validation_disabled = true;
161        self
162    }
163
164    pub fn with_body_validation<T>(mut self) -> Self
165    where
166        T: DeserializeOwned + Validate + 'static,
167    {
168        self.validators.push(body_validator::<T>());
169        self
170    }
171
172    pub fn with_body_validation_options<T>(mut self, options: ValidationOptions) -> Self
173    where
174        T: DeserializeOwned + Serialize + Validate + ValidationSchema + 'static,
175    {
176        self.validators
177            .push(body_validator_with_options::<T>(options));
178        self
179    }
180
181    pub fn with_params_validation<T>(mut self) -> Self
182    where
183        T: DeserializeOwned + Validate + 'static,
184    {
185        self.validators.push(params_validator::<T>());
186        self
187    }
188
189    pub fn with_params_validation_options<T>(mut self, options: ValidationOptions) -> Self
190    where
191        T: DeserializeOwned + Serialize + Validate + ValidationSchema + 'static,
192    {
193        self.validators
194            .push(params_validator_with_options::<T>(options));
195        self
196    }
197
198    pub fn with_query_validation<T>(mut self) -> Self
199    where
200        T: DeserializeOwned + Validate + 'static,
201    {
202        self.validators.push(query_validator::<T>());
203        self
204    }
205
206    pub fn with_query_validation_options<T>(mut self, options: ValidationOptions) -> Self
207    where
208        T: DeserializeOwned + Serialize + Validate + ValidationSchema + 'static,
209    {
210        self.validators
211            .push(query_validator_with_options::<T>(options));
212        self
213    }
214}
215
216fn prepend_arc<T>(prefix: &[Arc<T>], values: Vec<Arc<T>>) -> Vec<Arc<T>>
217where
218    T: ?Sized,
219{
220    let mut merged = prefix.to_vec();
221    merged.extend(values);
222    merged
223}
224
225fn prepend_component<T>(
226    prefix: &[PipelineComponent<T>],
227    values: Vec<PipelineComponent<T>>,
228) -> Vec<PipelineComponent<T>>
229where
230    T: ?Sized,
231{
232    let mut merged = prefix.to_vec();
233    merged.extend(values);
234    merged
235}