1use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt};
2use hyper::{Request, Response, StatusCode, Body, HeaderMap};
3use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
4use log::warn;
5#[allow(unused_imports)]
6use std::convert::{TryFrom, TryInto};
7use std::error::Error;
8use std::future::Future;
9use std::marker::PhantomData;
10use std::task::{Context, Poll};
11use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString};
12pub use swagger::auth::Authorization;
13use swagger::auth::Scopes;
14use url::form_urlencoded;
15
16#[allow(unused_imports)]
17use crate::models;
18use crate::header;
19
20pub use crate::context;
21
22type ServiceFuture = BoxFuture<'static, Result<Response<Body>, crate::ServiceError>>;
23
24use crate::{Api,
25 GetResponse,
26 GetMultiResponse,
27 HatResponse,
28 HatOffResponse,
29 HatOnResponse,
30 MbusApiResponse,
31 ScanResponse
32};
33
34mod paths {
35 use lazy_static::lazy_static;
36
37 lazy_static! {
38 pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![
39 r"^/mbus/api$",
40 r"^/mbus/get/(?P<device>[^/?#]*)/(?P<baudrate>[^/?#]*)/(?P<address>[^/?#]*)$",
41 r"^/mbus/getMulti/(?P<device>[^/?#]*)/(?P<baudrate>[^/?#]*)/(?P<address>[^/?#]*)/(?P<maxframes>[^/?#]*)$",
42 r"^/mbus/hat$",
43 r"^/mbus/hat/off$",
44 r"^/mbus/hat/on$",
45 r"^/mbus/scan/(?P<device>[^/?#]*)/(?P<baudrate>[^/?#]*)$"
46 ])
47 .expect("Unable to create global regex set");
48 }
49 pub(crate) static ID_MBUS_API: usize = 0;
50 pub(crate) static ID_MBUS_GET_DEVICE_BAUDRATE_ADDRESS: usize = 1;
51 lazy_static! {
52 pub static ref REGEX_MBUS_GET_DEVICE_BAUDRATE_ADDRESS: regex::Regex =
53 regex::Regex::new(r"^/mbus/get/(?P<device>[^/?#]*)/(?P<baudrate>[^/?#]*)/(?P<address>[^/?#]*)$")
54 .expect("Unable to create regex for MBUS_GET_DEVICE_BAUDRATE_ADDRESS");
55 }
56 pub(crate) static ID_MBUS_GETMULTI_DEVICE_BAUDRATE_ADDRESS_MAXFRAMES: usize = 2;
57 lazy_static! {
58 pub static ref REGEX_MBUS_GETMULTI_DEVICE_BAUDRATE_ADDRESS_MAXFRAMES: regex::Regex =
59 regex::Regex::new(r"^/mbus/getMulti/(?P<device>[^/?#]*)/(?P<baudrate>[^/?#]*)/(?P<address>[^/?#]*)/(?P<maxframes>[^/?#]*)$")
60 .expect("Unable to create regex for MBUS_GETMULTI_DEVICE_BAUDRATE_ADDRESS_MAXFRAMES");
61 }
62 pub(crate) static ID_MBUS_HAT: usize = 3;
63 pub(crate) static ID_MBUS_HAT_OFF: usize = 4;
64 pub(crate) static ID_MBUS_HAT_ON: usize = 5;
65 pub(crate) static ID_MBUS_SCAN_DEVICE_BAUDRATE: usize = 6;
66 lazy_static! {
67 pub static ref REGEX_MBUS_SCAN_DEVICE_BAUDRATE: regex::Regex =
68 regex::Regex::new(r"^/mbus/scan/(?P<device>[^/?#]*)/(?P<baudrate>[^/?#]*)$")
69 .expect("Unable to create regex for MBUS_SCAN_DEVICE_BAUDRATE");
70 }
71}
72
73pub struct MakeService<T, C> where
74 T: Api<C> + Clone + Send + 'static,
75 C: Has<XSpanIdString> + Send + Sync + 'static
76{
77 api_impl: T,
78 marker: PhantomData<C>,
79}
80
81impl<T, C> MakeService<T, C> where
82 T: Api<C> + Clone + Send + 'static,
83 C: Has<XSpanIdString> + Send + Sync + 'static
84{
85 pub fn new(api_impl: T) -> Self {
86 MakeService {
87 api_impl,
88 marker: PhantomData
89 }
90 }
91}
92
93impl<T, C, Target> hyper::service::Service<Target> for MakeService<T, C> where
94 T: Api<C> + Clone + Send + 'static,
95 C: Has<XSpanIdString> + Send + Sync + 'static
96{
97 type Response = Service<T, C>;
98 type Error = crate::ServiceError;
99 type Future = future::Ready<Result<Self::Response, Self::Error>>;
100
101 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
102 Poll::Ready(Ok(()))
103 }
104
105 fn call(&mut self, target: Target) -> Self::Future {
106 futures::future::ok(Service::new(
107 self.api_impl.clone(),
108 ))
109 }
110}
111
112fn method_not_allowed() -> Result<Response<Body>, crate::ServiceError> {
113 Ok(
114 Response::builder().status(StatusCode::METHOD_NOT_ALLOWED)
115 .body(Body::empty())
116 .expect("Unable to create Method Not Allowed response")
117 )
118}
119
120pub struct Service<T, C> where
121 T: Api<C> + Clone + Send + 'static,
122 C: Has<XSpanIdString> + Send + Sync + 'static
123{
124 api_impl: T,
125 marker: PhantomData<C>,
126}
127
128impl<T, C> Service<T, C> where
129 T: Api<C> + Clone + Send + 'static,
130 C: Has<XSpanIdString> + Send + Sync + 'static
131{
132 pub fn new(api_impl: T) -> Self {
133 Service {
134 api_impl: api_impl,
135 marker: PhantomData
136 }
137 }
138}
139
140impl<T, C> Clone for Service<T, C> where
141 T: Api<C> + Clone + Send + 'static,
142 C: Has<XSpanIdString> + Send + Sync + 'static
143{
144 fn clone(&self) -> Self {
145 Service {
146 api_impl: self.api_impl.clone(),
147 marker: self.marker.clone(),
148 }
149 }
150}
151
152impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
153 T: Api<C> + Clone + Send + Sync + 'static,
154 C: Has<XSpanIdString> + Send + Sync + 'static
155{
156 type Response = Response<Body>;
157 type Error = crate::ServiceError;
158 type Future = ServiceFuture;
159
160 fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
161 self.api_impl.poll_ready(cx)
162 }
163
164 fn call(&mut self, req: (Request<Body>, C)) -> Self::Future { async fn run<T, C>(mut api_impl: T, req: (Request<Body>, C)) -> Result<Response<Body>, crate::ServiceError> where
165 T: Api<C> + Clone + Send + 'static,
166 C: Has<XSpanIdString> + Send + Sync + 'static
167 {
168 let (request, context) = req;
169 let (parts, body) = request.into_parts();
170 let (method, uri, headers) = (parts.method, parts.uri, parts.headers);
171 let path = paths::GLOBAL_REGEX_SET.matches(uri.path());
172
173 match &method {
174
175 &hyper::Method::POST if path.matched(paths::ID_MBUS_GET_DEVICE_BAUDRATE_ADDRESS) => {
177 let path: &str = &uri.path().to_string();
179 let path_params =
180 paths::REGEX_MBUS_GET_DEVICE_BAUDRATE_ADDRESS
181 .captures(&path)
182 .unwrap_or_else(||
183 panic!("Path {} matched RE MBUS_GET_DEVICE_BAUDRATE_ADDRESS in set but failed match against \"{}\"", path, paths::REGEX_MBUS_GET_DEVICE_BAUDRATE_ADDRESS.as_str())
184 );
185
186 let param_device = match percent_encoding::percent_decode(path_params["device"].as_bytes()).decode_utf8() {
187 Ok(param_device) => match param_device.parse::<String>() {
188 Ok(param_device) => param_device,
189 Err(e) => return Ok(Response::builder()
190 .status(StatusCode::BAD_REQUEST)
191 .body(Body::from(format!("Couldn't parse path parameter device: {}", e)))
192 .expect("Unable to create Bad Request response for invalid path parameter")),
193 },
194 Err(_) => return Ok(Response::builder()
195 .status(StatusCode::BAD_REQUEST)
196 .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["device"])))
197 .expect("Unable to create Bad Request response for invalid percent decode"))
198 };
199
200 let param_baudrate = match percent_encoding::percent_decode(path_params["baudrate"].as_bytes()).decode_utf8() {
201 Ok(param_baudrate) => match param_baudrate.parse::<models::Baudrate>() {
202 Ok(param_baudrate) => param_baudrate,
203 Err(e) => return Ok(Response::builder()
204 .status(StatusCode::BAD_REQUEST)
205 .body(Body::from(format!("Couldn't parse path parameter baudrate: {}", e)))
206 .expect("Unable to create Bad Request response for invalid path parameter")),
207 },
208 Err(_) => return Ok(Response::builder()
209 .status(StatusCode::BAD_REQUEST)
210 .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["baudrate"])))
211 .expect("Unable to create Bad Request response for invalid percent decode"))
212 };
213
214 let param_address = match percent_encoding::percent_decode(path_params["address"].as_bytes()).decode_utf8() {
215 Ok(param_address) => match param_address.parse::<String>() {
216 Ok(param_address) => param_address,
217 Err(e) => return Ok(Response::builder()
218 .status(StatusCode::BAD_REQUEST)
219 .body(Body::from(format!("Couldn't parse path parameter address: {}", e)))
220 .expect("Unable to create Bad Request response for invalid path parameter")),
221 },
222 Err(_) => return Ok(Response::builder()
223 .status(StatusCode::BAD_REQUEST)
224 .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["address"])))
225 .expect("Unable to create Bad Request response for invalid percent decode"))
226 };
227
228 let result = api_impl.get(
229 param_device,
230 param_baudrate,
231 param_address,
232 &context
233 ).await;
234 let mut response = Response::new(Body::empty());
235 response.headers_mut().insert(
236 HeaderName::from_static("x-span-id"),
237 HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
238 .expect("Unable to create X-Span-ID header value"));
239
240 match result {
241 Ok(rsp) => match rsp {
242 GetResponse::OK
243 (body)
244 => {
245 *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
246 response.headers_mut().insert(
247 CONTENT_TYPE,
248 HeaderValue::from_str("application/xml")
249 .expect("Unable to create Content-Type header for GET_OK"));
250 let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize");
251 *response.body_mut() = Body::from(body);
252 },
253 GetResponse::BadRequest
254 (body)
255 => {
256 *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode");
257 response.headers_mut().insert(
258 CONTENT_TYPE,
259 HeaderValue::from_str("text/plain")
260 .expect("Unable to create Content-Type header for GET_BAD_REQUEST"));
261 let body = body;
262 *response.body_mut() = Body::from(body);
263 },
264 GetResponse::NotFound
265 (body)
266 => {
267 *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode");
268 response.headers_mut().insert(
269 CONTENT_TYPE,
270 HeaderValue::from_str("text/plain")
271 .expect("Unable to create Content-Type header for GET_NOT_FOUND"));
272 let body = body;
273 *response.body_mut() = Body::from(body);
274 },
275 },
276 Err(_) => {
277 *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
280 *response.body_mut() = Body::from("An internal error occurred");
281 },
282 }
283
284 Ok(response)
285 },
286
287 &hyper::Method::POST if path.matched(paths::ID_MBUS_GETMULTI_DEVICE_BAUDRATE_ADDRESS_MAXFRAMES) => {
289 let path: &str = &uri.path().to_string();
291 let path_params =
292 paths::REGEX_MBUS_GETMULTI_DEVICE_BAUDRATE_ADDRESS_MAXFRAMES
293 .captures(&path)
294 .unwrap_or_else(||
295 panic!("Path {} matched RE MBUS_GETMULTI_DEVICE_BAUDRATE_ADDRESS_MAXFRAMES in set but failed match against \"{}\"", path, paths::REGEX_MBUS_GETMULTI_DEVICE_BAUDRATE_ADDRESS_MAXFRAMES.as_str())
296 );
297
298 let param_device = match percent_encoding::percent_decode(path_params["device"].as_bytes()).decode_utf8() {
299 Ok(param_device) => match param_device.parse::<String>() {
300 Ok(param_device) => param_device,
301 Err(e) => return Ok(Response::builder()
302 .status(StatusCode::BAD_REQUEST)
303 .body(Body::from(format!("Couldn't parse path parameter device: {}", e)))
304 .expect("Unable to create Bad Request response for invalid path parameter")),
305 },
306 Err(_) => return Ok(Response::builder()
307 .status(StatusCode::BAD_REQUEST)
308 .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["device"])))
309 .expect("Unable to create Bad Request response for invalid percent decode"))
310 };
311
312 let param_baudrate = match percent_encoding::percent_decode(path_params["baudrate"].as_bytes()).decode_utf8() {
313 Ok(param_baudrate) => match param_baudrate.parse::<models::Baudrate>() {
314 Ok(param_baudrate) => param_baudrate,
315 Err(e) => return Ok(Response::builder()
316 .status(StatusCode::BAD_REQUEST)
317 .body(Body::from(format!("Couldn't parse path parameter baudrate: {}", e)))
318 .expect("Unable to create Bad Request response for invalid path parameter")),
319 },
320 Err(_) => return Ok(Response::builder()
321 .status(StatusCode::BAD_REQUEST)
322 .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["baudrate"])))
323 .expect("Unable to create Bad Request response for invalid percent decode"))
324 };
325
326 let param_address = match percent_encoding::percent_decode(path_params["address"].as_bytes()).decode_utf8() {
327 Ok(param_address) => match param_address.parse::<String>() {
328 Ok(param_address) => param_address,
329 Err(e) => return Ok(Response::builder()
330 .status(StatusCode::BAD_REQUEST)
331 .body(Body::from(format!("Couldn't parse path parameter address: {}", e)))
332 .expect("Unable to create Bad Request response for invalid path parameter")),
333 },
334 Err(_) => return Ok(Response::builder()
335 .status(StatusCode::BAD_REQUEST)
336 .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["address"])))
337 .expect("Unable to create Bad Request response for invalid percent decode"))
338 };
339
340 let param_maxframes = match percent_encoding::percent_decode(path_params["maxframes"].as_bytes()).decode_utf8() {
341 Ok(param_maxframes) => match param_maxframes.parse::<i32>() {
342 Ok(param_maxframes) => param_maxframes,
343 Err(e) => return Ok(Response::builder()
344 .status(StatusCode::BAD_REQUEST)
345 .body(Body::from(format!("Couldn't parse path parameter maxframes: {}", e)))
346 .expect("Unable to create Bad Request response for invalid path parameter")),
347 },
348 Err(_) => return Ok(Response::builder()
349 .status(StatusCode::BAD_REQUEST)
350 .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["maxframes"])))
351 .expect("Unable to create Bad Request response for invalid percent decode"))
352 };
353
354 let result = api_impl.get_multi(
355 param_device,
356 param_baudrate,
357 param_address,
358 param_maxframes,
359 &context
360 ).await;
361 let mut response = Response::new(Body::empty());
362 response.headers_mut().insert(
363 HeaderName::from_static("x-span-id"),
364 HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
365 .expect("Unable to create X-Span-ID header value"));
366
367 match result {
368 Ok(rsp) => match rsp {
369 GetMultiResponse::OK
370 (body)
371 => {
372 *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
373 response.headers_mut().insert(
374 CONTENT_TYPE,
375 HeaderValue::from_str("application/xml")
376 .expect("Unable to create Content-Type header for GET_MULTI_OK"));
377 let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize");
378 *response.body_mut() = Body::from(body);
379 },
380 GetMultiResponse::BadRequest
381 (body)
382 => {
383 *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode");
384 response.headers_mut().insert(
385 CONTENT_TYPE,
386 HeaderValue::from_str("text/plain")
387 .expect("Unable to create Content-Type header for GET_MULTI_BAD_REQUEST"));
388 let body = body;
389 *response.body_mut() = Body::from(body);
390 },
391 GetMultiResponse::NotFound
392 (body)
393 => {
394 *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode");
395 response.headers_mut().insert(
396 CONTENT_TYPE,
397 HeaderValue::from_str("text/plain")
398 .expect("Unable to create Content-Type header for GET_MULTI_NOT_FOUND"));
399 let body = body;
400 *response.body_mut() = Body::from(body);
401 },
402 },
403 Err(_) => {
404 *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
407 *response.body_mut() = Body::from("An internal error occurred");
408 },
409 }
410
411 Ok(response)
412 },
413
414 &hyper::Method::GET if path.matched(paths::ID_MBUS_HAT) => {
416 let result = api_impl.hat(
417 &context
418 ).await;
419 let mut response = Response::new(Body::empty());
420 response.headers_mut().insert(
421 HeaderName::from_static("x-span-id"),
422 HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
423 .expect("Unable to create X-Span-ID header value"));
424
425 match result {
426 Ok(rsp) => match rsp {
427 HatResponse::OK
428 (body)
429 => {
430 *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
431 response.headers_mut().insert(
432 CONTENT_TYPE,
433 HeaderValue::from_str("application/json")
434 .expect("Unable to create Content-Type header for HAT_OK"));
435 let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
436 *response.body_mut() = Body::from(body);
437 },
438 HatResponse::NotFound
439 (body)
440 => {
441 *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode");
442 response.headers_mut().insert(
443 CONTENT_TYPE,
444 HeaderValue::from_str("text/plain")
445 .expect("Unable to create Content-Type header for HAT_NOT_FOUND"));
446 let body = body;
447 *response.body_mut() = Body::from(body);
448 },
449 },
450 Err(_) => {
451 *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
454 *response.body_mut() = Body::from("An internal error occurred");
455 },
456 }
457
458 Ok(response)
459 },
460
461 &hyper::Method::POST if path.matched(paths::ID_MBUS_HAT_OFF) => {
463 let result = api_impl.hat_off(
464 &context
465 ).await;
466 let mut response = Response::new(Body::empty());
467 response.headers_mut().insert(
468 HeaderName::from_static("x-span-id"),
469 HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
470 .expect("Unable to create X-Span-ID header value"));
471
472 match result {
473 Ok(rsp) => match rsp {
474 HatOffResponse::OK
475 => {
476 *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
477 },
478 HatOffResponse::NotFound
479 (body)
480 => {
481 *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode");
482 response.headers_mut().insert(
483 CONTENT_TYPE,
484 HeaderValue::from_str("text/plain")
485 .expect("Unable to create Content-Type header for HAT_OFF_NOT_FOUND"));
486 let body = body;
487 *response.body_mut() = Body::from(body);
488 },
489 },
490 Err(_) => {
491 *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
494 *response.body_mut() = Body::from("An internal error occurred");
495 },
496 }
497
498 Ok(response)
499 },
500
501 &hyper::Method::POST if path.matched(paths::ID_MBUS_HAT_ON) => {
503 let result = api_impl.hat_on(
504 &context
505 ).await;
506 let mut response = Response::new(Body::empty());
507 response.headers_mut().insert(
508 HeaderName::from_static("x-span-id"),
509 HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
510 .expect("Unable to create X-Span-ID header value"));
511
512 match result {
513 Ok(rsp) => match rsp {
514 HatOnResponse::OK
515 => {
516 *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
517 },
518 HatOnResponse::NotFound
519 (body)
520 => {
521 *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode");
522 response.headers_mut().insert(
523 CONTENT_TYPE,
524 HeaderValue::from_str("text/plain")
525 .expect("Unable to create Content-Type header for HAT_ON_NOT_FOUND"));
526 let body = body;
527 *response.body_mut() = Body::from(body);
528 },
529 },
530 Err(_) => {
531 *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
534 *response.body_mut() = Body::from("An internal error occurred");
535 },
536 }
537
538 Ok(response)
539 },
540
541 &hyper::Method::GET if path.matched(paths::ID_MBUS_API) => {
543 let result = api_impl.mbus_api(
544 &context
545 ).await;
546 let mut response = Response::new(Body::empty());
547 response.headers_mut().insert(
548 HeaderName::from_static("x-span-id"),
549 HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
550 .expect("Unable to create X-Span-ID header value"));
551
552 match result {
553 Ok(rsp) => match rsp {
554 MbusApiResponse::OK
555 (body)
556 => {
557 *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
558 response.headers_mut().insert(
559 CONTENT_TYPE,
560 HeaderValue::from_str("text/x-yaml")
561 .expect("Unable to create Content-Type header for MBUS_API_OK"));
562 let body = body;
563 *response.body_mut() = Body::from(body);
564 },
565 MbusApiResponse::NotFound
566 (body)
567 => {
568 *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode");
569 response.headers_mut().insert(
570 CONTENT_TYPE,
571 HeaderValue::from_str("text/plain")
572 .expect("Unable to create Content-Type header for MBUS_API_NOT_FOUND"));
573 let body = body;
574 *response.body_mut() = Body::from(body);
575 },
576 },
577 Err(_) => {
578 *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
581 *response.body_mut() = Body::from("An internal error occurred");
582 },
583 }
584
585 Ok(response)
586 },
587
588 &hyper::Method::POST if path.matched(paths::ID_MBUS_SCAN_DEVICE_BAUDRATE) => {
590 let path: &str = &uri.path().to_string();
592 let path_params =
593 paths::REGEX_MBUS_SCAN_DEVICE_BAUDRATE
594 .captures(&path)
595 .unwrap_or_else(||
596 panic!("Path {} matched RE MBUS_SCAN_DEVICE_BAUDRATE in set but failed match against \"{}\"", path, paths::REGEX_MBUS_SCAN_DEVICE_BAUDRATE.as_str())
597 );
598
599 let param_device = match percent_encoding::percent_decode(path_params["device"].as_bytes()).decode_utf8() {
600 Ok(param_device) => match param_device.parse::<String>() {
601 Ok(param_device) => param_device,
602 Err(e) => return Ok(Response::builder()
603 .status(StatusCode::BAD_REQUEST)
604 .body(Body::from(format!("Couldn't parse path parameter device: {}", e)))
605 .expect("Unable to create Bad Request response for invalid path parameter")),
606 },
607 Err(_) => return Ok(Response::builder()
608 .status(StatusCode::BAD_REQUEST)
609 .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["device"])))
610 .expect("Unable to create Bad Request response for invalid percent decode"))
611 };
612
613 let param_baudrate = match percent_encoding::percent_decode(path_params["baudrate"].as_bytes()).decode_utf8() {
614 Ok(param_baudrate) => match param_baudrate.parse::<models::Baudrate>() {
615 Ok(param_baudrate) => param_baudrate,
616 Err(e) => return Ok(Response::builder()
617 .status(StatusCode::BAD_REQUEST)
618 .body(Body::from(format!("Couldn't parse path parameter baudrate: {}", e)))
619 .expect("Unable to create Bad Request response for invalid path parameter")),
620 },
621 Err(_) => return Ok(Response::builder()
622 .status(StatusCode::BAD_REQUEST)
623 .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["baudrate"])))
624 .expect("Unable to create Bad Request response for invalid percent decode"))
625 };
626
627 let result = api_impl.scan(
628 param_device,
629 param_baudrate,
630 &context
631 ).await;
632 let mut response = Response::new(Body::empty());
633 response.headers_mut().insert(
634 HeaderName::from_static("x-span-id"),
635 HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
636 .expect("Unable to create X-Span-ID header value"));
637
638 match result {
639 Ok(rsp) => match rsp {
640 ScanResponse::OK
641 (body)
642 => {
643 *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
644 response.headers_mut().insert(
645 CONTENT_TYPE,
646 HeaderValue::from_str("text/plain")
647 .expect("Unable to create Content-Type header for SCAN_OK"));
648 let body = body;
649 *response.body_mut() = Body::from(body);
650 },
651 ScanResponse::BadRequest
652 (body)
653 => {
654 *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode");
655 response.headers_mut().insert(
656 CONTENT_TYPE,
657 HeaderValue::from_str("text/plain")
658 .expect("Unable to create Content-Type header for SCAN_BAD_REQUEST"));
659 let body = body;
660 *response.body_mut() = Body::from(body);
661 },
662 ScanResponse::NotFound
663 (body)
664 => {
665 *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode");
666 response.headers_mut().insert(
667 CONTENT_TYPE,
668 HeaderValue::from_str("text/plain")
669 .expect("Unable to create Content-Type header for SCAN_NOT_FOUND"));
670 let body = body;
671 *response.body_mut() = Body::from(body);
672 },
673 },
674 Err(_) => {
675 *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
678 *response.body_mut() = Body::from("An internal error occurred");
679 },
680 }
681
682 Ok(response)
683 },
684
685 _ if path.matched(paths::ID_MBUS_API) => method_not_allowed(),
686 _ if path.matched(paths::ID_MBUS_GET_DEVICE_BAUDRATE_ADDRESS) => method_not_allowed(),
687 _ if path.matched(paths::ID_MBUS_GETMULTI_DEVICE_BAUDRATE_ADDRESS_MAXFRAMES) => method_not_allowed(),
688 _ if path.matched(paths::ID_MBUS_HAT) => method_not_allowed(),
689 _ if path.matched(paths::ID_MBUS_HAT_OFF) => method_not_allowed(),
690 _ if path.matched(paths::ID_MBUS_HAT_ON) => method_not_allowed(),
691 _ if path.matched(paths::ID_MBUS_SCAN_DEVICE_BAUDRATE) => method_not_allowed(),
692 _ => Ok(Response::builder().status(StatusCode::NOT_FOUND)
693 .body(Body::empty())
694 .expect("Unable to create Not Found response"))
695 }
696 } Box::pin(run(self.api_impl.clone(), req)) }
697}
698
699pub struct ApiRequestParser;
701impl<T> RequestParser<T> for ApiRequestParser {
702 fn parse_operation_id(request: &Request<T>) -> Result<&'static str, ()> {
703 let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path());
704 match request.method() {
705 &hyper::Method::POST if path.matched(paths::ID_MBUS_GET_DEVICE_BAUDRATE_ADDRESS) => Ok("Get"),
707 &hyper::Method::POST if path.matched(paths::ID_MBUS_GETMULTI_DEVICE_BAUDRATE_ADDRESS_MAXFRAMES) => Ok("GetMulti"),
709 &hyper::Method::GET if path.matched(paths::ID_MBUS_HAT) => Ok("Hat"),
711 &hyper::Method::POST if path.matched(paths::ID_MBUS_HAT_OFF) => Ok("HatOff"),
713 &hyper::Method::POST if path.matched(paths::ID_MBUS_HAT_ON) => Ok("HatOn"),
715 &hyper::Method::GET if path.matched(paths::ID_MBUS_API) => Ok("MbusApi"),
717 &hyper::Method::POST if path.matched(paths::ID_MBUS_SCAN_DEVICE_BAUDRATE) => Ok("Scan"),
719 _ => Err(()),
720 }
721 }
722}