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, params_validator, query_validator, BootErrorKind, ExceptionFilter,
7    ExecutionInterceptor, Guard, Interceptor, Middleware, Pipe, Validate,
8};
9use serde::de::DeserializeOwned;
10use std::sync::Arc;
11
12impl RouteDefinition {
13    pub(crate) fn with_pipeline_prefix(mut self, pipeline: &PipelineComponents) -> Self {
14        self.middleware = prepend_arc(&pipeline.middleware, self.middleware);
15        self.pipes = prepend_component(&pipeline.pipes, self.pipes);
16        self.guards = prepend_component(&pipeline.guards, self.guards);
17        self.interceptors = prepend_component(&pipeline.interceptors, self.interceptors);
18        self.filters = prepend_component(&pipeline.filters, self.filters);
19        if !self.validation_disabled {
20            self.validation_enabled = pipeline.validation_enabled || self.validation_enabled;
21        }
22        self
23    }
24
25    pub fn with_pipe<P>(mut self, pipe: P) -> Self
26    where
27        P: Pipe,
28    {
29        self.pipes.push(PipelineComponent::<dyn Pipe>::new(pipe));
30        self
31    }
32
33    pub fn with_middleware<M>(mut self, middleware: M) -> Self
34    where
35        M: Middleware,
36    {
37        self.middleware.push(Arc::new(middleware));
38        self
39    }
40
41    pub fn with_guard<G>(mut self, guard: G) -> Self
42    where
43        G: Guard,
44    {
45        self.guards.push(PipelineComponent::<dyn Guard>::new(guard));
46        self
47    }
48
49    pub fn with_interceptor<I>(mut self, interceptor: I) -> Self
50    where
51        I: Interceptor,
52    {
53        self.interceptors
54            .push(PipelineComponent::<dyn Interceptor>::new(interceptor));
55        self
56    }
57
58    pub fn with_execution_interceptor<I>(self, interceptor: I) -> Self
59    where
60        I: ExecutionInterceptor,
61    {
62        self.with_interceptor(ExecutionInterceptorAdapter::new(interceptor))
63    }
64
65    pub(crate) fn with_pipeline_overrides(mut self, overrides: &PipelineOverrides) -> Self {
66        overrides.apply_to_pipes(&mut self.pipes);
67        overrides.apply_to_guards(&mut self.guards);
68        overrides.apply_to_interceptors(&mut self.interceptors);
69        overrides.apply_to_filters(&mut self.filters);
70        self
71    }
72
73    pub fn with_filter<F>(mut self, filter: F) -> Self
74    where
75        F: ExceptionFilter,
76    {
77        self.filters
78            .push(PipelineComponent::<dyn ExceptionFilter>::new(filter));
79        self
80    }
81
82    pub fn with_catch_filter<I, F>(self, kinds: I, filter: F) -> Self
83    where
84        I: IntoIterator<Item = BootErrorKind>,
85        F: ExceptionFilter,
86    {
87        self.with_filter(crate::catch_errors(kinds, filter))
88    }
89
90    pub fn with_validation(mut self) -> Self {
91        self.validation_enabled = true;
92        self.validation_disabled = false;
93        self
94    }
95
96    pub fn without_validation(mut self) -> Self {
97        self.validation_enabled = false;
98        self.validation_disabled = true;
99        self
100    }
101
102    pub fn with_body_validation<T>(mut self) -> Self
103    where
104        T: DeserializeOwned + Validate + 'static,
105    {
106        self.validators.push(body_validator::<T>());
107        self
108    }
109
110    pub fn with_params_validation<T>(mut self) -> Self
111    where
112        T: DeserializeOwned + Validate + 'static,
113    {
114        self.validators.push(params_validator::<T>());
115        self
116    }
117
118    pub fn with_query_validation<T>(mut self) -> Self
119    where
120        T: DeserializeOwned + Validate + 'static,
121    {
122        self.validators.push(query_validator::<T>());
123        self
124    }
125}
126
127fn prepend_arc<T>(prefix: &[Arc<T>], values: Vec<Arc<T>>) -> Vec<Arc<T>>
128where
129    T: ?Sized,
130{
131    let mut merged = prefix.to_vec();
132    merged.extend(values);
133    merged
134}
135
136fn prepend_component<T>(
137    prefix: &[PipelineComponent<T>],
138    values: Vec<PipelineComponent<T>>,
139) -> Vec<PipelineComponent<T>>
140where
141    T: ?Sized,
142{
143    let mut merged = prefix.to_vec();
144    merged.extend(values);
145    merged
146}