i2cbus_api/client/
mod.rs

1use futures;
2use futures::{Future, Stream, future, stream};
3use hyper;
4use hyper::client::HttpConnector;
5use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
6use hyper::{Body, Uri, Response};
7#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
8use hyper_openssl::HttpsConnector;
9use serde_json;
10use std::borrow::Cow;
11use std::convert::TryInto;
12use std::io::{Read, Error, ErrorKind};
13use std::error;
14use std::fmt;
15use std::path::Path;
16use std::sync::Arc;
17use std::str;
18use std::str::FromStr;
19use std::string::ToString;
20use swagger;
21use swagger::{ApiError, Connector, client::Service, XSpanIdString, Has, AuthData};
22use url::form_urlencoded;
23use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET};
24
25use crate::models;
26use crate::header;
27
28url::define_encode_set! {
29    /// This encode set is used for object IDs
30    ///
31    /// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`,
32    /// the vertical bar (|) is encoded.
33    pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'}
34}
35
36use crate::{Api,
37     I2cBusApiResponse,
38     I2cBusListResponse,
39     I2cBusReadByteResponse,
40     I2cBusReadBytesResponse,
41     I2cBusReadRegResponse,
42     I2cBusWriteByteResponse,
43     I2cBusWriteByteRegResponse,
44     I2cBusWriteBytesResponse,
45     I2cBusWriteBytesRegResponse
46     };
47
48/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes.
49fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result<String, ClientInitError> {
50    // First convert to Uri, since a base path is a subset of Uri.
51    let uri = Uri::from_str(input)?;
52
53    let scheme = uri.scheme_part().ok_or(ClientInitError::InvalidScheme)?;
54
55    // Check the scheme if necessary
56    if let Some(correct_scheme) = correct_scheme {
57        if scheme != correct_scheme {
58            return Err(ClientInitError::InvalidScheme);
59        }
60    }
61
62    let host = uri.host().ok_or_else(|| ClientInitError::MissingHost)?;
63    let port = uri.port_part().map(|x| format!(":{}", x)).unwrap_or_default();
64    Ok(format!("{}://{}{}{}", scheme, host, port, uri.path().trim_end_matches('/')))
65}
66
67/// A client that implements the API by making HTTP calls out to a server.
68pub struct Client<F>
69{
70    /// Inner service
71    client_service: Arc<Box<dyn Service<ReqBody=Body, Future=F> + Send + Sync>>,
72
73    /// Base path of the API
74    base_path: String,
75}
76
77impl<F> fmt::Debug for Client<F>
78{
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        write!(f, "Client {{ base_path: {} }}", self.base_path)
81    }
82}
83
84impl<F> Clone for Client<F>
85{
86    fn clone(&self) -> Self {
87        Client {
88            client_service: self.client_service.clone(),
89            base_path: self.base_path.clone(),
90        }
91    }
92}
93
94impl Client<hyper::client::ResponseFuture>
95{
96    /// Create a client with a custom implementation of hyper::client::Connect.
97    ///
98    /// Intended for use with custom implementations of connect for e.g. protocol logging
99    /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection,
100    /// this function should be used in conjunction with `swagger::Connector::builder()`.
101    ///
102    /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https`
103    /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer.
104    ///
105    /// # Arguments
106    ///
107    /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com"
108    /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")`
109    /// * `connector` - Implementation of `hyper::client::Connect` to use for the client
110    pub fn try_new_with_connector<C>(
111        base_path: &str,
112        protocol: Option<&'static str>,
113        connector: C,
114    ) -> Result<Self, ClientInitError> where
115      C: hyper::client::connect::Connect + 'static,
116      C::Transport: 'static,
117      C::Future: 'static,
118    {
119        let client_service = Box::new(hyper::client::Client::builder().build(connector));
120
121        Ok(Client {
122            client_service: Arc::new(client_service),
123            base_path: into_base_path(base_path, protocol)?,
124        })
125    }
126
127    /// Create an HTTP client.
128    ///
129    /// # Arguments
130    /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com"
131    pub fn try_new_http(
132        base_path: &str,
133    ) -> Result<Self, ClientInitError> {
134        let http_connector = Connector::builder().build();
135
136        Self::try_new_with_connector(base_path, Some("http"), http_connector)
137    }
138
139    /// Create a client with a TLS connection to the server
140    ///
141    /// # Arguments
142    /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com"
143    pub fn try_new_https(base_path: &str) -> Result<Self, ClientInitError>
144    {
145        let https_connector = Connector::builder()
146            .https()
147            .build()
148            .map_err(|e| ClientInitError::SslError(e))?;
149        Self::try_new_with_connector(base_path, Some("https"), https_connector)
150    }
151
152    /// Create a client with a TLS connection to the server using a pinned certificate
153    ///
154    /// # Arguments
155    /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com"
156    /// * `ca_certificate` - Path to CA certificate used to authenticate the server
157    #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
158    pub fn try_new_https_pinned<CA>(
159        base_path: &str,
160        ca_certificate: CA,
161    ) -> Result<Self, ClientInitError>
162    where
163        CA: AsRef<Path>,
164    {
165        let https_connector = Connector::builder()
166            .https()
167            .pin_server_certificate(ca_certificate)
168            .build()
169            .map_err(|e| ClientInitError::SslError(e))?;
170        Self::try_new_with_connector(base_path, Some("https"), https_connector)
171    }
172
173    /// Create a client with a mutually authenticated TLS connection to the server.
174    ///
175    /// # Arguments
176    /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com"
177    /// * `ca_certificate` - Path to CA certificate used to authenticate the server
178    /// * `client_key` - Path to the client private key
179    /// * `client_certificate` - Path to the client's public certificate associated with the private key
180    #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
181    pub fn try_new_https_mutual<CA, K, D>(
182        base_path: &str,
183        ca_certificate: CA,
184        client_key: K,
185        client_certificate: D,
186    ) -> Result<Self, ClientInitError>
187    where
188        CA: AsRef<Path>,
189        K: AsRef<Path>,
190        D: AsRef<Path>,
191    {
192        let https_connector = Connector::builder()
193            .https()
194            .pin_server_certificate(ca_certificate)
195            .client_authentication(client_key, client_certificate)
196            .build()
197            .map_err(|e| ClientInitError::SslError(e))?;
198        Self::try_new_with_connector(base_path, Some("https"), https_connector)
199    }
200}
201
202impl<F> Client<F>
203{
204    /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service`
205    ///
206    /// This allows adding custom wrappers around the underlying transport, for example for logging.
207    pub fn try_new_with_client_service(
208        client_service: Arc<Box<dyn Service<ReqBody=Body, Future=F> + Send + Sync>>,
209        base_path: &str,
210    ) -> Result<Self, ClientInitError> {
211        Ok(Client {
212            client_service: client_service,
213            base_path: into_base_path(base_path, None)?,
214        })
215    }
216}
217
218/// Error type failing to create a Client
219#[derive(Debug)]
220pub enum ClientInitError {
221    /// Invalid URL Scheme
222    InvalidScheme,
223
224    /// Invalid URI
225    InvalidUri(hyper::http::uri::InvalidUri),
226
227    /// Missing Hostname
228    MissingHost,
229
230    /// SSL Connection Error
231    #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))]
232    SslError(native_tls::Error),
233
234    /// SSL Connection Error
235    #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))]
236    SslError(openssl::error::ErrorStack),
237}
238
239impl From<hyper::http::uri::InvalidUri> for ClientInitError {
240    fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError {
241        ClientInitError::InvalidUri(err)
242    }
243}
244
245impl fmt::Display for ClientInitError {
246    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247        let s: &dyn fmt::Debug = self;
248        s.fmt(f)
249    }
250}
251
252impl error::Error for ClientInitError {
253    fn description(&self) -> &str {
254        "Failed to produce a hyper client."
255    }
256}
257
258impl<C, F> Api<C> for Client<F> where
259    C: Has<XSpanIdString> ,
260    F: Future<Item=Response<Body>, Error=hyper::Error> + Send + 'static
261{
262    fn i2c_bus_api(
263        &self,
264        context: &C) -> Box<dyn Future<Item=I2cBusApiResponse, Error=ApiError> + Send>
265    {
266        let mut uri = format!(
267            "{}/i2c/api",
268            self.base_path
269        );
270
271        // Query parameters
272        let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
273        let query_string_str = query_string.finish();
274        if !query_string_str.is_empty() {
275            uri += "?";
276            uri += &query_string_str;
277        }
278
279        let uri = match Uri::from_str(&uri) {
280            Ok(uri) => uri,
281            Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
282        };
283
284        let mut request = match hyper::Request::builder()
285            .method("GET")
286            .uri(uri)
287            .body(Body::empty()) {
288                Ok(req) => req,
289                Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
290        };
291
292        let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
293        request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
294            Ok(h) => h,
295            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
296        });
297
298        Box::new(self.client_service.request(request)
299                             .map_err(|e| ApiError(format!("No response received: {}", e)))
300                             .and_then(|mut response| {
301            match response.status().as_u16() {
302                200 => {
303                    let body = response.into_body();
304                    Box::new(
305                        body
306                        .concat2()
307                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
308                        .and_then(|body|
309                        str::from_utf8(&body)
310                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
311                                             .and_then(|body|
312                                                 Ok(body.to_string())
313                                             )
314                                 )
315                        .map(move |body| {
316                            I2cBusApiResponse::OK
317                            (body)
318                        })
319                    ) as Box<dyn Future<Item=_, Error=_> + Send>
320                },
321                404 => {
322                    let body = response.into_body();
323                    Box::new(
324                        body
325                        .concat2()
326                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
327                        .and_then(|body|
328                        str::from_utf8(&body)
329                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
330                                             .and_then(|body|
331                                                 Ok(body.to_string())
332                                             )
333                                 )
334                        .map(move |body| {
335                            I2cBusApiResponse::FileNotFound
336                            (body)
337                        })
338                    ) as Box<dyn Future<Item=_, Error=_> + Send>
339                },
340                code => {
341                    let headers = response.headers().clone();
342                    Box::new(response.into_body()
343                            .take(100)
344                            .concat2()
345                            .then(move |body|
346                                future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
347                                    code,
348                                    headers,
349                                    match body {
350                                        Ok(ref body) => match str::from_utf8(body) {
351                                            Ok(body) => Cow::from(body),
352                                            Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
353                                        },
354                                        Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
355                                    })))
356                            )
357                    ) as Box<dyn Future<Item=_, Error=_> + Send>
358                }
359            }
360        }))
361    }
362
363    fn i2c_bus_list(
364        &self,
365        context: &C) -> Box<dyn Future<Item=I2cBusListResponse, Error=ApiError> + Send>
366    {
367        let mut uri = format!(
368            "{}/i2c/buslist",
369            self.base_path
370        );
371
372        // Query parameters
373        let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
374        let query_string_str = query_string.finish();
375        if !query_string_str.is_empty() {
376            uri += "?";
377            uri += &query_string_str;
378        }
379
380        let uri = match Uri::from_str(&uri) {
381            Ok(uri) => uri,
382            Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
383        };
384
385        let mut request = match hyper::Request::builder()
386            .method("GET")
387            .uri(uri)
388            .body(Body::empty()) {
389                Ok(req) => req,
390                Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
391        };
392
393        let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
394        request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
395            Ok(h) => h,
396            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
397        });
398
399        Box::new(self.client_service.request(request)
400                             .map_err(|e| ApiError(format!("No response received: {}", e)))
401                             .and_then(|mut response| {
402            match response.status().as_u16() {
403                200 => {
404                    let body = response.into_body();
405                    Box::new(
406                        body
407                        .concat2()
408                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
409                        .and_then(|body|
410                        str::from_utf8(&body)
411                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
412                                             .and_then(|body|
413                                                 serde_json::from_str::<Vec<models::I2cBusList>>(body)
414                                                     .map_err(|e| e.into())
415                                             )
416                                 )
417                        .map(move |body| {
418                            I2cBusListResponse::OK
419                            (body)
420                        })
421                    ) as Box<dyn Future<Item=_, Error=_> + Send>
422                },
423                code => {
424                    let headers = response.headers().clone();
425                    Box::new(response.into_body()
426                            .take(100)
427                            .concat2()
428                            .then(move |body|
429                                future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
430                                    code,
431                                    headers,
432                                    match body {
433                                        Ok(ref body) => match str::from_utf8(body) {
434                                            Ok(body) => Cow::from(body),
435                                            Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
436                                        },
437                                        Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
438                                    })))
439                            )
440                    ) as Box<dyn Future<Item=_, Error=_> + Send>
441                }
442            }
443        }))
444    }
445
446    fn i2c_bus_read_byte(
447        &self,
448        param_bus_id: i32,
449        param_addr: i32,
450        context: &C) -> Box<dyn Future<Item=I2cBusReadByteResponse, Error=ApiError> + Send>
451    {
452        let mut uri = format!(
453            "{}/i2c/{bus_id}/read/byte/{addr}",
454            self.base_path
455            ,bus_id=utf8_percent_encode(&param_bus_id.to_string(), ID_ENCODE_SET)
456            ,addr=utf8_percent_encode(&param_addr.to_string(), ID_ENCODE_SET)
457        );
458
459        // Query parameters
460        let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
461        let query_string_str = query_string.finish();
462        if !query_string_str.is_empty() {
463            uri += "?";
464            uri += &query_string_str;
465        }
466
467        let uri = match Uri::from_str(&uri) {
468            Ok(uri) => uri,
469            Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
470        };
471
472        let mut request = match hyper::Request::builder()
473            .method("GET")
474            .uri(uri)
475            .body(Body::empty()) {
476                Ok(req) => req,
477                Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
478        };
479
480        let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
481        request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
482            Ok(h) => h,
483            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
484        });
485
486        Box::new(self.client_service.request(request)
487                             .map_err(|e| ApiError(format!("No response received: {}", e)))
488                             .and_then(|mut response| {
489            match response.status().as_u16() {
490                200 => {
491                    let body = response.into_body();
492                    Box::new(
493                        body
494                        .concat2()
495                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
496                        .and_then(|body|
497                        str::from_utf8(&body)
498                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
499                                             .and_then(|body|
500                                                 serde_json::from_str::<models::I2cBusRead>(body)
501                                                     .map_err(|e| e.into())
502                                             )
503                                 )
504                        .map(move |body| {
505                            I2cBusReadByteResponse::OK
506                            (body)
507                        })
508                    ) as Box<dyn Future<Item=_, Error=_> + Send>
509                },
510                400 => {
511                    let body = response.into_body();
512                    Box::new(
513                        body
514                        .concat2()
515                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
516                        .and_then(|body|
517                        str::from_utf8(&body)
518                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
519                                             .and_then(|body|
520                                                 serde_json::from_str::<models::I2cBusArg>(body)
521                                                     .map_err(|e| e.into())
522                                             )
523                                 )
524                        .map(move |body| {
525                            I2cBusReadByteResponse::BadRequest
526                            (body)
527                        })
528                    ) as Box<dyn Future<Item=_, Error=_> + Send>
529                },
530                502 => {
531                    let body = response.into_body();
532                    Box::new(
533                        body
534                        .concat2()
535                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
536                        .and_then(|body|
537                        str::from_utf8(&body)
538                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
539                                             .and_then(|body|
540                                                 serde_json::from_str::<models::I2cBusError>(body)
541                                                     .map_err(|e| e.into())
542                                             )
543                                 )
544                        .map(move |body| {
545                            I2cBusReadByteResponse::TransactionFailed
546                            (body)
547                        })
548                    ) as Box<dyn Future<Item=_, Error=_> + Send>
549                },
550                code => {
551                    let headers = response.headers().clone();
552                    Box::new(response.into_body()
553                            .take(100)
554                            .concat2()
555                            .then(move |body|
556                                future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
557                                    code,
558                                    headers,
559                                    match body {
560                                        Ok(ref body) => match str::from_utf8(body) {
561                                            Ok(body) => Cow::from(body),
562                                            Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
563                                        },
564                                        Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
565                                    })))
566                            )
567                    ) as Box<dyn Future<Item=_, Error=_> + Send>
568                }
569            }
570        }))
571    }
572
573    fn i2c_bus_read_bytes(
574        &self,
575        param_bus_id: i32,
576        param_addr: i32,
577        param_num_bytes: i32,
578        context: &C) -> Box<dyn Future<Item=I2cBusReadBytesResponse, Error=ApiError> + Send>
579    {
580        let mut uri = format!(
581            "{}/i2c/{bus_id}/read/bytes/{addr}/{num_bytes}",
582            self.base_path
583            ,bus_id=utf8_percent_encode(&param_bus_id.to_string(), ID_ENCODE_SET)
584            ,addr=utf8_percent_encode(&param_addr.to_string(), ID_ENCODE_SET)
585            ,num_bytes=utf8_percent_encode(&param_num_bytes.to_string(), ID_ENCODE_SET)
586        );
587
588        // Query parameters
589        let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
590        let query_string_str = query_string.finish();
591        if !query_string_str.is_empty() {
592            uri += "?";
593            uri += &query_string_str;
594        }
595
596        let uri = match Uri::from_str(&uri) {
597            Ok(uri) => uri,
598            Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
599        };
600
601        let mut request = match hyper::Request::builder()
602            .method("GET")
603            .uri(uri)
604            .body(Body::empty()) {
605                Ok(req) => req,
606                Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
607        };
608
609        let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
610        request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
611            Ok(h) => h,
612            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
613        });
614
615        Box::new(self.client_service.request(request)
616                             .map_err(|e| ApiError(format!("No response received: {}", e)))
617                             .and_then(|mut response| {
618            match response.status().as_u16() {
619                200 => {
620                    let body = response.into_body();
621                    Box::new(
622                        body
623                        .concat2()
624                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
625                        .and_then(|body|
626                        str::from_utf8(&body)
627                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
628                                             .and_then(|body|
629                                                 serde_json::from_str::<models::I2cBusRead>(body)
630                                                     .map_err(|e| e.into())
631                                             )
632                                 )
633                        .map(move |body| {
634                            I2cBusReadBytesResponse::OK
635                            (body)
636                        })
637                    ) as Box<dyn Future<Item=_, Error=_> + Send>
638                },
639                400 => {
640                    let body = response.into_body();
641                    Box::new(
642                        body
643                        .concat2()
644                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
645                        .and_then(|body|
646                        str::from_utf8(&body)
647                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
648                                             .and_then(|body|
649                                                 serde_json::from_str::<models::I2cBusArg>(body)
650                                                     .map_err(|e| e.into())
651                                             )
652                                 )
653                        .map(move |body| {
654                            I2cBusReadBytesResponse::BadRequest
655                            (body)
656                        })
657                    ) as Box<dyn Future<Item=_, Error=_> + Send>
658                },
659                502 => {
660                    let body = response.into_body();
661                    Box::new(
662                        body
663                        .concat2()
664                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
665                        .and_then(|body|
666                        str::from_utf8(&body)
667                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
668                                             .and_then(|body|
669                                                 serde_json::from_str::<models::I2cBusError>(body)
670                                                     .map_err(|e| e.into())
671                                             )
672                                 )
673                        .map(move |body| {
674                            I2cBusReadBytesResponse::TransactionFailed
675                            (body)
676                        })
677                    ) as Box<dyn Future<Item=_, Error=_> + Send>
678                },
679                code => {
680                    let headers = response.headers().clone();
681                    Box::new(response.into_body()
682                            .take(100)
683                            .concat2()
684                            .then(move |body|
685                                future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
686                                    code,
687                                    headers,
688                                    match body {
689                                        Ok(ref body) => match str::from_utf8(body) {
690                                            Ok(body) => Cow::from(body),
691                                            Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
692                                        },
693                                        Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
694                                    })))
695                            )
696                    ) as Box<dyn Future<Item=_, Error=_> + Send>
697                }
698            }
699        }))
700    }
701
702    fn i2c_bus_read_reg(
703        &self,
704        param_bus_id: i32,
705        param_addr: i32,
706        param_reg: i32,
707        param_num_bytes: i32,
708        context: &C) -> Box<dyn Future<Item=I2cBusReadRegResponse, Error=ApiError> + Send>
709    {
710        let mut uri = format!(
711            "{}/i2c/{bus_id}/read/reg/{addr}/{reg}/{num_bytes}",
712            self.base_path
713            ,bus_id=utf8_percent_encode(&param_bus_id.to_string(), ID_ENCODE_SET)
714            ,addr=utf8_percent_encode(&param_addr.to_string(), ID_ENCODE_SET)
715            ,reg=utf8_percent_encode(&param_reg.to_string(), ID_ENCODE_SET)
716            ,num_bytes=utf8_percent_encode(&param_num_bytes.to_string(), ID_ENCODE_SET)
717        );
718
719        // Query parameters
720        let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
721        let query_string_str = query_string.finish();
722        if !query_string_str.is_empty() {
723            uri += "?";
724            uri += &query_string_str;
725        }
726
727        let uri = match Uri::from_str(&uri) {
728            Ok(uri) => uri,
729            Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
730        };
731
732        let mut request = match hyper::Request::builder()
733            .method("GET")
734            .uri(uri)
735            .body(Body::empty()) {
736                Ok(req) => req,
737                Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
738        };
739
740        let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
741        request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
742            Ok(h) => h,
743            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
744        });
745
746        Box::new(self.client_service.request(request)
747                             .map_err(|e| ApiError(format!("No response received: {}", e)))
748                             .and_then(|mut response| {
749            match response.status().as_u16() {
750                200 => {
751                    let body = response.into_body();
752                    Box::new(
753                        body
754                        .concat2()
755                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
756                        .and_then(|body|
757                        str::from_utf8(&body)
758                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
759                                             .and_then(|body|
760                                                 serde_json::from_str::<models::I2cBusRead>(body)
761                                                     .map_err(|e| e.into())
762                                             )
763                                 )
764                        .map(move |body| {
765                            I2cBusReadRegResponse::OK
766                            (body)
767                        })
768                    ) as Box<dyn Future<Item=_, Error=_> + Send>
769                },
770                400 => {
771                    let body = response.into_body();
772                    Box::new(
773                        body
774                        .concat2()
775                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
776                        .and_then(|body|
777                        str::from_utf8(&body)
778                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
779                                             .and_then(|body|
780                                                 serde_json::from_str::<models::I2cBusArg>(body)
781                                                     .map_err(|e| e.into())
782                                             )
783                                 )
784                        .map(move |body| {
785                            I2cBusReadRegResponse::BadRequest
786                            (body)
787                        })
788                    ) as Box<dyn Future<Item=_, Error=_> + Send>
789                },
790                502 => {
791                    let body = response.into_body();
792                    Box::new(
793                        body
794                        .concat2()
795                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
796                        .and_then(|body|
797                        str::from_utf8(&body)
798                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
799                                             .and_then(|body|
800                                                 serde_json::from_str::<models::I2cBusError>(body)
801                                                     .map_err(|e| e.into())
802                                             )
803                                 )
804                        .map(move |body| {
805                            I2cBusReadRegResponse::TransactionFailed
806                            (body)
807                        })
808                    ) as Box<dyn Future<Item=_, Error=_> + Send>
809                },
810                code => {
811                    let headers = response.headers().clone();
812                    Box::new(response.into_body()
813                            .take(100)
814                            .concat2()
815                            .then(move |body|
816                                future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
817                                    code,
818                                    headers,
819                                    match body {
820                                        Ok(ref body) => match str::from_utf8(body) {
821                                            Ok(body) => Cow::from(body),
822                                            Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
823                                        },
824                                        Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
825                                    })))
826                            )
827                    ) as Box<dyn Future<Item=_, Error=_> + Send>
828                }
829            }
830        }))
831    }
832
833    fn i2c_bus_write_byte(
834        &self,
835        param_bus_id: i32,
836        param_addr: i32,
837        param_value: i32,
838        context: &C) -> Box<dyn Future<Item=I2cBusWriteByteResponse, Error=ApiError> + Send>
839    {
840        let mut uri = format!(
841            "{}/i2c/{bus_id}/write/byte/{addr}/{value}",
842            self.base_path
843            ,bus_id=utf8_percent_encode(&param_bus_id.to_string(), ID_ENCODE_SET)
844            ,addr=utf8_percent_encode(&param_addr.to_string(), ID_ENCODE_SET)
845            ,value=utf8_percent_encode(&param_value.to_string(), ID_ENCODE_SET)
846        );
847
848        // Query parameters
849        let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
850        let query_string_str = query_string.finish();
851        if !query_string_str.is_empty() {
852            uri += "?";
853            uri += &query_string_str;
854        }
855
856        let uri = match Uri::from_str(&uri) {
857            Ok(uri) => uri,
858            Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
859        };
860
861        let mut request = match hyper::Request::builder()
862            .method("POST")
863            .uri(uri)
864            .body(Body::empty()) {
865                Ok(req) => req,
866                Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
867        };
868
869        let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
870        request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
871            Ok(h) => h,
872            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
873        });
874
875        Box::new(self.client_service.request(request)
876                             .map_err(|e| ApiError(format!("No response received: {}", e)))
877                             .and_then(|mut response| {
878            match response.status().as_u16() {
879                200 => {
880                    let body = response.into_body();
881                    Box::new(
882                        body
883                        .concat2()
884                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
885                        .and_then(|body|
886                        str::from_utf8(&body)
887                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
888                                             .and_then(|body|
889                                                 serde_json::from_str::<models::I2cBusOk>(body)
890                                                     .map_err(|e| e.into())
891                                             )
892                                 )
893                        .map(move |body| {
894                            I2cBusWriteByteResponse::OK
895                            (body)
896                        })
897                    ) as Box<dyn Future<Item=_, Error=_> + Send>
898                },
899                400 => {
900                    let body = response.into_body();
901                    Box::new(
902                        body
903                        .concat2()
904                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
905                        .and_then(|body|
906                        str::from_utf8(&body)
907                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
908                                             .and_then(|body|
909                                                 serde_json::from_str::<models::I2cBusArg>(body)
910                                                     .map_err(|e| e.into())
911                                             )
912                                 )
913                        .map(move |body| {
914                            I2cBusWriteByteResponse::BadRequest
915                            (body)
916                        })
917                    ) as Box<dyn Future<Item=_, Error=_> + Send>
918                },
919                502 => {
920                    let body = response.into_body();
921                    Box::new(
922                        body
923                        .concat2()
924                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
925                        .and_then(|body|
926                        str::from_utf8(&body)
927                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
928                                             .and_then(|body|
929                                                 serde_json::from_str::<models::I2cBusError>(body)
930                                                     .map_err(|e| e.into())
931                                             )
932                                 )
933                        .map(move |body| {
934                            I2cBusWriteByteResponse::TransactionFailed
935                            (body)
936                        })
937                    ) as Box<dyn Future<Item=_, Error=_> + Send>
938                },
939                code => {
940                    let headers = response.headers().clone();
941                    Box::new(response.into_body()
942                            .take(100)
943                            .concat2()
944                            .then(move |body|
945                                future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
946                                    code,
947                                    headers,
948                                    match body {
949                                        Ok(ref body) => match str::from_utf8(body) {
950                                            Ok(body) => Cow::from(body),
951                                            Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
952                                        },
953                                        Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
954                                    })))
955                            )
956                    ) as Box<dyn Future<Item=_, Error=_> + Send>
957                }
958            }
959        }))
960    }
961
962    fn i2c_bus_write_byte_reg(
963        &self,
964        param_bus_id: i32,
965        param_addr: i32,
966        param_reg: i32,
967        param_value: i32,
968        context: &C) -> Box<dyn Future<Item=I2cBusWriteByteRegResponse, Error=ApiError> + Send>
969    {
970        let mut uri = format!(
971            "{}/i2c/{bus_id}/write/byte/reg/{addr}/{reg}/{value}",
972            self.base_path
973            ,bus_id=utf8_percent_encode(&param_bus_id.to_string(), ID_ENCODE_SET)
974            ,addr=utf8_percent_encode(&param_addr.to_string(), ID_ENCODE_SET)
975            ,reg=utf8_percent_encode(&param_reg.to_string(), ID_ENCODE_SET)
976            ,value=utf8_percent_encode(&param_value.to_string(), ID_ENCODE_SET)
977        );
978
979        // Query parameters
980        let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
981        let query_string_str = query_string.finish();
982        if !query_string_str.is_empty() {
983            uri += "?";
984            uri += &query_string_str;
985        }
986
987        let uri = match Uri::from_str(&uri) {
988            Ok(uri) => uri,
989            Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
990        };
991
992        let mut request = match hyper::Request::builder()
993            .method("POST")
994            .uri(uri)
995            .body(Body::empty()) {
996                Ok(req) => req,
997                Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
998        };
999
1000        let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
1001        request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
1002            Ok(h) => h,
1003            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
1004        });
1005
1006        Box::new(self.client_service.request(request)
1007                             .map_err(|e| ApiError(format!("No response received: {}", e)))
1008                             .and_then(|mut response| {
1009            match response.status().as_u16() {
1010                200 => {
1011                    let body = response.into_body();
1012                    Box::new(
1013                        body
1014                        .concat2()
1015                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1016                        .and_then(|body|
1017                        str::from_utf8(&body)
1018                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
1019                                             .and_then(|body|
1020                                                 serde_json::from_str::<models::I2cBusOk>(body)
1021                                                     .map_err(|e| e.into())
1022                                             )
1023                                 )
1024                        .map(move |body| {
1025                            I2cBusWriteByteRegResponse::OK
1026                            (body)
1027                        })
1028                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1029                },
1030                400 => {
1031                    let body = response.into_body();
1032                    Box::new(
1033                        body
1034                        .concat2()
1035                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1036                        .and_then(|body|
1037                        str::from_utf8(&body)
1038                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
1039                                             .and_then(|body|
1040                                                 serde_json::from_str::<models::I2cBusArg>(body)
1041                                                     .map_err(|e| e.into())
1042                                             )
1043                                 )
1044                        .map(move |body| {
1045                            I2cBusWriteByteRegResponse::BadRequest
1046                            (body)
1047                        })
1048                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1049                },
1050                502 => {
1051                    let body = response.into_body();
1052                    Box::new(
1053                        body
1054                        .concat2()
1055                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1056                        .and_then(|body|
1057                        str::from_utf8(&body)
1058                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
1059                                             .and_then(|body|
1060                                                 serde_json::from_str::<models::I2cBusError>(body)
1061                                                     .map_err(|e| e.into())
1062                                             )
1063                                 )
1064                        .map(move |body| {
1065                            I2cBusWriteByteRegResponse::TransactionFailed
1066                            (body)
1067                        })
1068                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1069                },
1070                code => {
1071                    let headers = response.headers().clone();
1072                    Box::new(response.into_body()
1073                            .take(100)
1074                            .concat2()
1075                            .then(move |body|
1076                                future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
1077                                    code,
1078                                    headers,
1079                                    match body {
1080                                        Ok(ref body) => match str::from_utf8(body) {
1081                                            Ok(body) => Cow::from(body),
1082                                            Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
1083                                        },
1084                                        Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
1085                                    })))
1086                            )
1087                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1088                }
1089            }
1090        }))
1091    }
1092
1093    fn i2c_bus_write_bytes(
1094        &self,
1095        param_bus_id: i32,
1096        param_addr: i32,
1097        param_values: models::Values,
1098        context: &C) -> Box<dyn Future<Item=I2cBusWriteBytesResponse, Error=ApiError> + Send>
1099    {
1100        let mut uri = format!(
1101            "{}/i2c/{bus_id}/write/bytes/{addr}",
1102            self.base_path
1103            ,bus_id=utf8_percent_encode(&param_bus_id.to_string(), ID_ENCODE_SET)
1104            ,addr=utf8_percent_encode(&param_addr.to_string(), ID_ENCODE_SET)
1105        );
1106
1107        // Query parameters
1108        let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
1109        let query_string_str = query_string.finish();
1110        if !query_string_str.is_empty() {
1111            uri += "?";
1112            uri += &query_string_str;
1113        }
1114
1115        let uri = match Uri::from_str(&uri) {
1116            Ok(uri) => uri,
1117            Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
1118        };
1119
1120        let mut request = match hyper::Request::builder()
1121            .method("POST")
1122            .uri(uri)
1123            .body(Body::empty()) {
1124                Ok(req) => req,
1125                Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
1126        };
1127
1128        let body = serde_json::to_string(&param_values).expect("impossible to fail to serialize");
1129                *request.body_mut() = Body::from(body);
1130
1131        let header = "application/json";
1132        request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) {
1133            Ok(h) => h,
1134            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
1135        });
1136        let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
1137        request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
1138            Ok(h) => h,
1139            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
1140        });
1141
1142        Box::new(self.client_service.request(request)
1143                             .map_err(|e| ApiError(format!("No response received: {}", e)))
1144                             .and_then(|mut response| {
1145            match response.status().as_u16() {
1146                200 => {
1147                    let body = response.into_body();
1148                    Box::new(
1149                        body
1150                        .concat2()
1151                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1152                        .and_then(|body|
1153                        str::from_utf8(&body)
1154                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
1155                                             .and_then(|body|
1156                                                 serde_json::from_str::<models::I2cBusOk>(body)
1157                                                     .map_err(|e| e.into())
1158                                             )
1159                                 )
1160                        .map(move |body| {
1161                            I2cBusWriteBytesResponse::OK
1162                            (body)
1163                        })
1164                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1165                },
1166                400 => {
1167                    let body = response.into_body();
1168                    Box::new(
1169                        body
1170                        .concat2()
1171                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1172                        .and_then(|body|
1173                        str::from_utf8(&body)
1174                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
1175                                             .and_then(|body|
1176                                                 serde_json::from_str::<models::I2cBusArg>(body)
1177                                                     .map_err(|e| e.into())
1178                                             )
1179                                 )
1180                        .map(move |body| {
1181                            I2cBusWriteBytesResponse::BadRequest
1182                            (body)
1183                        })
1184                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1185                },
1186                502 => {
1187                    let body = response.into_body();
1188                    Box::new(
1189                        body
1190                        .concat2()
1191                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1192                        .and_then(|body|
1193                        str::from_utf8(&body)
1194                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
1195                                             .and_then(|body|
1196                                                 serde_json::from_str::<models::I2cBusError>(body)
1197                                                     .map_err(|e| e.into())
1198                                             )
1199                                 )
1200                        .map(move |body| {
1201                            I2cBusWriteBytesResponse::TransactionFailed
1202                            (body)
1203                        })
1204                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1205                },
1206                code => {
1207                    let headers = response.headers().clone();
1208                    Box::new(response.into_body()
1209                            .take(100)
1210                            .concat2()
1211                            .then(move |body|
1212                                future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
1213                                    code,
1214                                    headers,
1215                                    match body {
1216                                        Ok(ref body) => match str::from_utf8(body) {
1217                                            Ok(body) => Cow::from(body),
1218                                            Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
1219                                        },
1220                                        Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
1221                                    })))
1222                            )
1223                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1224                }
1225            }
1226        }))
1227    }
1228
1229    fn i2c_bus_write_bytes_reg(
1230        &self,
1231        param_bus_id: i32,
1232        param_addr: i32,
1233        param_reg: i32,
1234        param_values: models::Values,
1235        context: &C) -> Box<dyn Future<Item=I2cBusWriteBytesRegResponse, Error=ApiError> + Send>
1236    {
1237        let mut uri = format!(
1238            "{}/i2c/{bus_id}/write/bytes/reg/{addr}/{reg}",
1239            self.base_path
1240            ,bus_id=utf8_percent_encode(&param_bus_id.to_string(), ID_ENCODE_SET)
1241            ,addr=utf8_percent_encode(&param_addr.to_string(), ID_ENCODE_SET)
1242            ,reg=utf8_percent_encode(&param_reg.to_string(), ID_ENCODE_SET)
1243        );
1244
1245        // Query parameters
1246        let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
1247        let query_string_str = query_string.finish();
1248        if !query_string_str.is_empty() {
1249            uri += "?";
1250            uri += &query_string_str;
1251        }
1252
1253        let uri = match Uri::from_str(&uri) {
1254            Ok(uri) => uri,
1255            Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
1256        };
1257
1258        let mut request = match hyper::Request::builder()
1259            .method("POST")
1260            .uri(uri)
1261            .body(Body::empty()) {
1262                Ok(req) => req,
1263                Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
1264        };
1265
1266        let body = serde_json::to_string(&param_values).expect("impossible to fail to serialize");
1267
1268                *request.body_mut() = Body::from(body);
1269
1270        let header = "application/json";
1271        request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) {
1272            Ok(h) => h,
1273            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
1274        });
1275
1276        let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
1277        request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
1278            Ok(h) => h,
1279            Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
1280        });
1281
1282        Box::new(self.client_service.request(request)
1283                             .map_err(|e| ApiError(format!("No response received: {}", e)))
1284                             .and_then(|mut response| {
1285            match response.status().as_u16() {
1286                200 => {
1287                    let body = response.into_body();
1288                    Box::new(
1289                        body
1290                        .concat2()
1291                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1292                        .and_then(|body|
1293                        str::from_utf8(&body)
1294                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
1295                                             .and_then(|body|
1296                                                 serde_json::from_str::<models::I2cBusOk>(body)
1297                                                     .map_err(|e| e.into())
1298                                             )
1299                                 )
1300                        .map(move |body| {
1301                            I2cBusWriteBytesRegResponse::OK
1302                            (body)
1303                        })
1304                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1305                },
1306                400 => {
1307                    let body = response.into_body();
1308                    Box::new(
1309                        body
1310                        .concat2()
1311                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1312                        .and_then(|body|
1313                        str::from_utf8(&body)
1314                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
1315                                             .and_then(|body|
1316                                                 serde_json::from_str::<models::I2cBusArg>(body)
1317                                                     .map_err(|e| e.into())
1318                                             )
1319                                 )
1320                        .map(move |body| {
1321                            I2cBusWriteBytesRegResponse::BadRequest
1322                            (body)
1323                        })
1324                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1325                },
1326                502 => {
1327                    let body = response.into_body();
1328                    Box::new(
1329                        body
1330                        .concat2()
1331                        .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
1332                        .and_then(|body|
1333                        str::from_utf8(&body)
1334                                             .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
1335                                             .and_then(|body|
1336                                                 serde_json::from_str::<models::I2cBusError>(body)
1337                                                     .map_err(|e| e.into())
1338                                             )
1339                                 )
1340                        .map(move |body| {
1341                            I2cBusWriteBytesRegResponse::TransactionFailed
1342                            (body)
1343                        })
1344                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1345                },
1346                code => {
1347                    let headers = response.headers().clone();
1348                    Box::new(response.into_body()
1349                            .take(100)
1350                            .concat2()
1351                            .then(move |body|
1352                                future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
1353                                    code,
1354                                    headers,
1355                                    match body {
1356                                        Ok(ref body) => match str::from_utf8(body) {
1357                                            Ok(body) => Cow::from(body),
1358                                            Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
1359                                        },
1360                                        Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
1361                                    })))
1362                            )
1363                    ) as Box<dyn Future<Item=_, Error=_> + Send>
1364                }
1365            }
1366        }))
1367    }
1368
1369}
1370
1371#[allow(dead_code)]
1372pub mod remote;