diff options
Diffstat (limited to 'rust/fatcat-api/src')
| -rw-r--r-- | rust/fatcat-api/src/client/mod.rs | 2573 | ||||
| -rw-r--r-- | rust/fatcat-api/src/lib.rs | 599 | ||||
| -rw-r--r-- | rust/fatcat-api/src/mimetypes.rs | 313 | ||||
| -rw-r--r-- | rust/fatcat-api/src/models.rs | 392 | ||||
| -rw-r--r-- | rust/fatcat-api/src/server/auth.rs | 93 | ||||
| -rw-r--r-- | rust/fatcat-api/src/server/mod.rs | 2485 | 
6 files changed, 6455 insertions, 0 deletions
diff --git a/rust/fatcat-api/src/client/mod.rs b/rust/fatcat-api/src/client/mod.rs new file mode 100644 index 00000000..361fd390 --- /dev/null +++ b/rust/fatcat-api/src/client/mod.rs @@ -0,0 +1,2573 @@ +#![allow(unused_extern_crates)] +extern crate chrono; +extern crate hyper_tls; +extern crate mime; +extern crate native_tls; +extern crate openssl; +extern crate tokio_core; +extern crate url; + +use self::tokio_core::reactor::Handle; +use self::url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET}; +use futures; +use futures::{Future, Stream}; +use futures::{future, stream}; +use hyper; +use hyper::Uri; +use hyper::header::{ContentType, Headers}; +use std::borrow::Cow; +use std::error; +use std::fmt; +use std::io::{Error, ErrorKind, Read}; +use std::path::Path; +use std::str; +use std::str::FromStr; +use std::sync::Arc; + +use mimetypes; + +use serde_json; + +#[allow(unused_imports)] +use std::collections::{BTreeMap, HashMap}; +#[allow(unused_imports)] +use swagger; + +use swagger::{ApiError, Context, XSpanId}; + +use models; +use {Api, ContainerIdGetResponse, ContainerLookupGetResponse, ContainerPostResponse, +     CreatorIdGetResponse, CreatorLookupGetResponse, CreatorPostResponse, +     EditgroupIdAcceptPostResponse, EditgroupIdGetResponse, EditgroupPostResponse, +     EditorUsernameChangelogGetResponse, EditorUsernameGetResponse, FileIdGetResponse, +     FileLookupGetResponse, FilePostResponse, ReleaseIdGetResponse, ReleaseLookupGetResponse, +     ReleasePostResponse, WorkIdGetResponse, WorkPostResponse}; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path( +    input: &str, +    correct_scheme: Option<&'static str>, +) -> Result<String, ClientInitError> { +    // First convert to Uri, since a base path is a subset of Uri. +    let uri = Uri::from_str(input)?; + +    let scheme = uri.scheme().ok_or(ClientInitError::InvalidScheme)?; + +    // Check the scheme if necessary +    if let Some(correct_scheme) = correct_scheme { +        if scheme != correct_scheme { +            return Err(ClientInitError::InvalidScheme); +        } +    } + +    let host = uri.host().ok_or_else(|| ClientInitError::MissingHost)?; +    let port = uri.port().map(|x| format!(":{}", x)).unwrap_or_default(); +    Ok(format!("{}://{}{}", scheme, host, port)) +} + +/// A client that implements the API by making HTTP calls out to a server. +#[derive(Clone)] +pub struct Client { +    hyper_client: Arc< +        Fn( +                &Handle +            ) -> Box< +                hyper::client::Service< +                    Request = hyper::Request<hyper::Body>, +                    Response = hyper::Response, +                    Error = hyper::Error, +                    Future = hyper::client::FutureResponse, +                >, +            > +            + Sync +            + Send, +    >, +    handle: Arc<Handle>, +    base_path: String, +} + +impl fmt::Debug for Client { +    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +        write!(f, "Client {{ base_path: {} }}", self.base_path) +    } +} + +impl Client { +    /// Create an HTTP client. +    /// +    /// # Arguments +    /// * `handle` - tokio reactor handle to use for execution +    /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" +    pub fn try_new_http(handle: Handle, base_path: &str) -> Result<Client, ClientInitError> { +        let http_connector = swagger::http_connector(); +        Self::try_new_with_connector::<hyper::client::HttpConnector>( +            handle, +            base_path, +            Some("http"), +            http_connector, +        ) +    } + +    /// Create a client with a TLS connection to the server. +    /// +    /// # Arguments +    /// * `handle` - tokio reactor handle to use for execution +    /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" +    /// * `ca_certificate` - Path to CA certificate used to authenticate the server +    pub fn try_new_https<CA>( +        handle: Handle, +        base_path: &str, +        ca_certificate: CA, +    ) -> Result<Client, ClientInitError> +    where +        CA: AsRef<Path>, +    { +        let https_connector = swagger::https_connector(ca_certificate); +        Self::try_new_with_connector::<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>( +            handle, +            base_path, +            Some("https"), +            https_connector, +        ) +    } + +    /// Create a client with a mutually authenticated TLS connection to the server. +    /// +    /// # Arguments +    /// * `handle` - tokio reactor handle to use for execution +    /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" +    /// * `ca_certificate` - Path to CA certificate used to authenticate the server +    /// * `client_key` - Path to the client private key +    /// * `client_certificate` - Path to the client's public certificate associated with the private key +    pub fn try_new_https_mutual<CA, K, C, T>( +        handle: Handle, +        base_path: &str, +        ca_certificate: CA, +        client_key: K, +        client_certificate: C, +    ) -> Result<Client, ClientInitError> +    where +        CA: AsRef<Path>, +        K: AsRef<Path>, +        C: AsRef<Path>, +    { +        let https_connector = +            swagger::https_mutual_connector(ca_certificate, client_key, client_certificate); +        Self::try_new_with_connector::<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>( +            handle, +            base_path, +            Some("https"), +            https_connector, +        ) +    } + +    /// Create a client with a custom implementation of hyper::client::Connect. +    /// +    /// Intended for use with custom implementations of connect for e.g. protocol logging +    /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, +    /// this function should be used in conjunction with +    /// `swagger::{http_connector, https_connector, https_mutual_connector}`. +    /// +    /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` +    /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. +    /// +    /// # Arguments +    /// +    /// * `handle` - tokio reactor handle to use for execution +    /// * `base_path` - base path of the client API, i.e. "www.my-api-implementation.com" +    /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` +    /// * `connector_fn` - Function which returns an implementation of `hyper::client::Connect` +    pub fn try_new_with_connector<C>( +        handle: Handle, +        base_path: &str, +        protocol: Option<&'static str>, +        connector_fn: Box<Fn(&Handle) -> C + Send + Sync>, +    ) -> Result<Client, ClientInitError> +    where +        C: hyper::client::Connect + hyper::client::Service, +    { +        let hyper_client = { +            move |handle: &Handle| -> Box< +                hyper::client::Service< +                    Request = hyper::Request<hyper::Body>, +                    Response = hyper::Response, +                    Error = hyper::Error, +                    Future = hyper::client::FutureResponse, +                >, +            > { +                let connector = connector_fn(handle); +                Box::new( +                    hyper::Client::configure() +                        .connector(connector) +                        .build(handle), +                ) +            } +        }; + +        Ok(Client { +            hyper_client: Arc::new(hyper_client), +            handle: Arc::new(handle), +            base_path: into_base_path(base_path, protocol)?, +        }) +    } + +    /// Constructor for creating a `Client` by passing in a pre-made `hyper` client. +    /// +    /// One should avoid relying on this function if possible, since it adds a dependency on the underlying transport +    /// implementation, which it would be better to abstract away. Therefore, using this function may lead to a loss of +    /// code generality, which may make it harder to move the application to a serverless environment, for example. +    /// +    /// The reason for this function's existence is to support legacy test code, which did mocking at the hyper layer. +    /// This is not a recommended way to write new tests. If other reasons are found for using this function, they +    /// should be mentioned here. +    pub fn try_new_with_hyper_client( +        hyper_client: Arc< +            Fn( +                    &Handle +                ) -> Box< +                    hyper::client::Service< +                        Request = hyper::Request<hyper::Body>, +                        Response = hyper::Response, +                        Error = hyper::Error, +                        Future = hyper::client::FutureResponse, +                    >, +                > +                + Sync +                + Send, +        >, +        handle: Handle, +        base_path: &str, +    ) -> Result<Client, ClientInitError> { +        Ok(Client { +            hyper_client: hyper_client, +            handle: Arc::new(handle), +            base_path: into_base_path(base_path, None)?, +        }) +    } +} + +impl Api for Client { +    fn container_id_get( +        &self, +        param_id: String, +        context: &Context, +    ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>> { +        let uri = format!( +            "{}/v0/container/{id}", +            self.base_path, +            id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::ContainerEntity>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    ContainerIdGetResponse::FetchASingleContainerById(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ContainerIdGetResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    ContainerIdGetResponse::GenericErrorResponse(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn container_lookup_get( +        &self, +        param_issn: String, +        context: &Context, +    ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>> { +        // Query parameters +        let query_issn = format!("issn={issn}&", issn = param_issn.to_string()); + +        let uri = format!( +            "{}/v0/container/lookup?{issn}", +            self.base_path, +            issn = utf8_percent_encode(&query_issn, QUERY_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::ContainerEntity>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    ContainerLookupGetResponse::FindASingleContainerByExternalIdentifer(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ContainerLookupGetResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    404 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ContainerLookupGetResponse::NoSuchContainer(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    ContainerLookupGetResponse::GenericErrorResponse(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn container_post( +        &self, +        param_body: Option<models::ContainerEntity>, +        context: &Context, +    ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>> { +        let uri = format!("{}/v0/container", self.base_path); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Post, uri); + +        let body = param_body +            .map(|ref body| serde_json::to_string(body).expect("impossible to fail to serialize")); + +        if let Some(body) = body { +            request.set_body(body.into_bytes()); +        } + +        request +            .headers_mut() +            .set(ContentType(mimetypes::requests::CONTAINER_POST.clone())); +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    201 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::EntityEdit>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ContainerPostResponse::Created(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ContainerPostResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ContainerPostResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn creator_id_get( +        &self, +        param_id: String, +        context: &Context, +    ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>> { +        let uri = format!( +            "{}/v0/creator/{id}", +            self.base_path, +            id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::CreatorEntity>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    CreatorIdGetResponse::FetchASingleCreatorById(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| CreatorIdGetResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| CreatorIdGetResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn creator_lookup_get( +        &self, +        param_orcid: String, +        context: &Context, +    ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>> { +        // Query parameters +        let query_orcid = format!("orcid={orcid}&", orcid = param_orcid.to_string()); + +        let uri = format!( +            "{}/v0/creator/lookup?{orcid}", +            self.base_path, +            orcid = utf8_percent_encode(&query_orcid, QUERY_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::CreatorEntity>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    CreatorLookupGetResponse::FindASingleCreatorByExternalIdentifer( +                                        body, +                                    ) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| CreatorLookupGetResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    404 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| CreatorLookupGetResponse::NoSuchCreator(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    CreatorLookupGetResponse::GenericErrorResponse(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn creator_post( +        &self, +        param_body: Option<models::CreatorEntity>, +        context: &Context, +    ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>> { +        let uri = format!("{}/v0/creator", self.base_path); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Post, uri); + +        let body = param_body +            .map(|ref body| serde_json::to_string(body).expect("impossible to fail to serialize")); + +        if let Some(body) = body { +            request.set_body(body.into_bytes()); +        } + +        request +            .headers_mut() +            .set(ContentType(mimetypes::requests::CREATOR_POST.clone())); +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    201 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::EntityEdit>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| CreatorPostResponse::Created(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| CreatorPostResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| CreatorPostResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn editgroup_id_accept_post( +        &self, +        param_id: i32, +        context: &Context, +    ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>> { +        let uri = format!( +            "{}/v0/editgroup/{id}/accept", +            self.base_path, +            id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Post, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Success>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditgroupIdAcceptPostResponse::MergedEditgroupSuccessfully_( +                                        body, +                                    ) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditgroupIdAcceptPostResponse::EditgroupIsInAnUnmergableState( +                                        body, +                                    ) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    404 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditgroupIdAcceptPostResponse::NoSuchEditgroup(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditgroupIdAcceptPostResponse::GenericErrorResponse(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn editgroup_id_get( +        &self, +        param_id: i32, +        context: &Context, +    ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>> { +        let uri = format!( +            "{}/v0/editgroup/{id}", +            self.base_path, +            id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Editgroup>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditgroupIdGetResponse::FetchEditgroupByIdentifier(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    404 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| EditgroupIdGetResponse::NoSuchEditgroup(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditgroupIdGetResponse::GenericErrorResponse(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn editgroup_post( +        &self, +        context: &Context, +    ) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>> { +        let uri = format!("{}/v0/editgroup", self.base_path); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Post, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    201 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Editgroup>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| EditgroupPostResponse::SuccessfullyCreated(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditgroupPostResponse::InvalidRequestParameters(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| EditgroupPostResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn editor_username_changelog_get( +        &self, +        param_username: String, +        context: &Context, +    ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>> { +        let uri = format!( +            "{}/v0/editor/{username}/changelog", +            self.base_path, +            username = utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Changelogentry>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditorUsernameChangelogGetResponse::FindChanges_(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    404 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditorUsernameChangelogGetResponse::UsernameNotFound(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditorUsernameChangelogGetResponse::GenericErrorResponse(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn editor_username_get( +        &self, +        param_username: String, +        context: &Context, +    ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>> { +        let uri = format!( +            "{}/v0/editor/{username}", +            self.base_path, +            username = utf8_percent_encode(¶m_username.to_string(), PATH_SEGMENT_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Editor>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditorUsernameGetResponse::FetchGenericInformationAboutAnEditor( +                                        body, +                                    ) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    404 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| EditorUsernameGetResponse::UsernameNotFound(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    EditorUsernameGetResponse::GenericErrorResponse(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn file_id_get( +        &self, +        param_id: String, +        context: &Context, +    ) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>> { +        let uri = format!( +            "{}/v0/file/{id}", +            self.base_path, +            id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::FileEntity>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| FileIdGetResponse::FetchASingleFileById(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| FileIdGetResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| FileIdGetResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn file_lookup_get( +        &self, +        param_sha1: String, +        context: &Context, +    ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>> { +        // Query parameters +        let query_sha1 = format!("sha1={sha1}&", sha1 = param_sha1.to_string()); + +        let uri = format!( +            "{}/v0/file/lookup?{sha1}", +            self.base_path, +            sha1 = utf8_percent_encode(&query_sha1, QUERY_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::FileEntity>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    FileLookupGetResponse::FindASingleFileByExternalIdentifer(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| FileLookupGetResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    404 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| FileLookupGetResponse::NoSuchFile(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| FileLookupGetResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn file_post( +        &self, +        param_body: Option<models::FileEntity>, +        context: &Context, +    ) -> Box<Future<Item = FilePostResponse, Error = ApiError>> { +        let uri = format!("{}/v0/file", self.base_path); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Post, uri); + +        let body = param_body +            .map(|ref body| serde_json::to_string(body).expect("impossible to fail to serialize")); + +        if let Some(body) = body { +            request.set_body(body.into_bytes()); +        } + +        request +            .headers_mut() +            .set(ContentType(mimetypes::requests::FILE_POST.clone())); +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    201 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::EntityEdit>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| FilePostResponse::Created(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| FilePostResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| FilePostResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn release_id_get( +        &self, +        param_id: String, +        context: &Context, +    ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>> { +        let uri = format!( +            "{}/v0/release/{id}", +            self.base_path, +            id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::ReleaseEntity>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    ReleaseIdGetResponse::FetchASingleReleaseById(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ReleaseIdGetResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ReleaseIdGetResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn release_lookup_get( +        &self, +        param_doi: String, +        context: &Context, +    ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>> { +        // Query parameters +        let query_doi = format!("doi={doi}&", doi = param_doi.to_string()); + +        let uri = format!( +            "{}/v0/release/lookup?{doi}", +            self.base_path, +            doi = utf8_percent_encode(&query_doi, QUERY_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::ReleaseEntity>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    ReleaseLookupGetResponse::FindASingleReleaseByExternalIdentifer( +                                        body, +                                    ) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ReleaseLookupGetResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    404 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ReleaseLookupGetResponse::NoSuchRelease(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| { +                                    ReleaseLookupGetResponse::GenericErrorResponse(body) +                                }), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn release_post( +        &self, +        param_body: Option<models::ReleaseEntity>, +        context: &Context, +    ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>> { +        let uri = format!("{}/v0/release", self.base_path); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Post, uri); + +        let body = param_body +            .map(|ref body| serde_json::to_string(body).expect("impossible to fail to serialize")); + +        if let Some(body) = body { +            request.set_body(body.into_bytes()); +        } + +        request +            .headers_mut() +            .set(ContentType(mimetypes::requests::RELEASE_POST.clone())); +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    201 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::EntityEdit>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ReleasePostResponse::Created(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ReleasePostResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| ReleasePostResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn work_id_get( +        &self, +        param_id: String, +        context: &Context, +    ) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>> { +        let uri = format!( +            "{}/v0/work/{id}", +            self.base_path, +            id = utf8_percent_encode(¶m_id.to_string(), PATH_SEGMENT_ENCODE_SET) +        ); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Get, uri); + +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    200 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::WorkEntity>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| WorkIdGetResponse::FetchASingleWorkById(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| WorkIdGetResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| WorkIdGetResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } + +    fn work_post( +        &self, +        param_body: Option<models::WorkEntity>, +        context: &Context, +    ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>> { +        let uri = format!("{}/v0/work", self.base_path); + +        let uri = match Uri::from_str(&uri) { +            Ok(uri) => uri, +            Err(err) => { +                return Box::new(futures::done(Err(ApiError(format!( +                    "Unable to build URI: {}", +                    err +                ))))) +            } +        }; + +        let mut request = hyper::Request::new(hyper::Method::Post, uri); + +        let body = param_body +            .map(|ref body| serde_json::to_string(body).expect("impossible to fail to serialize")); + +        if let Some(body) = body { +            request.set_body(body.into_bytes()); +        } + +        request +            .headers_mut() +            .set(ContentType(mimetypes::requests::WORK_POST.clone())); +        context +            .x_span_id +            .as_ref() +            .map(|header| request.headers_mut().set(XSpanId(header.clone()))); + +        let hyper_client = (self.hyper_client)(&*self.handle); +        Box::new( +            hyper_client +                .call(request) +                .map_err(|e| ApiError(format!("No response received: {}", e))) +                .and_then(|mut response| match response.status().as_u16() { +                    201 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::EntityEdit>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| WorkPostResponse::Created(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    400 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| WorkPostResponse::BadRequest(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    0 => { +                        let body = response.body(); +                        Box::new( +                            body.concat2() +                                .map_err(|e| ApiError(format!("Failed to read response: {}", e))) +                                .and_then(|body| { +                                    str::from_utf8(&body) +                                        .map_err(|e| { +                                            ApiError(format!("Response was not valid UTF8: {}", e)) +                                        }) +                                        .and_then(|body| { +                                            serde_json::from_str::<models::Error>(body) +                                                .map_err(|e| e.into()) +                                        }) +                                }) +                                .map(move |body| WorkPostResponse::GenericErrorResponse(body)), +                        ) as Box<Future<Item = _, Error = _>> +                    } +                    code => { +                        let headers = response.headers().clone(); +                        Box::new(response.body().take(100).concat2().then(move |body| { +                            future::err(ApiError(format!( +                                "Unexpected response code {}:\n{:?}\n\n{}", +                                code, +                                headers, +                                match body { +                                    Ok(ref body) => match str::from_utf8(body) { +                                        Ok(body) => Cow::from(body), +                                        Err(e) => { +                                            Cow::from(format!("<Body was not UTF8: {:?}>", e)) +                                        } +                                    }, +                                    Err(e) => Cow::from(format!("<Failed to read body: {}>", e)), +                                } +                            ))) +                        })) as Box<Future<Item = _, Error = _>> +                    } +                }), +        ) +    } +} + +#[derive(Debug)] +pub enum ClientInitError { +    InvalidScheme, +    InvalidUri(hyper::error::UriError), +    MissingHost, +    SslError(openssl::error::ErrorStack), +} + +impl From<hyper::error::UriError> for ClientInitError { +    fn from(err: hyper::error::UriError) -> ClientInitError { +        ClientInitError::InvalidUri(err) +    } +} + +impl From<openssl::error::ErrorStack> for ClientInitError { +    fn from(err: openssl::error::ErrorStack) -> ClientInitError { +        ClientInitError::SslError(err) +    } +} + +impl fmt::Display for ClientInitError { +    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +        (self as &fmt::Debug).fmt(f) +    } +} + +impl error::Error for ClientInitError { +    fn description(&self) -> &str { +        "Failed to produce a hyper client." +    } +} diff --git a/rust/fatcat-api/src/lib.rs b/rust/fatcat-api/src/lib.rs new file mode 100644 index 00000000..36573537 --- /dev/null +++ b/rust/fatcat-api/src/lib.rs @@ -0,0 +1,599 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, +         unused_extern_crates, non_camel_case_types)] +extern crate serde; +#[macro_use] +extern crate serde_derive; +extern crate serde_json; + +extern crate chrono; +extern crate futures; +#[macro_use] +extern crate lazy_static; +#[macro_use] +extern crate log; + +// Logically this should be in the client and server modules, but rust doesn't allow `macro_use` from a module. +#[cfg(any(feature = "client", feature = "server"))] +#[macro_use] +extern crate hyper; + +extern crate swagger; + +use futures::Stream; +use std::io::Error; + +#[allow(unused_imports)] +use std::collections::HashMap; + +pub use futures::Future; + +#[cfg(any(feature = "client", feature = "server"))] +mod mimetypes; + +pub use swagger::{ApiError, Context, ContextWrapper}; + +pub const BASE_PATH: &'static str = "/v0"; +pub const API_VERSION: &'static str = "0.1.0"; + +#[derive(Debug, PartialEq)] +pub enum ContainerIdGetResponse { +    /// fetch a single container by id +    FetchASingleContainerById(models::ContainerEntity), +    /// bad request +    BadRequest(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum ContainerLookupGetResponse { +    /// find a single container by external identifer +    FindASingleContainerByExternalIdentifer(models::ContainerEntity), +    /// bad request +    BadRequest(models::Error), +    /// no such container +    NoSuchContainer(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum ContainerPostResponse { +    /// created +    Created(models::EntityEdit), +    /// bad request +    BadRequest(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum CreatorIdGetResponse { +    /// fetch a single creator by id +    FetchASingleCreatorById(models::CreatorEntity), +    /// bad request +    BadRequest(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum CreatorLookupGetResponse { +    /// find a single creator by external identifer +    FindASingleCreatorByExternalIdentifer(models::CreatorEntity), +    /// bad request +    BadRequest(models::Error), +    /// no such creator +    NoSuchCreator(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum CreatorPostResponse { +    /// created +    Created(models::EntityEdit), +    /// bad request +    BadRequest(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum EditgroupIdAcceptPostResponse { +    /// merged editgroup successfully (\"live\") +    MergedEditgroupSuccessfully_(models::Success), +    /// editgroup is in an unmergable state +    EditgroupIsInAnUnmergableState(models::Error), +    /// no such editgroup +    NoSuchEditgroup(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum EditgroupIdGetResponse { +    /// fetch editgroup by identifier +    FetchEditgroupByIdentifier(models::Editgroup), +    /// no such editgroup +    NoSuchEditgroup(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum EditgroupPostResponse { +    /// successfully created +    SuccessfullyCreated(models::Editgroup), +    /// invalid request parameters +    InvalidRequestParameters(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum EditorUsernameChangelogGetResponse { +    /// find changes (editgroups) by this editor which have been merged +    FindChanges_(models::Changelogentry), +    /// username not found +    UsernameNotFound(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum EditorUsernameGetResponse { +    /// fetch generic information about an editor +    FetchGenericInformationAboutAnEditor(models::Editor), +    /// username not found +    UsernameNotFound(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum FileIdGetResponse { +    /// fetch a single file by id +    FetchASingleFileById(models::FileEntity), +    /// bad request +    BadRequest(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum FileLookupGetResponse { +    /// find a single file by external identifer +    FindASingleFileByExternalIdentifer(models::FileEntity), +    /// bad request +    BadRequest(models::Error), +    /// no such file +    NoSuchFile(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum FilePostResponse { +    /// created +    Created(models::EntityEdit), +    /// bad request +    BadRequest(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum ReleaseIdGetResponse { +    /// fetch a single release by id +    FetchASingleReleaseById(models::ReleaseEntity), +    /// bad request +    BadRequest(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum ReleaseLookupGetResponse { +    /// find a single release by external identifer +    FindASingleReleaseByExternalIdentifer(models::ReleaseEntity), +    /// bad request +    BadRequest(models::Error), +    /// no such release +    NoSuchRelease(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum ReleasePostResponse { +    /// created +    Created(models::EntityEdit), +    /// bad request +    BadRequest(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum WorkIdGetResponse { +    /// fetch a single work by id +    FetchASingleWorkById(models::WorkEntity), +    /// bad request +    BadRequest(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +#[derive(Debug, PartialEq)] +pub enum WorkPostResponse { +    /// created +    Created(models::EntityEdit), +    /// bad request +    BadRequest(models::Error), +    /// generic error response +    GenericErrorResponse(models::Error), +} + +/// API +pub trait Api { +    fn container_id_get( +        &self, +        id: String, +        context: &Context, +    ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>>; + +    fn container_lookup_get( +        &self, +        issn: String, +        context: &Context, +    ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>>; + +    fn container_post( +        &self, +        body: Option<models::ContainerEntity>, +        context: &Context, +    ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>>; + +    fn creator_id_get( +        &self, +        id: String, +        context: &Context, +    ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>>; + +    fn creator_lookup_get( +        &self, +        orcid: String, +        context: &Context, +    ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>>; + +    fn creator_post( +        &self, +        body: Option<models::CreatorEntity>, +        context: &Context, +    ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>>; + +    fn editgroup_id_accept_post( +        &self, +        id: i32, +        context: &Context, +    ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>>; + +    fn editgroup_id_get( +        &self, +        id: i32, +        context: &Context, +    ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>>; + +    fn editgroup_post( +        &self, +        context: &Context, +    ) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>>; + +    fn editor_username_changelog_get( +        &self, +        username: String, +        context: &Context, +    ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>>; + +    fn editor_username_get( +        &self, +        username: String, +        context: &Context, +    ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>>; + +    fn file_id_get( +        &self, +        id: String, +        context: &Context, +    ) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>>; + +    fn file_lookup_get( +        &self, +        sha1: String, +        context: &Context, +    ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>>; + +    fn file_post( +        &self, +        body: Option<models::FileEntity>, +        context: &Context, +    ) -> Box<Future<Item = FilePostResponse, Error = ApiError>>; + +    fn release_id_get( +        &self, +        id: String, +        context: &Context, +    ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>>; + +    fn release_lookup_get( +        &self, +        doi: String, +        context: &Context, +    ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>>; + +    fn release_post( +        &self, +        body: Option<models::ReleaseEntity>, +        context: &Context, +    ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>>; + +    fn work_id_get( +        &self, +        id: String, +        context: &Context, +    ) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>>; + +    fn work_post( +        &self, +        body: Option<models::WorkEntity>, +        context: &Context, +    ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>>; +} + +/// API without a `Context` +pub trait ApiNoContext { +    fn container_id_get( +        &self, +        id: String, +    ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>>; + +    fn container_lookup_get( +        &self, +        issn: String, +    ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>>; + +    fn container_post( +        &self, +        body: Option<models::ContainerEntity>, +    ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>>; + +    fn creator_id_get( +        &self, +        id: String, +    ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>>; + +    fn creator_lookup_get( +        &self, +        orcid: String, +    ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>>; + +    fn creator_post( +        &self, +        body: Option<models::CreatorEntity>, +    ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>>; + +    fn editgroup_id_accept_post( +        &self, +        id: i32, +    ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>>; + +    fn editgroup_id_get( +        &self, +        id: i32, +    ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>>; + +    fn editgroup_post(&self) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>>; + +    fn editor_username_changelog_get( +        &self, +        username: String, +    ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>>; + +    fn editor_username_get( +        &self, +        username: String, +    ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>>; + +    fn file_id_get(&self, id: String) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>>; + +    fn file_lookup_get( +        &self, +        sha1: String, +    ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>>; + +    fn file_post( +        &self, +        body: Option<models::FileEntity>, +    ) -> Box<Future<Item = FilePostResponse, Error = ApiError>>; + +    fn release_id_get( +        &self, +        id: String, +    ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>>; + +    fn release_lookup_get( +        &self, +        doi: String, +    ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>>; + +    fn release_post( +        &self, +        body: Option<models::ReleaseEntity>, +    ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>>; + +    fn work_id_get(&self, id: String) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>>; + +    fn work_post( +        &self, +        body: Option<models::WorkEntity>, +    ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>>; +} + +/// Trait to extend an API to make it easy to bind it to a context. +pub trait ContextWrapperExt<'a> +where +    Self: Sized, +{ +    /// Binds this API to a context. +    fn with_context(self: &'a Self, context: Context) -> ContextWrapper<'a, Self>; +} + +impl<'a, T: Api + Sized> ContextWrapperExt<'a> for T { +    fn with_context(self: &'a T, context: Context) -> ContextWrapper<'a, T> { +        ContextWrapper::<T>::new(self, context) +    } +} + +impl<'a, T: Api> ApiNoContext for ContextWrapper<'a, T> { +    fn container_id_get( +        &self, +        id: String, +    ) -> Box<Future<Item = ContainerIdGetResponse, Error = ApiError>> { +        self.api().container_id_get(id, &self.context()) +    } + +    fn container_lookup_get( +        &self, +        issn: String, +    ) -> Box<Future<Item = ContainerLookupGetResponse, Error = ApiError>> { +        self.api().container_lookup_get(issn, &self.context()) +    } + +    fn container_post( +        &self, +        body: Option<models::ContainerEntity>, +    ) -> Box<Future<Item = ContainerPostResponse, Error = ApiError>> { +        self.api().container_post(body, &self.context()) +    } + +    fn creator_id_get( +        &self, +        id: String, +    ) -> Box<Future<Item = CreatorIdGetResponse, Error = ApiError>> { +        self.api().creator_id_get(id, &self.context()) +    } + +    fn creator_lookup_get( +        &self, +        orcid: String, +    ) -> Box<Future<Item = CreatorLookupGetResponse, Error = ApiError>> { +        self.api().creator_lookup_get(orcid, &self.context()) +    } + +    fn creator_post( +        &self, +        body: Option<models::CreatorEntity>, +    ) -> Box<Future<Item = CreatorPostResponse, Error = ApiError>> { +        self.api().creator_post(body, &self.context()) +    } + +    fn editgroup_id_accept_post( +        &self, +        id: i32, +    ) -> Box<Future<Item = EditgroupIdAcceptPostResponse, Error = ApiError>> { +        self.api().editgroup_id_accept_post(id, &self.context()) +    } + +    fn editgroup_id_get( +        &self, +        id: i32, +    ) -> Box<Future<Item = EditgroupIdGetResponse, Error = ApiError>> { +        self.api().editgroup_id_get(id, &self.context()) +    } + +    fn editgroup_post(&self) -> Box<Future<Item = EditgroupPostResponse, Error = ApiError>> { +        self.api().editgroup_post(&self.context()) +    } + +    fn editor_username_changelog_get( +        &self, +        username: String, +    ) -> Box<Future<Item = EditorUsernameChangelogGetResponse, Error = ApiError>> { +        self.api() +            .editor_username_changelog_get(username, &self.context()) +    } + +    fn editor_username_get( +        &self, +        username: String, +    ) -> Box<Future<Item = EditorUsernameGetResponse, Error = ApiError>> { +        self.api().editor_username_get(username, &self.context()) +    } + +    fn file_id_get(&self, id: String) -> Box<Future<Item = FileIdGetResponse, Error = ApiError>> { +        self.api().file_id_get(id, &self.context()) +    } + +    fn file_lookup_get( +        &self, +        sha1: String, +    ) -> Box<Future<Item = FileLookupGetResponse, Error = ApiError>> { +        self.api().file_lookup_get(sha1, &self.context()) +    } + +    fn file_post( +        &self, +        body: Option<models::FileEntity>, +    ) -> Box<Future<Item = FilePostResponse, Error = ApiError>> { +        self.api().file_post(body, &self.context()) +    } + +    fn release_id_get( +        &self, +        id: String, +    ) -> Box<Future<Item = ReleaseIdGetResponse, Error = ApiError>> { +        self.api().release_id_get(id, &self.context()) +    } + +    fn release_lookup_get( +        &self, +        doi: String, +    ) -> Box<Future<Item = ReleaseLookupGetResponse, Error = ApiError>> { +        self.api().release_lookup_get(doi, &self.context()) +    } + +    fn release_post( +        &self, +        body: Option<models::ReleaseEntity>, +    ) -> Box<Future<Item = ReleasePostResponse, Error = ApiError>> { +        self.api().release_post(body, &self.context()) +    } + +    fn work_id_get(&self, id: String) -> Box<Future<Item = WorkIdGetResponse, Error = ApiError>> { +        self.api().work_id_get(id, &self.context()) +    } + +    fn work_post( +        &self, +        body: Option<models::WorkEntity>, +    ) -> Box<Future<Item = WorkPostResponse, Error = ApiError>> { +        self.api().work_post(body, &self.context()) +    } +} + +#[cfg(feature = "client")] +pub mod client; + +// Re-export Client as a top-level name +#[cfg(feature = "client")] +pub use self::client::Client; + +#[cfg(feature = "server")] +pub mod server; + +// Re-export router() as a top-level name +#[cfg(feature = "server")] +pub use self::server::Service; + +pub mod models; diff --git a/rust/fatcat-api/src/mimetypes.rs b/rust/fatcat-api/src/mimetypes.rs new file mode 100644 index 00000000..dfbff890 --- /dev/null +++ b/rust/fatcat-api/src/mimetypes.rs @@ -0,0 +1,313 @@ +/// mime types for requests and responses + +pub mod responses { +    use hyper::mime::*; + +    // The macro is called per-operation to beat the recursion limit +    /// Create Mime objects for the response content types for ContainerIdGet +    lazy_static! { +        pub static ref CONTAINER_ID_GET_FETCH_A_SINGLE_CONTAINER_BY_ID: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ContainerIdGet +    lazy_static! { +        pub static ref CONTAINER_ID_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ContainerIdGet +    lazy_static! { +        pub static ref CONTAINER_ID_GET_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ContainerLookupGet +    lazy_static! { +        pub static ref CONTAINER_LOOKUP_GET_FIND_A_SINGLE_CONTAINER_BY_EXTERNAL_IDENTIFER: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ContainerLookupGet +    lazy_static! { +        pub static ref CONTAINER_LOOKUP_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ContainerLookupGet +    lazy_static! { +        pub static ref CONTAINER_LOOKUP_GET_NO_SUCH_CONTAINER: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ContainerLookupGet +    lazy_static! { +        pub static ref CONTAINER_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ContainerPost +    lazy_static! { +        pub static ref CONTAINER_POST_CREATED: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ContainerPost +    lazy_static! { +        pub static ref CONTAINER_POST_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ContainerPost +    lazy_static! { +        pub static ref CONTAINER_POST_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for CreatorIdGet +    lazy_static! { +        pub static ref CREATOR_ID_GET_FETCH_A_SINGLE_CREATOR_BY_ID: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for CreatorIdGet +    lazy_static! { +        pub static ref CREATOR_ID_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for CreatorIdGet +    lazy_static! { +        pub static ref CREATOR_ID_GET_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for CreatorLookupGet +    lazy_static! { +        pub static ref CREATOR_LOOKUP_GET_FIND_A_SINGLE_CREATOR_BY_EXTERNAL_IDENTIFER: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for CreatorLookupGet +    lazy_static! { +        pub static ref CREATOR_LOOKUP_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for CreatorLookupGet +    lazy_static! { +        pub static ref CREATOR_LOOKUP_GET_NO_SUCH_CREATOR: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for CreatorLookupGet +    lazy_static! { +        pub static ref CREATOR_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for CreatorPost +    lazy_static! { +        pub static ref CREATOR_POST_CREATED: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for CreatorPost +    lazy_static! { +        pub static ref CREATOR_POST_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for CreatorPost +    lazy_static! { +        pub static ref CREATOR_POST_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditgroupIdAcceptPost +    lazy_static! { +        pub static ref EDITGROUP_ID_ACCEPT_POST_MERGED_EDITGROUP_SUCCESSFULLY_: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditgroupIdAcceptPost +    lazy_static! { +        pub static ref EDITGROUP_ID_ACCEPT_POST_EDITGROUP_IS_IN_AN_UNMERGABLE_STATE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditgroupIdAcceptPost +    lazy_static! { +        pub static ref EDITGROUP_ID_ACCEPT_POST_NO_SUCH_EDITGROUP: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditgroupIdAcceptPost +    lazy_static! { +        pub static ref EDITGROUP_ID_ACCEPT_POST_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditgroupIdGet +    lazy_static! { +        pub static ref EDITGROUP_ID_GET_FETCH_EDITGROUP_BY_IDENTIFIER: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditgroupIdGet +    lazy_static! { +        pub static ref EDITGROUP_ID_GET_NO_SUCH_EDITGROUP: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditgroupIdGet +    lazy_static! { +        pub static ref EDITGROUP_ID_GET_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditgroupPost +    lazy_static! { +        pub static ref EDITGROUP_POST_SUCCESSFULLY_CREATED: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditgroupPost +    lazy_static! { +        pub static ref EDITGROUP_POST_INVALID_REQUEST_PARAMETERS: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditgroupPost +    lazy_static! { +        pub static ref EDITGROUP_POST_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditorUsernameChangelogGet +    lazy_static! { +        pub static ref EDITOR_USERNAME_CHANGELOG_GET_FIND_CHANGES_: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditorUsernameChangelogGet +    lazy_static! { +        pub static ref EDITOR_USERNAME_CHANGELOG_GET_USERNAME_NOT_FOUND: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditorUsernameChangelogGet +    lazy_static! { +        pub static ref EDITOR_USERNAME_CHANGELOG_GET_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditorUsernameGet +    lazy_static! { +        pub static ref EDITOR_USERNAME_GET_FETCH_GENERIC_INFORMATION_ABOUT_AN_EDITOR: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditorUsernameGet +    lazy_static! { +        pub static ref EDITOR_USERNAME_GET_USERNAME_NOT_FOUND: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for EditorUsernameGet +    lazy_static! { +        pub static ref EDITOR_USERNAME_GET_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for FileIdGet +    lazy_static! { +        pub static ref FILE_ID_GET_FETCH_A_SINGLE_FILE_BY_ID: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for FileIdGet +    lazy_static! { +        pub static ref FILE_ID_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for FileIdGet +    lazy_static! { +        pub static ref FILE_ID_GET_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for FileLookupGet +    lazy_static! { +        pub static ref FILE_LOOKUP_GET_FIND_A_SINGLE_FILE_BY_EXTERNAL_IDENTIFER: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for FileLookupGet +    lazy_static! { +        pub static ref FILE_LOOKUP_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for FileLookupGet +    lazy_static! { +        pub static ref FILE_LOOKUP_GET_NO_SUCH_FILE: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for FileLookupGet +    lazy_static! { +        pub static ref FILE_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for FilePost +    lazy_static! { +        pub static ref FILE_POST_CREATED: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for FilePost +    lazy_static! { +        pub static ref FILE_POST_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for FilePost +    lazy_static! { +        pub static ref FILE_POST_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ReleaseIdGet +    lazy_static! { +        pub static ref RELEASE_ID_GET_FETCH_A_SINGLE_RELEASE_BY_ID: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ReleaseIdGet +    lazy_static! { +        pub static ref RELEASE_ID_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ReleaseIdGet +    lazy_static! { +        pub static ref RELEASE_ID_GET_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ReleaseLookupGet +    lazy_static! { +        pub static ref RELEASE_LOOKUP_GET_FIND_A_SINGLE_RELEASE_BY_EXTERNAL_IDENTIFER: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ReleaseLookupGet +    lazy_static! { +        pub static ref RELEASE_LOOKUP_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ReleaseLookupGet +    lazy_static! { +        pub static ref RELEASE_LOOKUP_GET_NO_SUCH_RELEASE: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ReleaseLookupGet +    lazy_static! { +        pub static ref RELEASE_LOOKUP_GET_GENERIC_ERROR_RESPONSE: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ReleasePost +    lazy_static! { +        pub static ref RELEASE_POST_CREATED: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ReleasePost +    lazy_static! { +        pub static ref RELEASE_POST_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for ReleasePost +    lazy_static! { +        pub static ref RELEASE_POST_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for WorkIdGet +    lazy_static! { +        pub static ref WORK_ID_GET_FETCH_A_SINGLE_WORK_BY_ID: Mime = +            "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for WorkIdGet +    lazy_static! { +        pub static ref WORK_ID_GET_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for WorkIdGet +    lazy_static! { +        pub static ref WORK_ID_GET_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for WorkPost +    lazy_static! { +        pub static ref WORK_POST_CREATED: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for WorkPost +    lazy_static! { +        pub static ref WORK_POST_BAD_REQUEST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the response content types for WorkPost +    lazy_static! { +        pub static ref WORK_POST_GENERIC_ERROR_RESPONSE: Mime = "application/json".parse().unwrap(); +    } + +} + +pub mod requests { +    use hyper::mime::*; +    /// Create Mime objects for the request content types for ContainerPost +    lazy_static! { +        pub static ref CONTAINER_POST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the request content types for CreatorPost +    lazy_static! { +        pub static ref CREATOR_POST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the request content types for FilePost +    lazy_static! { +        pub static ref FILE_POST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the request content types for ReleasePost +    lazy_static! { +        pub static ref RELEASE_POST: Mime = "application/json".parse().unwrap(); +    } +    /// Create Mime objects for the request content types for WorkPost +    lazy_static! { +        pub static ref WORK_POST: Mime = "application/json".parse().unwrap(); +    } + +} diff --git a/rust/fatcat-api/src/models.rs b/rust/fatcat-api/src/models.rs new file mode 100644 index 00000000..3d104b78 --- /dev/null +++ b/rust/fatcat-api/src/models.rs @@ -0,0 +1,392 @@ +#![allow(unused_imports, unused_qualifications, unused_extern_crates)] +extern crate chrono; +extern crate uuid; + +use serde::ser::Serializer; + +use models; +use std::collections::HashMap; +use swagger; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Changelogentry { +    #[serde(rename = "index")] +    pub index: isize, + +    #[serde(rename = "editgroup_id")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub editgroup_id: Option<isize>, + +    #[serde(rename = "timestamp")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub timestamp: Option<chrono::DateTime<chrono::Utc>>, +} + +impl Changelogentry { +    pub fn new(index: isize) -> Changelogentry { +        Changelogentry { +            index: index, +            editgroup_id: None, +            timestamp: None, +        } +    } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ContainerEntity { +    #[serde(rename = "issn")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub issn: Option<String>, + +    #[serde(rename = "publisher")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub publisher: Option<String>, + +    #[serde(rename = "parent")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub parent: Option<String>, + +    #[serde(rename = "name")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub name: Option<String>, + +    // Note: inline enums are not fully supported by swagger-codegen +    #[serde(rename = "state")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub state: Option<String>, + +    #[serde(rename = "ident")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub ident: Option<String>, + +    #[serde(rename = "revision")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub revision: Option<isize>, + +    #[serde(rename = "redirect")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub redirect: Option<String>, + +    #[serde(rename = "editgroup")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub editgroup: Option<isize>, +} + +impl ContainerEntity { +    pub fn new() -> ContainerEntity { +        ContainerEntity { +            issn: None, +            publisher: None, +            parent: None, +            name: None, +            state: None, +            ident: None, +            revision: None, +            redirect: None, +            editgroup: None, +        } +    } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct CreatorEntity { +    #[serde(rename = "orcid")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub orcid: Option<String>, + +    #[serde(rename = "name")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub name: Option<String>, + +    #[serde(rename = "editgroup")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub editgroup: Option<isize>, + +    #[serde(rename = "redirect")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub redirect: Option<String>, + +    #[serde(rename = "revision")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub revision: Option<isize>, + +    #[serde(rename = "ident")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub ident: Option<String>, + +    // Note: inline enums are not fully supported by swagger-codegen +    #[serde(rename = "state")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub state: Option<String>, +} + +impl CreatorEntity { +    pub fn new() -> CreatorEntity { +        CreatorEntity { +            orcid: None, +            name: None, +            editgroup: None, +            redirect: None, +            revision: None, +            ident: None, +            state: None, +        } +    } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Editgroup { +    #[serde(rename = "id")] +    pub id: isize, + +    #[serde(rename = "editor_id")] +    pub editor_id: isize, +} + +impl Editgroup { +    pub fn new(id: isize, editor_id: isize) -> Editgroup { +        Editgroup { +            id: id, +            editor_id: editor_id, +        } +    } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Editor { +    #[serde(rename = "username")] +    pub username: String, +} + +impl Editor { +    pub fn new(username: String) -> Editor { +        Editor { username: username } +    } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct EntityEdit { +    #[serde(rename = "editgroup_id")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub editgroup_id: Option<isize>, + +    #[serde(rename = "revision")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub revision: Option<isize>, + +    #[serde(rename = "ident")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub ident: Option<String>, + +    #[serde(rename = "id")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub id: Option<isize>, +} + +impl EntityEdit { +    pub fn new() -> EntityEdit { +        EntityEdit { +            editgroup_id: None, +            revision: None, +            ident: None, +            id: None, +        } +    } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Error { +    #[serde(rename = "message")] +    pub message: String, +} + +impl Error { +    pub fn new(message: String) -> Error { +        Error { message: message } +    } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct FileEntity { +    #[serde(rename = "url")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub url: Option<String>, + +    #[serde(rename = "sha1")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub sha1: Option<String>, + +    #[serde(rename = "size")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub size: Option<isize>, + +    #[serde(rename = "editgroup")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub editgroup: Option<isize>, + +    #[serde(rename = "redirect")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub redirect: Option<String>, + +    #[serde(rename = "revision")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub revision: Option<isize>, + +    #[serde(rename = "ident")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub ident: Option<String>, + +    // Note: inline enums are not fully supported by swagger-codegen +    #[serde(rename = "state")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub state: Option<String>, +} + +impl FileEntity { +    pub fn new() -> FileEntity { +        FileEntity { +            url: None, +            sha1: None, +            size: None, +            editgroup: None, +            redirect: None, +            revision: None, +            ident: None, +            state: None, +        } +    } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct ReleaseEntity { +    #[serde(rename = "issue")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub issue: Option<String>, + +    #[serde(rename = "pages")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub pages: Option<String>, + +    #[serde(rename = "volume")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub volume: Option<String>, + +    #[serde(rename = "doi")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub doi: Option<String>, + +    #[serde(rename = "release_type")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub release_type: Option<String>, + +    #[serde(rename = "license")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub license: Option<String>, + +    #[serde(rename = "container")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub container: Option<String>, + +    #[serde(rename = "work")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub work: Option<String>, + +    // Note: inline enums are not fully supported by swagger-codegen +    #[serde(rename = "state")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub state: Option<String>, + +    #[serde(rename = "ident")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub ident: Option<String>, + +    #[serde(rename = "revision")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub revision: Option<isize>, + +    #[serde(rename = "redirect")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub redirect: Option<String>, + +    #[serde(rename = "editgroup")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub editgroup: Option<isize>, +} + +impl ReleaseEntity { +    pub fn new() -> ReleaseEntity { +        ReleaseEntity { +            issue: None, +            pages: None, +            volume: None, +            doi: None, +            release_type: None, +            license: None, +            container: None, +            work: None, +            state: None, +            ident: None, +            revision: None, +            redirect: None, +            editgroup: None, +        } +    } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Success { +    #[serde(rename = "message")] +    pub message: String, +} + +impl Success { +    pub fn new(message: String) -> Success { +        Success { message: message } +    } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct WorkEntity { +    #[serde(rename = "work_type")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub work_type: Option<String>, + +    #[serde(rename = "title")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub title: Option<String>, + +    #[serde(rename = "editgroup")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub editgroup: Option<isize>, + +    #[serde(rename = "redirect")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub redirect: Option<String>, + +    #[serde(rename = "revision")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub revision: Option<isize>, + +    #[serde(rename = "ident")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub ident: Option<String>, + +    // Note: inline enums are not fully supported by swagger-codegen +    #[serde(rename = "state")] +    #[serde(skip_serializing_if = "Option::is_none")] +    pub state: Option<String>, +} + +impl WorkEntity { +    pub fn new() -> WorkEntity { +        WorkEntity { +            work_type: None, +            title: None, +            editgroup: None, +            redirect: None, +            revision: None, +            ident: None, +            state: None, +        } +    } +} diff --git a/rust/fatcat-api/src/server/auth.rs b/rust/fatcat-api/src/server/auth.rs new file mode 100644 index 00000000..48dfd7d6 --- /dev/null +++ b/rust/fatcat-api/src/server/auth.rs @@ -0,0 +1,93 @@ +use Api; +use hyper; +use hyper::{Error, Request, Response, StatusCode}; +use server::url::form_urlencoded; +use std::io; +use swagger::auth::{AuthData, Authorization, Scopes}; + +pub struct NewService<T> +where +    T: hyper::server::NewService< +        Request = (Request, Option<AuthData>), +        Response = Response, +        Error = Error, +    >, +{ +    inner: T, +} + +impl<T> NewService<T> +where +    T: hyper::server::NewService< +            Request = (Request, Option<AuthData>), +            Response = Response, +            Error = Error, +        > +        + 'static, +{ +    pub fn new(inner: T) -> NewService<T> { +        NewService { inner } +    } +} + +impl<T> hyper::server::NewService for NewService<T> +where +    T: hyper::server::NewService< +            Request = (Request, Option<AuthData>), +            Response = Response, +            Error = Error, +        > +        + 'static, +{ +    type Request = Request; +    type Response = Response; +    type Error = Error; +    type Instance = Service<T::Instance>; + +    fn new_service(&self) -> Result<Self::Instance, io::Error> { +        self.inner.new_service().map(|s| Service::new(s)) +    } +} + +/// Middleware to extract authentication data from request +pub struct Service<T> +where +    T: hyper::server::Service< +        Request = (Request, Option<AuthData>), +        Response = Response, +        Error = Error, +    >, +{ +    inner: T, +} + +impl<T> Service<T> +where +    T: hyper::server::Service< +        Request = (Request, Option<AuthData>), +        Response = Response, +        Error = Error, +    >, +{ +    pub fn new(inner: T) -> Service<T> { +        Service { inner } +    } +} + +impl<T> hyper::server::Service for Service<T> +where +    T: hyper::server::Service< +        Request = (Request, Option<AuthData>), +        Response = Response, +        Error = Error, +    >, +{ +    type Request = Request; +    type Response = Response; +    type Error = Error; +    type Future = T::Future; + +    fn call(&self, req: Self::Request) -> Self::Future { +        return self.inner.call((req, None)); +    } +} diff --git a/rust/fatcat-api/src/server/mod.rs b/rust/fatcat-api/src/server/mod.rs new file mode 100644 index 00000000..186f8272 --- /dev/null +++ b/rust/fatcat-api/src/server/mod.rs @@ -0,0 +1,2485 @@ +#![allow(unused_extern_crates)] +extern crate chrono; +extern crate hyper_tls; +extern crate mime; +extern crate native_tls; +extern crate openssl; +extern crate serde_ignored; +extern crate tokio_core; +extern crate uuid; + +extern crate percent_encoding; +extern crate url; + +use self::url::form_urlencoded; +use futures::{future, stream, Future, Stream}; +use hyper; +use hyper::header::{ContentType, Headers}; +use hyper::{Error, Request, Response, StatusCode}; +use mimetypes; +use std::sync::Arc; + +use serde_json; + +#[allow(unused_imports)] +use std::collections::{BTreeMap, HashMap}; +use std::io; +#[allow(unused_imports)] +use swagger; + +#[allow(unused_imports)] +use std::collections::BTreeSet; + +pub use swagger::auth::Authorization; +use swagger::auth::Scopes; +use swagger::{ApiError, Context, XSpanId}; + +#[allow(unused_imports)] +use models; +use {Api, ContainerIdGetResponse, ContainerLookupGetResponse, ContainerPostResponse, +     CreatorIdGetResponse, CreatorLookupGetResponse, CreatorPostResponse, +     EditgroupIdAcceptPostResponse, EditgroupIdGetResponse, EditgroupPostResponse, +     EditorUsernameChangelogGetResponse, EditorUsernameGetResponse, FileIdGetResponse, +     FileLookupGetResponse, FilePostResponse, ReleaseIdGetResponse, ReleaseLookupGetResponse, +     ReleasePostResponse, WorkIdGetResponse, WorkPostResponse}; + +pub mod auth; + +header! { (Warning, "Warning") => [String] } + +mod paths { +    extern crate regex; + +    lazy_static! { +        pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(&[ +            r"^/v0/container$", +            r"^/v0/container/lookup$", +            r"^/v0/container/(?P<id>[^/?#]*)$", +            r"^/v0/creator$", +            r"^/v0/creator/lookup$", +            r"^/v0/creator/(?P<id>[^/?#]*)$", +            r"^/v0/editgroup$", +            r"^/v0/editgroup/(?P<id>[^/?#]*)$", +            r"^/v0/editgroup/(?P<id>[^/?#]*)/accept$", +            r"^/v0/editor/(?P<username>[^/?#]*)$", +            r"^/v0/editor/(?P<username>[^/?#]*)/changelog$", +            r"^/v0/file$", +            r"^/v0/file/lookup$", +            r"^/v0/file/(?P<id>[^/?#]*)$", +            r"^/v0/release$", +            r"^/v0/release/lookup$", +            r"^/v0/release/(?P<id>[^/?#]*)$", +            r"^/v0/work$", +            r"^/v0/work/(?P<id>[^/?#]*)$" +        ]).unwrap(); +    } +    pub static ID_CONTAINER: usize = 0; +    pub static ID_CONTAINER_LOOKUP: usize = 1; +    pub static ID_CONTAINER_ID: usize = 2; +    lazy_static! { +        pub static ref REGEX_CONTAINER_ID: regex::Regex = +            regex::Regex::new(r"^/v0/container/(?P<id>[^/?#]*)$").unwrap(); +    } +    pub static ID_CREATOR: usize = 3; +    pub static ID_CREATOR_LOOKUP: usize = 4; +    pub static ID_CREATOR_ID: usize = 5; +    lazy_static! { +        pub static ref REGEX_CREATOR_ID: regex::Regex = +            regex::Regex::new(r"^/v0/creator/(?P<id>[^/?#]*)$").unwrap(); +    } +    pub static ID_EDITGROUP: usize = 6; +    pub static ID_EDITGROUP_ID: usize = 7; +    lazy_static! { +        pub static ref REGEX_EDITGROUP_ID: regex::Regex = +            regex::Regex::new(r"^/v0/editgroup/(?P<id>[^/?#]*)$").unwrap(); +    } +    pub static ID_EDITGROUP_ID_ACCEPT: usize = 8; +    lazy_static! { +        pub static ref REGEX_EDITGROUP_ID_ACCEPT: regex::Regex = +            regex::Regex::new(r"^/v0/editgroup/(?P<id>[^/?#]*)/accept$").unwrap(); +    } +    pub static ID_EDITOR_USERNAME: usize = 9; +    lazy_static! { +        pub static ref REGEX_EDITOR_USERNAME: regex::Regex = +            regex::Regex::new(r"^/v0/editor/(?P<username>[^/?#]*)$").unwrap(); +    } +    pub static ID_EDITOR_USERNAME_CHANGELOG: usize = 10; +    lazy_static! { +        pub static ref REGEX_EDITOR_USERNAME_CHANGELOG: regex::Regex = +            regex::Regex::new(r"^/v0/editor/(?P<username>[^/?#]*)/changelog$").unwrap(); +    } +    pub static ID_FILE: usize = 11; +    pub static ID_FILE_LOOKUP: usize = 12; +    pub static ID_FILE_ID: usize = 13; +    lazy_static! { +        pub static ref REGEX_FILE_ID: regex::Regex = +            regex::Regex::new(r"^/v0/file/(?P<id>[^/?#]*)$").unwrap(); +    } +    pub static ID_RELEASE: usize = 14; +    pub static ID_RELEASE_LOOKUP: usize = 15; +    pub static ID_RELEASE_ID: usize = 16; +    lazy_static! { +        pub static ref REGEX_RELEASE_ID: regex::Regex = +            regex::Regex::new(r"^/v0/release/(?P<id>[^/?#]*)$").unwrap(); +    } +    pub static ID_WORK: usize = 17; +    pub static ID_WORK_ID: usize = 18; +    lazy_static! { +        pub static ref REGEX_WORK_ID: regex::Regex = +            regex::Regex::new(r"^/v0/work/(?P<id>[^/?#]*)$").unwrap(); +    } +} + +pub struct NewService<T> { +    api_impl: Arc<T>, +} + +impl<T> NewService<T> +where +    T: Api + Clone + 'static, +{ +    pub fn new<U: Into<Arc<T>>>(api_impl: U) -> NewService<T> { +        NewService { +            api_impl: api_impl.into(), +        } +    } +} + +impl<T> hyper::server::NewService for NewService<T> +where +    T: Api + Clone + 'static, +{ +    type Request = (Request, Context); +    type Response = Response; +    type Error = Error; +    type Instance = Service<T>; + +    fn new_service(&self) -> Result<Self::Instance, io::Error> { +        Ok(Service::new(self.api_impl.clone())) +    } +} + +pub struct Service<T> { +    api_impl: Arc<T>, +} + +impl<T> Service<T> +where +    T: Api + Clone + 'static, +{ +    pub fn new<U: Into<Arc<T>>>(api_impl: U) -> Service<T> { +        Service { +            api_impl: api_impl.into(), +        } +    } +} + +impl<T> hyper::server::Service for Service<T> +where +    T: Api + Clone + 'static, +{ +    type Request = (Request, Context); +    type Response = Response; +    type Error = Error; +    type Future = Box<Future<Item = Response, Error = Error>>; + +    fn call(&self, (req, mut context): Self::Request) -> Self::Future { +        let api_impl = self.api_impl.clone(); +        let (method, uri, _, headers, body) = req.deconstruct(); +        let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); +        match &method { +            // ContainerIdGet - GET /container/{id} +            &hyper::Method::Get if path.matched(paths::ID_CONTAINER_ID) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Path parameters +                let path = uri.path().to_string(); +                let path_params = paths::REGEX_CONTAINER_ID +                    .captures(&path) +                    .unwrap_or_else(|| { +                        panic!("Path {} matched RE CONTAINER_ID in set but failed match against \"{}\"", path, paths::REGEX_CONTAINER_ID.as_str()) +                    }); + +                let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) +                    .decode_utf8() +                { +                    Ok(param_id) => match param_id.parse::<String>() { +                        Ok(param_id) => param_id, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't parse path parameter id: {}", e)), +                            )) +                        } +                    }, +                    Err(_) => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body(format!( +                                    "Couldn't percent-decode path parameter as UTF-8: {}", +                                    &path_params["id"] +                                )), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.container_id_get(param_id, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                ContainerIdGetResponse::FetchASingleContainerById + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(200).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_ID_GET_FETCH_A_SINGLE_CONTAINER_BY_ID.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                ContainerIdGetResponse::BadRequest + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(400).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_ID_GET_BAD_REQUEST.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                ContainerIdGetResponse::GenericErrorResponse + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(0).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response.set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            }, +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // ContainerLookupGet - GET /container/lookup +            &hyper::Method::Get if path.matched(paths::ID_CONTAINER_LOOKUP) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) +                let query_params = form_urlencoded::parse( +                    uri.query().unwrap_or_default().as_bytes(), +                ).collect::<Vec<_>>(); +                let param_issn = query_params +                    .iter() +                    .filter(|e| e.0 == "issn") +                    .map(|e| e.1.to_owned()) +                    .nth(0); +                let param_issn = match param_issn { +                    Some(param_issn) => match param_issn.parse::<String>() { +                        Ok(param_issn) => param_issn, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!( +                                "Couldn't parse query parameter issn - doesn't match schema: {}", +                                e +                            )), +                            )) +                        } +                    }, +                    None => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body("Missing required query parameter issn"), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.container_lookup_get(param_issn, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                ContainerLookupGetResponse::FindASingleContainerByExternalIdentifer + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(200).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_FIND_A_SINGLE_CONTAINER_BY_EXTERNAL_IDENTIFER.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                ContainerLookupGetResponse::BadRequest + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(400).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_BAD_REQUEST.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                ContainerLookupGetResponse::NoSuchContainer + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(404).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_NO_SUCH_CONTAINER.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                ContainerLookupGetResponse::GenericErrorResponse + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(0).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response.set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            }, +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // ContainerPost - POST /container +            &hyper::Method::Post if path.matched(paths::ID_CONTAINER) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Body parameters (note that non-required body parameters will ignore garbage +                // values, rather than causing a 400 response). Produce warning header and logs for +                // any unused fields. +                Box::new(body.concat2().then( +                    move |result| -> Box<Future<Item = Response, Error = Error>> { +                        match result { +                            Ok(body) => { +                                let mut unused_elements = Vec::new(); +                                let param_body: Option< +                                    models::ContainerEntity, +                                > = if !body.is_empty() { +                                    let deserializer = +                                        &mut serde_json::Deserializer::from_slice(&*body); + +                                    match serde_ignored::deserialize(deserializer, |path| { +                                        warn!("Ignoring unknown field in body: {}", path); +                                        unused_elements.push(path.to_string()); +                                    }) { +                                        Ok(param_body) => param_body, + +                                        Err(_) => None, +                                    } +                                } else { +                                    None +                                }; + +                                Box::new(api_impl.container_post(param_body, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        if !unused_elements.is_empty() { +                                            response.headers_mut().set(Warning(format!( +                                                "Ignoring unknown fields in body: {:?}", +                                                unused_elements +                                            ))); +                                        } + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                ContainerPostResponse::Created(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(201).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_POST_CREATED.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                ContainerPostResponse::BadRequest(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(400).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_POST_BAD_REQUEST.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                ContainerPostResponse::GenericErrorResponse( +                                                    body, +                                                ) => { +                                                    response.set_status( +                                                        StatusCode::try_from(0).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CONTAINER_POST_GENERIC_ERROR_RESPONSE.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response +                                                    .set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            } +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                            Err(e) => Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't read body parameter body: {}", e)), +                            )), +                        } +                    }, +                )) as Box<Future<Item = Response, Error = Error>> +            } + +            // CreatorIdGet - GET /creator/{id} +            &hyper::Method::Get if path.matched(paths::ID_CREATOR_ID) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Path parameters +                let path = uri.path().to_string(); +                let path_params = paths::REGEX_CREATOR_ID.captures(&path).unwrap_or_else(|| { +                    panic!( +                        "Path {} matched RE CREATOR_ID in set but failed match against \"{}\"", +                        path, +                        paths::REGEX_CREATOR_ID.as_str() +                    ) +                }); + +                let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) +                    .decode_utf8() +                { +                    Ok(param_id) => match param_id.parse::<String>() { +                        Ok(param_id) => param_id, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't parse path parameter id: {}", e)), +                            )) +                        } +                    }, +                    Err(_) => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body(format!( +                                    "Couldn't percent-decode path parameter as UTF-8: {}", +                                    &path_params["id"] +                                )), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.creator_id_get(param_id, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                CreatorIdGetResponse::FetchASingleCreatorById( +                                                    body, +                                                ) => { +                                                    response.set_status( +                                                        StatusCode::try_from(200).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_ID_GET_FETCH_A_SINGLE_CREATOR_BY_ID.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                CreatorIdGetResponse::BadRequest(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(400).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_ID_GET_BAD_REQUEST.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                CreatorIdGetResponse::GenericErrorResponse( +                                                    body, +                                                ) => { +                                                    response.set_status( +                                                        StatusCode::try_from(0).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response +                                                    .set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            } +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // CreatorLookupGet - GET /creator/lookup +            &hyper::Method::Get if path.matched(paths::ID_CREATOR_LOOKUP) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) +                let query_params = form_urlencoded::parse( +                    uri.query().unwrap_or_default().as_bytes(), +                ).collect::<Vec<_>>(); +                let param_orcid = query_params +                    .iter() +                    .filter(|e| e.0 == "orcid") +                    .map(|e| e.1.to_owned()) +                    .nth(0); +                let param_orcid = match param_orcid { +                    Some(param_orcid) => match param_orcid.parse::<String>() { +                        Ok(param_orcid) => param_orcid, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!( +                                "Couldn't parse query parameter orcid - doesn't match schema: {}", +                                e +                            )), +                            )) +                        } +                    }, +                    None => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body("Missing required query parameter orcid"), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.creator_lookup_get(param_orcid, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                CreatorLookupGetResponse::FindASingleCreatorByExternalIdentifer + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(200).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_FIND_A_SINGLE_CREATOR_BY_EXTERNAL_IDENTIFER.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                CreatorLookupGetResponse::BadRequest + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(400).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_BAD_REQUEST.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                CreatorLookupGetResponse::NoSuchCreator + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(404).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_NO_SUCH_CREATOR.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                CreatorLookupGetResponse::GenericErrorResponse + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(0).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response.set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            }, +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // CreatorPost - POST /creator +            &hyper::Method::Post if path.matched(paths::ID_CREATOR) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Body parameters (note that non-required body parameters will ignore garbage +                // values, rather than causing a 400 response). Produce warning header and logs for +                // any unused fields. +                Box::new(body.concat2().then( +                    move |result| -> Box<Future<Item = Response, Error = Error>> { +                        match result { +                            Ok(body) => { +                                let mut unused_elements = Vec::new(); +                                let param_body: Option< +                                    models::CreatorEntity, +                                > = if !body.is_empty() { +                                    let deserializer = +                                        &mut serde_json::Deserializer::from_slice(&*body); + +                                    match serde_ignored::deserialize(deserializer, |path| { +                                        warn!("Ignoring unknown field in body: {}", path); +                                        unused_elements.push(path.to_string()); +                                    }) { +                                        Ok(param_body) => param_body, + +                                        Err(_) => None, +                                    } +                                } else { +                                    None +                                }; + +                                Box::new(api_impl.creator_post(param_body, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        if !unused_elements.is_empty() { +                                            response.headers_mut().set(Warning(format!( +                                                "Ignoring unknown fields in body: {:?}", +                                                unused_elements +                                            ))); +                                        } + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                CreatorPostResponse::Created(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(201).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType( +                                                        mimetypes::responses::CREATOR_POST_CREATED +                                                            .clone(), +                                                    )); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                CreatorPostResponse::BadRequest(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(400).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_POST_BAD_REQUEST.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                CreatorPostResponse::GenericErrorResponse(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(0).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::CREATOR_POST_GENERIC_ERROR_RESPONSE.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response +                                                    .set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            } +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                            Err(e) => Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't read body parameter body: {}", e)), +                            )), +                        } +                    }, +                )) as Box<Future<Item = Response, Error = Error>> +            } + +            // EditgroupIdAcceptPost - POST /editgroup/{id}/accept +            &hyper::Method::Post if path.matched(paths::ID_EDITGROUP_ID_ACCEPT) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Path parameters +                let path = uri.path().to_string(); +                let path_params = paths::REGEX_EDITGROUP_ID_ACCEPT +                    .captures(&path) +                    .unwrap_or_else(|| { +                        panic!("Path {} matched RE EDITGROUP_ID_ACCEPT in set but failed match against \"{}\"", path, paths::REGEX_EDITGROUP_ID_ACCEPT.as_str()) +                    }); + +                let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) +                    .decode_utf8() +                { +                    Ok(param_id) => match param_id.parse::<i32>() { +                        Ok(param_id) => param_id, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't parse path parameter id: {}", e)), +                            )) +                        } +                    }, +                    Err(_) => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body(format!( +                                    "Couldn't percent-decode path parameter as UTF-8: {}", +                                    &path_params["id"] +                                )), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new( +                                    api_impl.editgroup_id_accept_post(param_id, &context).then( +                                        move |result| { +                                            let mut response = Response::new(); +                                            context.x_span_id.as_ref().map(|header| { +                                                response.headers_mut().set(XSpanId(header.clone())) +                                            }); + +                                            match result { +                                            Ok(rsp) => match rsp { +                                                EditgroupIdAcceptPostResponse::MergedEditgroupSuccessfully_ + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(200).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_MERGED_EDITGROUP_SUCCESSFULLY_.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                EditgroupIdAcceptPostResponse::EditgroupIsInAnUnmergableState + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(400).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_EDITGROUP_IS_IN_AN_UNMERGABLE_STATE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                EditgroupIdAcceptPostResponse::NoSuchEditgroup + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(404).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_NO_SUCH_EDITGROUP.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                EditgroupIdAcceptPostResponse::GenericErrorResponse + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(0).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_ACCEPT_POST_GENERIC_ERROR_RESPONSE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response.set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            }, +                                        } + +                                            future::ok(response) +                                        }, +                                    ), +                                ) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // EditgroupIdGet - GET /editgroup/{id} +            &hyper::Method::Get if path.matched(paths::ID_EDITGROUP_ID) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Path parameters +                let path = uri.path().to_string(); +                let path_params = paths::REGEX_EDITGROUP_ID +                    .captures(&path) +                    .unwrap_or_else(|| { +                        panic!("Path {} matched RE EDITGROUP_ID in set but failed match against \"{}\"", path, paths::REGEX_EDITGROUP_ID.as_str()) +                    }); + +                let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) +                    .decode_utf8() +                { +                    Ok(param_id) => match param_id.parse::<i32>() { +                        Ok(param_id) => param_id, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't parse path parameter id: {}", e)), +                            )) +                        } +                    }, +                    Err(_) => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body(format!( +                                    "Couldn't percent-decode path parameter as UTF-8: {}", +                                    &path_params["id"] +                                )), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.editgroup_id_get(param_id, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                EditgroupIdGetResponse::FetchEditgroupByIdentifier + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(200).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_GET_FETCH_EDITGROUP_BY_IDENTIFIER.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                EditgroupIdGetResponse::NoSuchEditgroup + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(404).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_GET_NO_SUCH_EDITGROUP.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                EditgroupIdGetResponse::GenericErrorResponse + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(0).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response.set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            }, +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // EditgroupPost - POST /editgroup +            &hyper::Method::Post if path.matched(paths::ID_EDITGROUP) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.editgroup_post(&context).then(move |result| { +                                    let mut response = Response::new(); +                                    context.x_span_id.as_ref().map(|header| { +                                        response.headers_mut().set(XSpanId(header.clone())) +                                    }); + +                                    match result { +                                        Ok(rsp) => match rsp { +                                            EditgroupPostResponse::SuccessfullyCreated(body) => { +                                                response +                                                    .set_status(StatusCode::try_from(201).unwrap()); + +                                                response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_POST_SUCCESSFULLY_CREATED.clone())); + +                                                let body = serde_json::to_string(&body) +                                                    .expect("impossible to fail to serialize"); + +                                                response.set_body(body); +                                            } +                                            EditgroupPostResponse::InvalidRequestParameters( +                                                body, +                                            ) => { +                                                response +                                                    .set_status(StatusCode::try_from(400).unwrap()); + +                                                response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_POST_INVALID_REQUEST_PARAMETERS.clone())); + +                                                let body = serde_json::to_string(&body) +                                                    .expect("impossible to fail to serialize"); + +                                                response.set_body(body); +                                            } +                                            EditgroupPostResponse::GenericErrorResponse(body) => { +                                                response +                                                    .set_status(StatusCode::try_from(0).unwrap()); + +                                                response.headers_mut().set(ContentType(mimetypes::responses::EDITGROUP_POST_GENERIC_ERROR_RESPONSE.clone())); + +                                                let body = serde_json::to_string(&body) +                                                    .expect("impossible to fail to serialize"); + +                                                response.set_body(body); +                                            } +                                        }, +                                        Err(_) => { +                                            // Application code returned an error. This should not happen, as the implementation should +                                            // return a valid response. +                                            response.set_status(StatusCode::InternalServerError); +                                            response.set_body("An internal error occurred"); +                                        } +                                    } + +                                    future::ok(response) +                                })) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // EditorUsernameChangelogGet - GET /editor/{username}/changelog +            &hyper::Method::Get if path.matched(paths::ID_EDITOR_USERNAME_CHANGELOG) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Path parameters +                let path = uri.path().to_string(); +                let path_params = paths::REGEX_EDITOR_USERNAME_CHANGELOG +                    .captures(&path) +                    .unwrap_or_else(|| { +                        panic!("Path {} matched RE EDITOR_USERNAME_CHANGELOG in set but failed match against \"{}\"", path, paths::REGEX_EDITOR_USERNAME_CHANGELOG.as_str()) +                    }); + +                let param_username = match percent_encoding::percent_decode( +                    path_params["username"].as_bytes(), +                ).decode_utf8() +                { +                    Ok(param_username) => match param_username.parse::<String>() { +                        Ok(param_username) => param_username, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!( +                                        "Couldn't parse path parameter username: {}", +                                        e +                                    )), +                            )) +                        } +                    }, +                    Err(_) => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body(format!( +                                    "Couldn't percent-decode path parameter as UTF-8: {}", +                                    &path_params["username"] +                                )), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new( +                                    api_impl +                                        .editor_username_changelog_get(param_username, &context) +                                        .then(move |result| { +                                            let mut response = Response::new(); +                                            context.x_span_id.as_ref().map(|header| { +                                                response.headers_mut().set(XSpanId(header.clone())) +                                            }); + +                                            match result { +                                            Ok(rsp) => match rsp { +                                                EditorUsernameChangelogGetResponse::FindChanges_ + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(200).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_CHANGELOG_GET_FIND_CHANGES_.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                EditorUsernameChangelogGetResponse::UsernameNotFound + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(404).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_CHANGELOG_GET_USERNAME_NOT_FOUND.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                EditorUsernameChangelogGetResponse::GenericErrorResponse + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(0).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_CHANGELOG_GET_GENERIC_ERROR_RESPONSE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response.set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            }, +                                        } + +                                            future::ok(response) +                                        }), +                                ) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // EditorUsernameGet - GET /editor/{username} +            &hyper::Method::Get if path.matched(paths::ID_EDITOR_USERNAME) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Path parameters +                let path = uri.path().to_string(); +                let path_params = paths::REGEX_EDITOR_USERNAME.captures(&path).unwrap_or_else( +                    || { +                        panic!("Path {} matched RE EDITOR_USERNAME in set but failed match against \"{}\"", path, paths::REGEX_EDITOR_USERNAME.as_str()) +                    }, +                ); + +                let param_username = match percent_encoding::percent_decode( +                    path_params["username"].as_bytes(), +                ).decode_utf8() +                { +                    Ok(param_username) => match param_username.parse::<String>() { +                        Ok(param_username) => param_username, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!( +                                        "Couldn't parse path parameter username: {}", +                                        e +                                    )), +                            )) +                        } +                    }, +                    Err(_) => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body(format!( +                                    "Couldn't percent-decode path parameter as UTF-8: {}", +                                    &path_params["username"] +                                )), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new( +                                    api_impl.editor_username_get(param_username, &context).then( +                                        move |result| { +                                            let mut response = Response::new(); +                                            context.x_span_id.as_ref().map(|header| { +                                                response.headers_mut().set(XSpanId(header.clone())) +                                            }); + +                                            match result { +                                            Ok(rsp) => match rsp { +                                                EditorUsernameGetResponse::FetchGenericInformationAboutAnEditor + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(200).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_GET_FETCH_GENERIC_INFORMATION_ABOUT_AN_EDITOR.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                EditorUsernameGetResponse::UsernameNotFound + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(404).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_GET_USERNAME_NOT_FOUND.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                EditorUsernameGetResponse::GenericErrorResponse + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(0).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::EDITOR_USERNAME_GET_GENERIC_ERROR_RESPONSE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response.set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            }, +                                        } + +                                            future::ok(response) +                                        }, +                                    ), +                                ) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // FileIdGet - GET /file/{id} +            &hyper::Method::Get if path.matched(paths::ID_FILE_ID) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Path parameters +                let path = uri.path().to_string(); +                let path_params = paths::REGEX_FILE_ID.captures(&path).unwrap_or_else(|| { +                    panic!( +                        "Path {} matched RE FILE_ID in set but failed match against \"{}\"", +                        path, +                        paths::REGEX_FILE_ID.as_str() +                    ) +                }); + +                let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) +                    .decode_utf8() +                { +                    Ok(param_id) => match param_id.parse::<String>() { +                        Ok(param_id) => param_id, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't parse path parameter id: {}", e)), +                            )) +                        } +                    }, +                    Err(_) => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body(format!( +                                    "Couldn't percent-decode path parameter as UTF-8: {}", +                                    &path_params["id"] +                                )), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.file_id_get(param_id, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                FileIdGetResponse::FetchASingleFileById(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(200).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::FILE_ID_GET_FETCH_A_SINGLE_FILE_BY_ID.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                FileIdGetResponse::BadRequest(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(400).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::FILE_ID_GET_BAD_REQUEST.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                FileIdGetResponse::GenericErrorResponse(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(0).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::FILE_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response +                                                    .set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            } +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // FileLookupGet - GET /file/lookup +            &hyper::Method::Get if path.matched(paths::ID_FILE_LOOKUP) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) +                let query_params = form_urlencoded::parse( +                    uri.query().unwrap_or_default().as_bytes(), +                ).collect::<Vec<_>>(); +                let param_sha1 = query_params +                    .iter() +                    .filter(|e| e.0 == "sha1") +                    .map(|e| e.1.to_owned()) +                    .nth(0); +                let param_sha1 = match param_sha1 { +                    Some(param_sha1) => match param_sha1.parse::<String>() { +                        Ok(param_sha1) => param_sha1, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!( +                                "Couldn't parse query parameter sha1 - doesn't match schema: {}", +                                e +                            )), +                            )) +                        } +                    }, +                    None => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body("Missing required query parameter sha1"), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.file_lookup_get(param_sha1, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                FileLookupGetResponse::FindASingleFileByExternalIdentifer + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(200).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_FIND_A_SINGLE_FILE_BY_EXTERNAL_IDENTIFER.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                FileLookupGetResponse::BadRequest + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(400).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_BAD_REQUEST.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                FileLookupGetResponse::NoSuchFile + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(404).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_NO_SUCH_FILE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                FileLookupGetResponse::GenericErrorResponse + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(0).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::FILE_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response.set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            }, +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // FilePost - POST /file +            &hyper::Method::Post if path.matched(paths::ID_FILE) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Body parameters (note that non-required body parameters will ignore garbage +                // values, rather than causing a 400 response). Produce warning header and logs for +                // any unused fields. +                Box::new(body.concat2().then( +                    move |result| -> Box<Future<Item = Response, Error = Error>> { +                        match result { +                            Ok(body) => { +                                let mut unused_elements = Vec::new(); +                                let param_body: Option< +                                    models::FileEntity, +                                > = if !body.is_empty() { +                                    let deserializer = +                                        &mut serde_json::Deserializer::from_slice(&*body); + +                                    match serde_ignored::deserialize(deserializer, |path| { +                                        warn!("Ignoring unknown field in body: {}", path); +                                        unused_elements.push(path.to_string()); +                                    }) { +                                        Ok(param_body) => param_body, + +                                        Err(_) => None, +                                    } +                                } else { +                                    None +                                }; + +                                Box::new(api_impl.file_post(param_body, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        if !unused_elements.is_empty() { +                                            response.headers_mut().set(Warning(format!( +                                                "Ignoring unknown fields in body: {:?}", +                                                unused_elements +                                            ))); +                                        } + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                FilePostResponse::Created(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(201).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType( +                                                        mimetypes::responses::FILE_POST_CREATED +                                                            .clone(), +                                                    )); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                FilePostResponse::BadRequest(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(400).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType( +                                                        mimetypes::responses::FILE_POST_BAD_REQUEST +                                                            .clone(), +                                                    )); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                FilePostResponse::GenericErrorResponse(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(0).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::FILE_POST_GENERIC_ERROR_RESPONSE.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response +                                                    .set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            } +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                            Err(e) => Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't read body parameter body: {}", e)), +                            )), +                        } +                    }, +                )) as Box<Future<Item = Response, Error = Error>> +            } + +            // ReleaseIdGet - GET /release/{id} +            &hyper::Method::Get if path.matched(paths::ID_RELEASE_ID) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Path parameters +                let path = uri.path().to_string(); +                let path_params = paths::REGEX_RELEASE_ID.captures(&path).unwrap_or_else(|| { +                    panic!( +                        "Path {} matched RE RELEASE_ID in set but failed match against \"{}\"", +                        path, +                        paths::REGEX_RELEASE_ID.as_str() +                    ) +                }); + +                let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) +                    .decode_utf8() +                { +                    Ok(param_id) => match param_id.parse::<String>() { +                        Ok(param_id) => param_id, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't parse path parameter id: {}", e)), +                            )) +                        } +                    }, +                    Err(_) => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body(format!( +                                    "Couldn't percent-decode path parameter as UTF-8: {}", +                                    &path_params["id"] +                                )), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.release_id_get(param_id, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                ReleaseIdGetResponse::FetchASingleReleaseById( +                                                    body, +                                                ) => { +                                                    response.set_status( +                                                        StatusCode::try_from(200).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_ID_GET_FETCH_A_SINGLE_RELEASE_BY_ID.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                ReleaseIdGetResponse::BadRequest(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(400).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_ID_GET_BAD_REQUEST.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                ReleaseIdGetResponse::GenericErrorResponse( +                                                    body, +                                                ) => { +                                                    response.set_status( +                                                        StatusCode::try_from(0).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response +                                                    .set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            } +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // ReleaseLookupGet - GET /release/lookup +            &hyper::Method::Get if path.matched(paths::ID_RELEASE_LOOKUP) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) +                let query_params = form_urlencoded::parse( +                    uri.query().unwrap_or_default().as_bytes(), +                ).collect::<Vec<_>>(); +                let param_doi = query_params +                    .iter() +                    .filter(|e| e.0 == "doi") +                    .map(|e| e.1.to_owned()) +                    .nth(0); +                let param_doi = match param_doi { +                    Some(param_doi) => match param_doi.parse::<String>() { +                        Ok(param_doi) => param_doi, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!( +                                    "Couldn't parse query parameter doi - doesn't match schema: {}", +                                    e +                                )), +                            )) +                        } +                    }, +                    None => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body("Missing required query parameter doi"), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.release_lookup_get(param_doi, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                ReleaseLookupGetResponse::FindASingleReleaseByExternalIdentifer + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(200).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_FIND_A_SINGLE_RELEASE_BY_EXTERNAL_IDENTIFER.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                ReleaseLookupGetResponse::BadRequest + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(400).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_BAD_REQUEST.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                ReleaseLookupGetResponse::NoSuchRelease + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(404).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_NO_SUCH_RELEASE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                                ReleaseLookupGetResponse::GenericErrorResponse + +                                                    (body) + + +                                                => { +                                                    response.set_status(StatusCode::try_from(0).unwrap()); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_LOOKUP_GET_GENERIC_ERROR_RESPONSE.clone())); + + +                                                    let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                }, +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response.set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            }, +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // ReleasePost - POST /release +            &hyper::Method::Post if path.matched(paths::ID_RELEASE) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Body parameters (note that non-required body parameters will ignore garbage +                // values, rather than causing a 400 response). Produce warning header and logs for +                // any unused fields. +                Box::new(body.concat2().then( +                    move |result| -> Box<Future<Item = Response, Error = Error>> { +                        match result { +                            Ok(body) => { +                                let mut unused_elements = Vec::new(); +                                let param_body: Option< +                                    models::ReleaseEntity, +                                > = if !body.is_empty() { +                                    let deserializer = +                                        &mut serde_json::Deserializer::from_slice(&*body); + +                                    match serde_ignored::deserialize(deserializer, |path| { +                                        warn!("Ignoring unknown field in body: {}", path); +                                        unused_elements.push(path.to_string()); +                                    }) { +                                        Ok(param_body) => param_body, + +                                        Err(_) => None, +                                    } +                                } else { +                                    None +                                }; + +                                Box::new(api_impl.release_post(param_body, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        if !unused_elements.is_empty() { +                                            response.headers_mut().set(Warning(format!( +                                                "Ignoring unknown fields in body: {:?}", +                                                unused_elements +                                            ))); +                                        } + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                ReleasePostResponse::Created(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(201).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType( +                                                        mimetypes::responses::RELEASE_POST_CREATED +                                                            .clone(), +                                                    )); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                ReleasePostResponse::BadRequest(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(400).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_POST_BAD_REQUEST.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                ReleasePostResponse::GenericErrorResponse(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(0).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::RELEASE_POST_GENERIC_ERROR_RESPONSE.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response +                                                    .set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            } +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                            Err(e) => Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't read body parameter body: {}", e)), +                            )), +                        } +                    }, +                )) as Box<Future<Item = Response, Error = Error>> +            } + +            // WorkIdGet - GET /work/{id} +            &hyper::Method::Get if path.matched(paths::ID_WORK_ID) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Path parameters +                let path = uri.path().to_string(); +                let path_params = paths::REGEX_WORK_ID.captures(&path).unwrap_or_else(|| { +                    panic!( +                        "Path {} matched RE WORK_ID in set but failed match against \"{}\"", +                        path, +                        paths::REGEX_WORK_ID.as_str() +                    ) +                }); + +                let param_id = match percent_encoding::percent_decode(path_params["id"].as_bytes()) +                    .decode_utf8() +                { +                    Ok(param_id) => match param_id.parse::<String>() { +                        Ok(param_id) => param_id, +                        Err(e) => { +                            return Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't parse path parameter id: {}", e)), +                            )) +                        } +                    }, +                    Err(_) => { +                        return Box::new(future::ok( +                            Response::new() +                                .with_status(StatusCode::BadRequest) +                                .with_body(format!( +                                    "Couldn't percent-decode path parameter as UTF-8: {}", +                                    &path_params["id"] +                                )), +                        )) +                    } +                }; + +                Box::new( +                    ({ +                        { +                            { +                                Box::new(api_impl.work_id_get(param_id, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                WorkIdGetResponse::FetchASingleWorkById(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(200).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::WORK_ID_GET_FETCH_A_SINGLE_WORK_BY_ID.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                WorkIdGetResponse::BadRequest(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(400).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::WORK_ID_GET_BAD_REQUEST.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                WorkIdGetResponse::GenericErrorResponse(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(0).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::WORK_ID_GET_GENERIC_ERROR_RESPONSE.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response +                                                    .set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            } +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                        } +                    }), +                ) as Box<Future<Item = Response, Error = Error>> +            } + +            // WorkPost - POST /work +            &hyper::Method::Post if path.matched(paths::ID_WORK) => { +                if context.x_span_id.is_none() { +                    context.x_span_id = Some( +                        headers +                            .get::<XSpanId>() +                            .map(XSpanId::to_string) +                            .unwrap_or_else(|| self::uuid::Uuid::new_v4().to_string()), +                    ); +                } + +                // Body parameters (note that non-required body parameters will ignore garbage +                // values, rather than causing a 400 response). Produce warning header and logs for +                // any unused fields. +                Box::new(body.concat2().then( +                    move |result| -> Box<Future<Item = Response, Error = Error>> { +                        match result { +                            Ok(body) => { +                                let mut unused_elements = Vec::new(); +                                let param_body: Option< +                                    models::WorkEntity, +                                > = if !body.is_empty() { +                                    let deserializer = +                                        &mut serde_json::Deserializer::from_slice(&*body); + +                                    match serde_ignored::deserialize(deserializer, |path| { +                                        warn!("Ignoring unknown field in body: {}", path); +                                        unused_elements.push(path.to_string()); +                                    }) { +                                        Ok(param_body) => param_body, + +                                        Err(_) => None, +                                    } +                                } else { +                                    None +                                }; + +                                Box::new(api_impl.work_post(param_body, &context).then( +                                    move |result| { +                                        let mut response = Response::new(); +                                        context.x_span_id.as_ref().map(|header| { +                                            response.headers_mut().set(XSpanId(header.clone())) +                                        }); + +                                        if !unused_elements.is_empty() { +                                            response.headers_mut().set(Warning(format!( +                                                "Ignoring unknown fields in body: {:?}", +                                                unused_elements +                                            ))); +                                        } + +                                        match result { +                                            Ok(rsp) => match rsp { +                                                WorkPostResponse::Created(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(201).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType( +                                                        mimetypes::responses::WORK_POST_CREATED +                                                            .clone(), +                                                    )); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                WorkPostResponse::BadRequest(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(400).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType( +                                                        mimetypes::responses::WORK_POST_BAD_REQUEST +                                                            .clone(), +                                                    )); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                                WorkPostResponse::GenericErrorResponse(body) => { +                                                    response.set_status( +                                                        StatusCode::try_from(0).unwrap(), +                                                    ); + +                                                    response.headers_mut().set(ContentType(mimetypes::responses::WORK_POST_GENERIC_ERROR_RESPONSE.clone())); + +                                                    let body = serde_json::to_string(&body) +                                                        .expect("impossible to fail to serialize"); + +                                                    response.set_body(body); +                                                } +                                            }, +                                            Err(_) => { +                                                // Application code returned an error. This should not happen, as the implementation should +                                                // return a valid response. +                                                response +                                                    .set_status(StatusCode::InternalServerError); +                                                response.set_body("An internal error occurred"); +                                            } +                                        } + +                                        future::ok(response) +                                    }, +                                )) +                            } +                            Err(e) => Box::new(future::ok( +                                Response::new() +                                    .with_status(StatusCode::BadRequest) +                                    .with_body(format!("Couldn't read body parameter body: {}", e)), +                            )), +                        } +                    }, +                )) as Box<Future<Item = Response, Error = Error>> +            } + +            _ => Box::new(future::ok( +                Response::new().with_status(StatusCode::NotFound), +            )) as Box<Future<Item = Response, Error = Error>>, +        } +    } +}  | 
