spacegate_kernel/service/http_route/
builder.rs1use std::{fmt::Debug, path::PathBuf, time::Duration};
2
3use hyper::Version;
4
5use crate::BoxLayer;
6
7use super::{match_request::HttpRouteMatch, Backend, BalancePolicyEnum, HttpBackend, HttpRoute, HttpRouteRule};
8
9#[derive(Debug)]
10pub struct HttpRouteBuilder {
11 pub name: String,
12 pub hostnames: Vec<String>,
13 pub rules: Vec<HttpRouteRule>,
14 pub plugins: Vec<BoxLayer>,
15 pub priority: Option<i16>,
16 pub extensions: hyper::http::Extensions,
17}
18
19impl Default for HttpRouteBuilder {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25impl HttpRouteBuilder {
26 pub fn new() -> Self {
27 Self {
28 name: Default::default(),
29 hostnames: Vec::new(),
30 rules: Vec::new(),
31 plugins: Vec::new(),
32 priority: None,
33 extensions: Default::default(),
34 }
35 }
36 pub fn name(mut self, name: impl Into<String>) -> Self {
37 self.name = name.into();
38 self
39 }
40 pub fn hostnames(mut self, hostnames: impl IntoIterator<Item = String>) -> Self {
41 self.hostnames = hostnames.into_iter().collect();
42 self
43 }
44 pub fn rule(mut self, rule: HttpRouteRule) -> Self {
45 self.rules.push(rule);
46 self
47 }
48 pub fn rules(mut self, rules: impl IntoIterator<Item = HttpRouteRule>) -> Self {
49 self.rules.extend(rules);
50 self
51 }
52 pub fn plugin(mut self, plugin: BoxLayer) -> Self {
53 self.plugins.push(plugin);
54 self
55 }
56 pub fn plugins(mut self, plugins: impl IntoIterator<Item = BoxLayer>) -> Self {
57 self.plugins.extend(plugins);
58 self
59 }
60 pub fn priority(mut self, priority: i16) -> Self {
61 self.priority = Some(priority);
62 self
63 }
64 pub fn ext(mut self, extensions: hyper::http::Extensions) -> Self {
65 self.extensions = extensions;
66 self
67 }
68 pub fn build(mut self) -> HttpRoute {
69 if self.hostnames.iter().any(|host| host == "*") {
70 self.hostnames = vec!["*".to_string()]
71 }
72 HttpRoute {
73 plugins: self.plugins,
74 hostnames: self.hostnames,
75 rules: self.rules,
76 priority: self.priority.unwrap_or(1),
77 name: self.name,
78 ext: self.extensions,
79 }
80 }
81}
82
83#[derive(Debug)]
84pub struct HttpRouteRuleBuilder {
85 r#match: Option<Vec<HttpRouteMatch>>,
86 pub plugins: Vec<BoxLayer>,
87 timeouts: Option<Duration>,
88 backends: Vec<HttpBackend>,
89 pub extensions: hyper::http::Extensions,
90 pub balance_policy: BalancePolicyEnum,
91}
92impl Default for HttpRouteRuleBuilder {
93 fn default() -> Self {
94 Self::new()
95 }
96}
97
98impl HttpRouteRuleBuilder {
99 pub fn new() -> Self {
100 Self {
101 r#match: None,
102 plugins: Vec::new(),
103 timeouts: None,
104 backends: Vec::new(),
105 extensions: Default::default(),
106 balance_policy: BalancePolicyEnum::default(),
107 }
108 }
109 pub fn match_item(mut self, item: impl Into<HttpRouteMatch>) -> Self {
110 match self.r#match {
111 Some(ref mut matches) => matches.push(item.into()),
112 None => self.r#match = Some(vec![item.into()]),
113 }
114 self
115 }
116 pub fn matches(mut self, matches: impl IntoIterator<Item = HttpRouteMatch>) -> Self {
117 self.r#match = Some(matches.into_iter().collect());
118 self
119 }
120 pub fn match_all(mut self) -> Self {
121 self.r#match = None;
122 self
123 }
124 pub fn plugin(mut self, plugin: BoxLayer) -> Self {
125 self.plugins.push(plugin);
126 self
127 }
128 pub fn plugins(mut self, plugins: impl IntoIterator<Item = BoxLayer>) -> Self {
129 self.plugins.extend(plugins);
130 self
131 }
132 pub fn timeout(mut self, timeout: Duration) -> Self {
133 self.timeouts = Some(timeout);
134 self
135 }
136 pub fn backend(mut self, backend: HttpBackend) -> Self {
137 self.backends.push(backend);
138 self
139 }
140 pub fn backends(mut self, backend: impl IntoIterator<Item = HttpBackend>) -> Self {
141 self.backends.extend(backend);
142 self
143 }
144 pub fn balance_policy(mut self, policy: BalancePolicyEnum) -> Self {
145 self.balance_policy = policy;
146 self
147 }
148 pub fn build(self) -> HttpRouteRule {
149 HttpRouteRule {
150 r#match: self.r#match,
151 plugins: self.plugins,
152 timeouts: self.timeouts,
153 backends: self.backends,
154 ext: self.extensions,
155 balance_policy: self.balance_policy,
156 }
157 }
158 pub fn ext(mut self, extension: hyper::http::Extensions) -> Self {
159 self.extensions = extension;
160 self
161 }
162}
163pub trait BackendKindBuilder: Default + Debug {
164 fn build(self) -> Backend;
165}
166#[derive(Debug)]
167pub struct HttpBackendBuilder<B: BackendKindBuilder = HttpBackendKindBuilder> {
168 backend: B,
169 pub plugins: Vec<BoxLayer>,
170 timeout: Option<Duration>,
171 weight: u16,
172 pub extensions: hyper::http::Extensions,
173}
174
175#[derive(Debug, Default, Clone)]
176pub struct HttpBackendKindBuilder {
177 pub host: Option<String>,
178 pub port: Option<u16>,
179 pub schema: Option<String>,
180 pub version: Option<Version>,
181}
182
183impl BackendKindBuilder for HttpBackendKindBuilder {
184 fn build(self) -> Backend {
185 Backend::Http {
186 host: self.host,
187 port: self.port,
188 schema: self.schema,
189 version: self.version,
190 }
191 }
192}
193#[derive(Debug, Default, Clone)]
194
195pub struct FileBackendKindBuilder {
196 path: PathBuf,
197}
198
199impl BackendKindBuilder for FileBackendKindBuilder {
200 fn build(self) -> Backend {
201 Backend::File { path: self.path }
202 }
203}
204
205impl<B: BackendKindBuilder> Default for HttpBackendBuilder<B> {
206 fn default() -> Self {
207 Self {
208 backend: B::default(),
209 plugins: Vec::new(),
210 timeout: None,
211 weight: 1,
212 extensions: Default::default(),
213 }
214 }
215}
216
217impl HttpBackendBuilder<FileBackendKindBuilder> {
218 pub fn path(mut self, path: impl Into<PathBuf>) -> Self {
219 self.backend = FileBackendKindBuilder { path: path.into() };
220 self
221 }
222}
223
224impl HttpBackendBuilder<HttpBackendKindBuilder> {
225 pub fn host(mut self, host: impl Into<String>) -> Self {
226 self.backend = HttpBackendKindBuilder {
227 host: Some(host.into()),
228 ..self.backend
229 };
230 self
231 }
232 pub fn port(mut self, port: u16) -> Self {
233 self.backend = HttpBackendKindBuilder { port: Some(port), ..self.backend };
234 self
235 }
236 pub fn schema(mut self, schema: impl Into<String>) -> Self {
237 self.backend = HttpBackendKindBuilder {
238 schema: Some(schema.into()),
239 ..self.backend
240 };
241 self
242 }
243 pub fn version(mut self, version: Version) -> Self {
244 self.backend = HttpBackendKindBuilder {
245 version: Some(version),
246 ..self.backend
247 };
248 self
249 }
250}
251
252impl<B: BackendKindBuilder> HttpBackendBuilder<B> {
253 pub fn new() -> Self {
254 Self::default()
255 }
256 pub fn plugin(mut self, plugin: BoxLayer) -> Self {
257 self.plugins.push(plugin);
258 self
259 }
260 pub fn plugins(mut self, plugins: impl IntoIterator<Item = BoxLayer>) -> Self {
261 self.plugins.extend(plugins);
262 self
263 }
264 pub fn timeout(mut self, timeout: Duration) -> Self {
265 self.timeout = Some(timeout);
266 self
267 }
268 pub fn weight(mut self, weight: u16) -> Self {
269 self.weight = weight;
270 self
271 }
272 pub fn http(self) -> HttpBackendBuilder<HttpBackendKindBuilder> {
273 HttpBackendBuilder {
274 backend: HttpBackendKindBuilder::default(),
275 plugins: self.plugins,
276 timeout: self.timeout,
277 weight: self.weight,
278 extensions: self.extensions,
279 }
280 }
281 pub fn file(self) -> HttpBackendBuilder<FileBackendKindBuilder> {
282 HttpBackendBuilder {
283 backend: FileBackendKindBuilder::default(),
284 plugins: self.plugins,
285 timeout: self.timeout,
286 weight: self.weight,
287 extensions: self.extensions,
288 }
289 }
290 pub fn ext(mut self, extension: hyper::http::Extensions) -> Self {
291 self.extensions = extension;
292 self
293 }
294 pub fn build(self) -> HttpBackend {
295 HttpBackend {
296 backend: self.backend.build(),
297 plugins: self.plugins,
298 timeout: self.timeout,
299 weight: self.weight,
300 ext: self.extensions,
301 }
302 }
303}