1use async_trait::async_trait;
2use futures::{
3 future, future::BoxFuture, future::FutureExt, future::TryFutureExt, stream, stream::StreamExt,
4 Stream,
5};
6use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
7use hyper::{service::Service, Body, Request, Response, Uri};
8use percent_encoding::{utf8_percent_encode, AsciiSet};
9use std::borrow::Cow;
10use std::convert::TryInto;
11use std::error::Error;
12use std::fmt;
13use std::future::Future;
14use std::io::{ErrorKind, Read};
15use std::marker::PhantomData;
16use std::path::Path;
17use std::str;
18use std::str::FromStr;
19use std::string::ToString;
20use std::sync::{Arc, Mutex};
21use std::task::{Context, Poll};
22use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString};
23use url::form_urlencoded;
24
25use crate::header;
26use crate::models;
27
28#[allow(dead_code)]
30const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS
31 .add(b' ')
32 .add(b'"')
33 .add(b'<')
34 .add(b'>')
35 .add(b'`');
36
37#[allow(dead_code)]
42const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|');
43
44use crate::{
45 Api, GetTaskListResponse, GetTaskLogByIdResponse, PauseTaskByIdResponse,
46 ResumeTaskByIdResponse, StartTaskResponse, StopTaskByIdResponse,
47};
48
49fn into_base_path(
51 input: impl TryInto<Uri, Error = hyper::http::uri::InvalidUri>,
52 correct_scheme: Option<&'static str>,
53) -> Result<String, ClientInitError> {
54 let uri = input.try_into()?;
56
57 let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?;
58
59 if let Some(correct_scheme) = correct_scheme {
61 if scheme != correct_scheme {
62 return Err(ClientInitError::InvalidScheme);
63 }
64 }
65
66 let host = uri.host().ok_or(ClientInitError::MissingHost)?;
67 let port = uri
68 .port_u16()
69 .map(|x| format!(":{}", x))
70 .unwrap_or_default();
71 Ok(format!(
72 "{}://{}{}{}",
73 scheme,
74 host,
75 port,
76 uri.path().trim_end_matches('/')
77 ))
78}
79
80pub struct Client<S, C>
82where
83 S: Service<(Request<Body>, C), Response = Response<Body>> + Clone + Sync + Send + 'static,
84 S::Future: Send + 'static,
85 S::Error: Into<crate::ServiceError> + fmt::Display,
86 C: Clone + Send + Sync + 'static,
87{
88 client_service: S,
90
91 base_path: String,
93
94 marker: PhantomData<fn(C)>,
96}
97
98impl<S, C> fmt::Debug for Client<S, C>
99where
100 S: Service<(Request<Body>, C), Response = Response<Body>> + Clone + Sync + Send + 'static,
101 S::Future: Send + 'static,
102 S::Error: Into<crate::ServiceError> + fmt::Display,
103 C: Clone + Send + Sync + 'static,
104{
105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 write!(f, "Client {{ base_path: {} }}", self.base_path)
107 }
108}
109
110impl<S, C> Clone for Client<S, C>
111where
112 S: Service<(Request<Body>, C), Response = Response<Body>> + Clone + Sync + Send + 'static,
113 S::Future: Send + 'static,
114 S::Error: Into<crate::ServiceError> + fmt::Display,
115 C: Clone + Send + Sync + 'static,
116{
117 fn clone(&self) -> Self {
118 Self {
119 client_service: self.client_service.clone(),
120 base_path: self.base_path.clone(),
121 marker: PhantomData,
122 }
123 }
124}
125
126impl<Connector, C> Client<DropContextService<hyper::client::Client<Connector, Body>, C>, C>
127where
128 Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static,
129 C: Clone + Send + Sync + 'static,
130{
131 pub fn try_new_with_connector(
146 base_path: &str,
147 protocol: Option<&'static str>,
148 connector: Connector,
149 ) -> Result<Self, ClientInitError> {
150 let client_service = hyper::client::Client::builder().build(connector);
151 let client_service = DropContextService::new(client_service);
152
153 Ok(Self {
154 client_service,
155 base_path: into_base_path(base_path, protocol)?,
156 marker: PhantomData,
157 })
158 }
159}
160
161#[derive(Debug, Clone)]
162pub enum HyperClient {
163 Http(hyper::client::Client<hyper::client::HttpConnector, Body>),
164 Https(hyper::client::Client<HttpsConnector, Body>),
165}
166
167impl Service<Request<Body>> for HyperClient {
168 type Response = Response<Body>;
169 type Error = hyper::Error;
170 type Future = hyper::client::ResponseFuture;
171
172 fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
173 match self {
174 HyperClient::Http(client) => client.poll_ready(cx),
175 HyperClient::Https(client) => client.poll_ready(cx),
176 }
177 }
178
179 fn call(&mut self, req: Request<Body>) -> Self::Future {
180 match self {
181 HyperClient::Http(client) => client.call(req),
182 HyperClient::Https(client) => client.call(req),
183 }
184 }
185}
186
187impl<C> Client<DropContextService<HyperClient, C>, C>
188where
189 C: Clone + Send + Sync + 'static,
190{
191 pub fn try_new(base_path: &str) -> Result<Self, ClientInitError> {
196 let uri = Uri::from_str(base_path)?;
197
198 let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?;
199 let scheme = scheme.to_ascii_lowercase();
200
201 let connector = Connector::builder();
202
203 let client_service = match scheme.as_str() {
204 "http" => HyperClient::Http(hyper::client::Client::builder().build(connector.build())),
205 "https" => {
206 let connector = connector
207 .https()
208 .build()
209 .map_err(ClientInitError::SslError)?;
210 HyperClient::Https(hyper::client::Client::builder().build(connector))
211 }
212 _ => {
213 return Err(ClientInitError::InvalidScheme);
214 }
215 };
216
217 let client_service = DropContextService::new(client_service);
218
219 Ok(Self {
220 client_service,
221 base_path: into_base_path(base_path, None)?,
222 marker: PhantomData,
223 })
224 }
225}
226
227impl<C> Client<DropContextService<hyper::client::Client<hyper::client::HttpConnector, Body>, C>, C>
228where
229 C: Clone + Send + Sync + 'static,
230{
231 pub fn try_new_http(base_path: &str) -> Result<Self, ClientInitError> {
236 let http_connector = Connector::builder().build();
237
238 Self::try_new_with_connector(base_path, Some("http"), http_connector)
239 }
240}
241
242#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))]
243type HttpsConnector = hyper_tls::HttpsConnector<hyper::client::HttpConnector>;
244
245#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
246type HttpsConnector = hyper_openssl::HttpsConnector<hyper::client::HttpConnector>;
247
248impl<C> Client<DropContextService<hyper::client::Client<HttpsConnector, Body>, C>, C>
249where
250 C: Clone + Send + Sync + 'static,
251{
252 pub fn try_new_https(base_path: &str) -> Result<Self, ClientInitError> {
257 let https_connector = Connector::builder()
258 .https()
259 .build()
260 .map_err(ClientInitError::SslError)?;
261 Self::try_new_with_connector(base_path, Some("https"), https_connector)
262 }
263
264 #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
270 pub fn try_new_https_pinned<CA>(
271 base_path: &str,
272 ca_certificate: CA,
273 ) -> Result<Self, ClientInitError>
274 where
275 CA: AsRef<Path>,
276 {
277 let https_connector = Connector::builder()
278 .https()
279 .pin_server_certificate(ca_certificate)
280 .build()
281 .map_err(ClientInitError::SslError)?;
282 Self::try_new_with_connector(base_path, Some("https"), https_connector)
283 }
284
285 #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
293 pub fn try_new_https_mutual<CA, K, D>(
294 base_path: &str,
295 ca_certificate: CA,
296 client_key: K,
297 client_certificate: D,
298 ) -> Result<Self, ClientInitError>
299 where
300 CA: AsRef<Path>,
301 K: AsRef<Path>,
302 D: AsRef<Path>,
303 {
304 let https_connector = Connector::builder()
305 .https()
306 .pin_server_certificate(ca_certificate)
307 .client_authentication(client_key, client_certificate)
308 .build()
309 .map_err(ClientInitError::SslError)?;
310 Self::try_new_with_connector(base_path, Some("https"), https_connector)
311 }
312}
313
314impl<S, C> Client<S, C>
315where
316 S: Service<(Request<Body>, C), Response = Response<Body>> + Clone + Sync + Send + 'static,
317 S::Future: Send + 'static,
318 S::Error: Into<crate::ServiceError> + fmt::Display,
319 C: Clone + Send + Sync + 'static,
320{
321 pub fn try_new_with_client_service(
326 client_service: S,
327 base_path: &str,
328 ) -> Result<Self, ClientInitError> {
329 Ok(Self {
330 client_service,
331 base_path: into_base_path(base_path, None)?,
332 marker: PhantomData,
333 })
334 }
335}
336
337#[derive(Debug)]
339pub enum ClientInitError {
340 InvalidScheme,
342
343 InvalidUri(hyper::http::uri::InvalidUri),
345
346 MissingHost,
348
349 #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))]
351 SslError(native_tls::Error),
352
353 #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
355 SslError(openssl::error::ErrorStack),
356}
357
358impl From<hyper::http::uri::InvalidUri> for ClientInitError {
359 fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError {
360 ClientInitError::InvalidUri(err)
361 }
362}
363
364impl fmt::Display for ClientInitError {
365 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
366 let s: &dyn fmt::Debug = self;
367 s.fmt(f)
368 }
369}
370
371impl Error for ClientInitError {
372 fn description(&self) -> &str {
373 "Failed to produce a hyper client."
374 }
375}
376
377#[async_trait]
378impl<S, C> Api<C> for Client<S, C>
379where
380 S: Service<(Request<Body>, C), Response = Response<Body>> + Clone + Sync + Send + 'static,
381 S::Future: Send + 'static,
382 S::Error: Into<crate::ServiceError> + fmt::Display,
383 C: Has<XSpanIdString> + Clone + Send + Sync + 'static,
384{
385 fn poll_ready(&self, cx: &mut Context) -> Poll<Result<(), crate::ServiceError>> {
386 match self.client_service.clone().poll_ready(cx) {
387 Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())),
388 Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)),
389 Poll::Pending => Poll::Pending,
390 }
391 }
392
393 async fn get_task_list(&self, context: &C) -> Result<GetTaskListResponse, ApiError> {
394 let mut client_service = self.client_service.clone();
395 let mut uri = format!("{}/task", self.base_path);
396
397 let query_string = {
399 let mut query_string = form_urlencoded::Serializer::new("".to_owned());
400 query_string.finish()
401 };
402 if !query_string.is_empty() {
403 uri += "?";
404 uri += &query_string;
405 }
406
407 let uri = match Uri::from_str(&uri) {
408 Ok(uri) => uri,
409 Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
410 };
411
412 let mut request = match Request::builder()
413 .method("GET")
414 .uri(uri)
415 .body(Body::empty())
416 {
417 Ok(req) => req,
418 Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))),
419 };
420
421 let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.as_str());
422 request.headers_mut().insert(
423 HeaderName::from_static("x-span-id"),
424 match header {
425 Ok(h) => h,
426 Err(e) => {
427 return Err(ApiError(format!(
428 "Unable to create X-Span ID header value: {}",
429 e
430 )))
431 }
432 },
433 );
434
435 let response = client_service
436 .call((request, context.clone()))
437 .map_err(|e| ApiError(format!("No response received: {}", e)))
438 .await?;
439
440 match response.status().as_u16() {
441 200 => {
442 let body = response.into_body();
443 let body = body
444 .into_raw()
445 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
446 .await?;
447 let body = str::from_utf8(&body)
448 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
449 let body = serde_json::from_str::<models::TaskListResponse>(body).map_err(|e| {
450 ApiError(format!("Response body did not match the schema: {}", e))
451 })?;
452 Ok(GetTaskListResponse::ListOfRunningTasks(body))
453 }
454 code => {
455 let headers = response.headers().clone();
456 let body = response.into_body().take(100).into_raw().await;
457 Err(ApiError(format!(
458 "Unexpected response code {}:\n{:?}\n\n{}",
459 code,
460 headers,
461 match body {
462 Ok(body) => match String::from_utf8(body) {
463 Ok(body) => body,
464 Err(e) => format!("<Body was not UTF8: {:?}>", e),
465 },
466 Err(e) => format!("<Failed to read body: {}>", e),
467 }
468 )))
469 }
470 }
471 }
472
473 async fn get_task_log_by_id(
474 &self,
475 param_get_task_log_request: models::GetTaskLogRequest,
476 context: &C,
477 ) -> Result<GetTaskLogByIdResponse, ApiError> {
478 let mut client_service = self.client_service.clone();
479 let mut uri = format!("{}/log", self.base_path);
480
481 let query_string = {
483 let mut query_string = form_urlencoded::Serializer::new("".to_owned());
484 query_string.finish()
485 };
486 if !query_string.is_empty() {
487 uri += "?";
488 uri += &query_string;
489 }
490
491 let uri = match Uri::from_str(&uri) {
492 Ok(uri) => uri,
493 Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
494 };
495
496 let mut request = match Request::builder()
497 .method("POST")
498 .uri(uri)
499 .body(Body::empty())
500 {
501 Ok(req) => req,
502 Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))),
503 };
504
505 let body = serde_json::to_string(¶m_get_task_log_request)
506 .expect("impossible to fail to serialize");
507 *request.body_mut() = Body::from(body);
508
509 let header = "application/json";
510 request.headers_mut().insert(
511 CONTENT_TYPE,
512 match HeaderValue::from_str(header) {
513 Ok(h) => h,
514 Err(e) => {
515 return Err(ApiError(format!(
516 "Unable to create header: {} - {}",
517 header, e
518 )))
519 }
520 },
521 );
522 let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.as_str());
523 request.headers_mut().insert(
524 HeaderName::from_static("x-span-id"),
525 match header {
526 Ok(h) => h,
527 Err(e) => {
528 return Err(ApiError(format!(
529 "Unable to create X-Span ID header value: {}",
530 e
531 )))
532 }
533 },
534 );
535
536 let response = client_service
537 .call((request, context.clone()))
538 .map_err(|e| ApiError(format!("No response received: {}", e)))
539 .await?;
540
541 match response.status().as_u16() {
542 404 => {
543 let body = response.into_body();
544 let body = body
545 .into_raw()
546 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
547 .await?;
548 let body = str::from_utf8(&body)
549 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
550 let body = serde_json::from_str::<models::GeneralError>(body).map_err(|e| {
551 ApiError(format!("Response body did not match the schema: {}", e))
552 })?;
553 Ok(GetTaskLogByIdResponse::InvalidHandle(body))
554 }
555 200 => {
556 let body = response.into_body();
557 let body = body
558 .into_raw()
559 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
560 .await?;
561 let body = str::from_utf8(&body)
562 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
563 let body = serde_json::from_str::<Vec<models::GetTaskLogResponseInner>>(body)
564 .map_err(|e| {
565 ApiError(format!("Response body did not match the schema: {}", e))
566 })?;
567 Ok(GetTaskLogByIdResponse::TheLogFetched(body))
568 }
569 code => {
570 let headers = response.headers().clone();
571 let body = response.into_body().take(100).into_raw().await;
572 Err(ApiError(format!(
573 "Unexpected response code {}:\n{:?}\n\n{}",
574 code,
575 headers,
576 match body {
577 Ok(body) => match String::from_utf8(body) {
578 Ok(body) => body,
579 Err(e) => format!("<Body was not UTF8: {:?}>", e),
580 },
581 Err(e) => format!("<Failed to read body: {}>", e),
582 }
583 )))
584 }
585 }
586 }
587
588 async fn pause_task_by_id(
589 &self,
590 param_simple_id_request: models::SimpleIdRequest,
591 context: &C,
592 ) -> Result<PauseTaskByIdResponse, ApiError> {
593 let mut client_service = self.client_service.clone();
594 let mut uri = format!("{}/pause", self.base_path);
595
596 let query_string = {
598 let mut query_string = form_urlencoded::Serializer::new("".to_owned());
599 query_string.finish()
600 };
601 if !query_string.is_empty() {
602 uri += "?";
603 uri += &query_string;
604 }
605
606 let uri = match Uri::from_str(&uri) {
607 Ok(uri) => uri,
608 Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
609 };
610
611 let mut request = match Request::builder()
612 .method("POST")
613 .uri(uri)
614 .body(Body::empty())
615 {
616 Ok(req) => req,
617 Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))),
618 };
619
620 let body = serde_json::to_string(¶m_simple_id_request)
621 .expect("impossible to fail to serialize");
622 *request.body_mut() = Body::from(body);
623
624 let header = "application/json";
625 request.headers_mut().insert(
626 CONTENT_TYPE,
627 match HeaderValue::from_str(header) {
628 Ok(h) => h,
629 Err(e) => {
630 return Err(ApiError(format!(
631 "Unable to create header: {} - {}",
632 header, e
633 )))
634 }
635 },
636 );
637 let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.as_str());
638 request.headers_mut().insert(
639 HeaderName::from_static("x-span-id"),
640 match header {
641 Ok(h) => h,
642 Err(e) => {
643 return Err(ApiError(format!(
644 "Unable to create X-Span ID header value: {}",
645 e
646 )))
647 }
648 },
649 );
650
651 let response = client_service
652 .call((request, context.clone()))
653 .map_err(|e| ApiError(format!("No response received: {}", e)))
654 .await?;
655
656 match response.status().as_u16() {
657 400 => {
658 let body = response.into_body();
659 let body = body
660 .into_raw()
661 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
662 .await?;
663 let body = str::from_utf8(&body)
664 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
665 let body = serde_json::from_str::<models::GeneralError>(body).map_err(|e| {
666 ApiError(format!("Response body did not match the schema: {}", e))
667 })?;
668 Ok(PauseTaskByIdResponse::FailedToPause(body))
669 }
670 404 => {
671 let body = response.into_body();
672 let body = body
673 .into_raw()
674 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
675 .await?;
676 let body = str::from_utf8(&body)
677 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
678 let body = serde_json::from_str::<models::GeneralError>(body).map_err(|e| {
679 ApiError(format!("Response body did not match the schema: {}", e))
680 })?;
681 Ok(PauseTaskByIdResponse::InvalidHandle(body))
682 }
683 200 => {
684 let body = response.into_body();
685 let body = body
686 .into_raw()
687 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
688 .await?;
689 let body = str::from_utf8(&body)
690 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
691 let body = serde_json::from_str::<models::TaskStatus>(body).map_err(|e| {
692 ApiError(format!("Response body did not match the schema: {}", e))
693 })?;
694 Ok(PauseTaskByIdResponse::StatusOfPausingTheTask(body))
695 }
696 code => {
697 let headers = response.headers().clone();
698 let body = response.into_body().take(100).into_raw().await;
699 Err(ApiError(format!(
700 "Unexpected response code {}:\n{:?}\n\n{}",
701 code,
702 headers,
703 match body {
704 Ok(body) => match String::from_utf8(body) {
705 Ok(body) => body,
706 Err(e) => format!("<Body was not UTF8: {:?}>", e),
707 },
708 Err(e) => format!("<Failed to read body: {}>", e),
709 }
710 )))
711 }
712 }
713 }
714
715 async fn resume_task_by_id(
716 &self,
717 param_simple_id_request: models::SimpleIdRequest,
718 context: &C,
719 ) -> Result<ResumeTaskByIdResponse, ApiError> {
720 let mut client_service = self.client_service.clone();
721 let mut uri = format!("{}/resume", self.base_path);
722
723 let query_string = {
725 let mut query_string = form_urlencoded::Serializer::new("".to_owned());
726 query_string.finish()
727 };
728 if !query_string.is_empty() {
729 uri += "?";
730 uri += &query_string;
731 }
732
733 let uri = match Uri::from_str(&uri) {
734 Ok(uri) => uri,
735 Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
736 };
737
738 let mut request = match Request::builder()
739 .method("POST")
740 .uri(uri)
741 .body(Body::empty())
742 {
743 Ok(req) => req,
744 Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))),
745 };
746
747 let body = serde_json::to_string(¶m_simple_id_request)
748 .expect("impossible to fail to serialize");
749 *request.body_mut() = Body::from(body);
750
751 let header = "application/json";
752 request.headers_mut().insert(
753 CONTENT_TYPE,
754 match HeaderValue::from_str(header) {
755 Ok(h) => h,
756 Err(e) => {
757 return Err(ApiError(format!(
758 "Unable to create header: {} - {}",
759 header, e
760 )))
761 }
762 },
763 );
764 let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.as_str());
765 request.headers_mut().insert(
766 HeaderName::from_static("x-span-id"),
767 match header {
768 Ok(h) => h,
769 Err(e) => {
770 return Err(ApiError(format!(
771 "Unable to create X-Span ID header value: {}",
772 e
773 )))
774 }
775 },
776 );
777
778 let response = client_service
779 .call((request, context.clone()))
780 .map_err(|e| ApiError(format!("No response received: {}", e)))
781 .await?;
782
783 match response.status().as_u16() {
784 400 => {
785 let body = response.into_body();
786 let body = body
787 .into_raw()
788 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
789 .await?;
790 let body = str::from_utf8(&body)
791 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
792 let body = serde_json::from_str::<models::GeneralError>(body).map_err(|e| {
793 ApiError(format!("Response body did not match the schema: {}", e))
794 })?;
795 Ok(ResumeTaskByIdResponse::FailedToResume(body))
796 }
797 404 => {
798 let body = response.into_body();
799 let body = body
800 .into_raw()
801 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
802 .await?;
803 let body = str::from_utf8(&body)
804 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
805 let body = serde_json::from_str::<models::GeneralError>(body).map_err(|e| {
806 ApiError(format!("Response body did not match the schema: {}", e))
807 })?;
808 Ok(ResumeTaskByIdResponse::InvalidHandle(body))
809 }
810 200 => {
811 let body = response.into_body();
812 let body = body
813 .into_raw()
814 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
815 .await?;
816 let body = str::from_utf8(&body)
817 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
818 let body = serde_json::from_str::<models::TaskStatus>(body).map_err(|e| {
819 ApiError(format!("Response body did not match the schema: {}", e))
820 })?;
821 Ok(ResumeTaskByIdResponse::StatusOfTheTask(body))
822 }
823 code => {
824 let headers = response.headers().clone();
825 let body = response.into_body().take(100).into_raw().await;
826 Err(ApiError(format!(
827 "Unexpected response code {}:\n{:?}\n\n{}",
828 code,
829 headers,
830 match body {
831 Ok(body) => match String::from_utf8(body) {
832 Ok(body) => body,
833 Err(e) => format!("<Body was not UTF8: {:?}>", e),
834 },
835 Err(e) => format!("<Failed to read body: {}>", e),
836 }
837 )))
838 }
839 }
840 }
841
842 async fn start_task(
843 &self,
844 param_start_task_request: models::StartTaskRequest,
845 context: &C,
846 ) -> Result<StartTaskResponse, ApiError> {
847 let mut client_service = self.client_service.clone();
848 let mut uri = format!("{}/task", self.base_path);
849
850 let query_string = {
852 let mut query_string = form_urlencoded::Serializer::new("".to_owned());
853 query_string.finish()
854 };
855 if !query_string.is_empty() {
856 uri += "?";
857 uri += &query_string;
858 }
859
860 let uri = match Uri::from_str(&uri) {
861 Ok(uri) => uri,
862 Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
863 };
864
865 let mut request = match Request::builder()
866 .method("POST")
867 .uri(uri)
868 .body(Body::empty())
869 {
870 Ok(req) => req,
871 Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))),
872 };
873
874 let body = serde_json::to_string(¶m_start_task_request)
875 .expect("impossible to fail to serialize");
876 *request.body_mut() = Body::from(body);
877
878 let header = "application/json";
879 request.headers_mut().insert(
880 CONTENT_TYPE,
881 match HeaderValue::from_str(header) {
882 Ok(h) => h,
883 Err(e) => {
884 return Err(ApiError(format!(
885 "Unable to create header: {} - {}",
886 header, e
887 )))
888 }
889 },
890 );
891 let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.as_str());
892 request.headers_mut().insert(
893 HeaderName::from_static("x-span-id"),
894 match header {
895 Ok(h) => h,
896 Err(e) => {
897 return Err(ApiError(format!(
898 "Unable to create X-Span ID header value: {}",
899 e
900 )))
901 }
902 },
903 );
904
905 let response = client_service
906 .call((request, context.clone()))
907 .map_err(|e| ApiError(format!("No response received: {}", e)))
908 .await?;
909
910 match response.status().as_u16() {
911 400 => {
912 let body = response.into_body();
913 let body = body
914 .into_raw()
915 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
916 .await?;
917 let body = str::from_utf8(&body)
918 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
919 let body = serde_json::from_str::<models::GeneralError>(body).map_err(|e| {
920 ApiError(format!("Response body did not match the schema: {}", e))
921 })?;
922 Ok(StartTaskResponse::InvalidArguments(body))
923 }
924 200 => {
925 let body = response.into_body();
926 let body = body
927 .into_raw()
928 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
929 .await?;
930 let body = str::from_utf8(&body)
931 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
932 let body =
933 serde_json::from_str::<models::StartTask200Response>(body).map_err(|e| {
934 ApiError(format!("Response body did not match the schema: {}", e))
935 })?;
936 Ok(StartTaskResponse::ListOfRunningTasks(body))
937 }
938 code => {
939 let headers = response.headers().clone();
940 let body = response.into_body().take(100).into_raw().await;
941 Err(ApiError(format!(
942 "Unexpected response code {}:\n{:?}\n\n{}",
943 code,
944 headers,
945 match body {
946 Ok(body) => match String::from_utf8(body) {
947 Ok(body) => body,
948 Err(e) => format!("<Body was not UTF8: {:?}>", e),
949 },
950 Err(e) => format!("<Failed to read body: {}>", e),
951 }
952 )))
953 }
954 }
955 }
956
957 async fn stop_task_by_id(
958 &self,
959 param_simple_id_request: models::SimpleIdRequest,
960 context: &C,
961 ) -> Result<StopTaskByIdResponse, ApiError> {
962 let mut client_service = self.client_service.clone();
963 let mut uri = format!("{}/stop", self.base_path);
964
965 let query_string = {
967 let mut query_string = form_urlencoded::Serializer::new("".to_owned());
968 query_string.finish()
969 };
970 if !query_string.is_empty() {
971 uri += "?";
972 uri += &query_string;
973 }
974
975 let uri = match Uri::from_str(&uri) {
976 Ok(uri) => uri,
977 Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
978 };
979
980 let mut request = match Request::builder()
981 .method("POST")
982 .uri(uri)
983 .body(Body::empty())
984 {
985 Ok(req) => req,
986 Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))),
987 };
988
989 let body = serde_json::to_string(¶m_simple_id_request)
990 .expect("impossible to fail to serialize");
991
992 *request.body_mut() = Body::from(body);
993
994 let header = "application/json";
995 request.headers_mut().insert(
996 CONTENT_TYPE,
997 match HeaderValue::from_str(header) {
998 Ok(h) => h,
999 Err(e) => {
1000 return Err(ApiError(format!(
1001 "Unable to create header: {} - {}",
1002 header, e
1003 )))
1004 }
1005 },
1006 );
1007
1008 let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.as_str());
1009 request.headers_mut().insert(
1010 HeaderName::from_static("x-span-id"),
1011 match header {
1012 Ok(h) => h,
1013 Err(e) => {
1014 return Err(ApiError(format!(
1015 "Unable to create X-Span ID header value: {}",
1016 e
1017 )))
1018 }
1019 },
1020 );
1021
1022 let response = client_service
1023 .call((request, context.clone()))
1024 .map_err(|e| ApiError(format!("No response received: {}", e)))
1025 .await?;
1026
1027 match response.status().as_u16() {
1028 200 => {
1029 let body = response.into_body();
1030 let body = body
1031 .into_raw()
1032 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1033 .await?;
1034 let body = str::from_utf8(&body)
1035 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
1036 let body = serde_json::from_str::<serde_json::Value>(body).map_err(|e| {
1037 ApiError(format!("Response body did not match the schema: {}", e))
1038 })?;
1039 Ok(StopTaskByIdResponse::StatusOfStoppingTheTask(body))
1040 }
1041 404 => {
1042 let body = response.into_body();
1043 let body = body
1044 .into_raw()
1045 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1046 .await?;
1047 let body = str::from_utf8(&body)
1048 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
1049 let body = serde_json::from_str::<models::GeneralError>(body).map_err(|e| {
1050 ApiError(format!("Response body did not match the schema: {}", e))
1051 })?;
1052 Ok(StopTaskByIdResponse::InvalidHandle(body))
1053 }
1054 500 => {
1055 let body = response.into_body();
1056 let body = body
1057 .into_raw()
1058 .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1059 .await?;
1060 let body = str::from_utf8(&body)
1061 .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?;
1062 let body = serde_json::from_str::<models::GeneralError>(body).map_err(|e| {
1063 ApiError(format!("Response body did not match the schema: {}", e))
1064 })?;
1065 Ok(StopTaskByIdResponse::FailedToTerminate(body))
1066 }
1067 code => {
1068 let headers = response.headers().clone();
1069 let body = response.into_body().take(100).into_raw().await;
1070 Err(ApiError(format!(
1071 "Unexpected response code {}:\n{:?}\n\n{}",
1072 code,
1073 headers,
1074 match body {
1075 Ok(body) => match String::from_utf8(body) {
1076 Ok(body) => body,
1077 Err(e) => format!("<Body was not UTF8: {:?}>", e),
1078 },
1079 Err(e) => format!("<Failed to read body: {}>", e),
1080 }
1081 )))
1082 }
1083 }
1084 }
1085}