Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
rust-server.server-mod.mustache Maven / Gradle / Ivy
#![allow(unused_extern_crates)]
extern crate serde_ignored;
extern crate tokio_core;
extern crate native_tls;
extern crate hyper_tls;
extern crate openssl;
extern crate mime;
{{^apiUsesUuid}}extern crate uuid;{{/apiUsesUuid}}
extern crate chrono;
extern crate percent_encoding;
extern crate url;
{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}}
use std::sync::Arc;
use std::marker::PhantomData;
use futures::{Future, future, Stream, stream};
use hyper;
use hyper::{Request, Response, Error, StatusCode};
use hyper::header::{Headers, ContentType};
use self::url::form_urlencoded;
use mimetypes;
use serde_json;
{{#usesXml}}use serde_xml_rs;{{/usesXml}}
#[allow(unused_imports)]
use std::collections::{HashMap, BTreeMap};
#[allow(unused_imports)]
use swagger;
use std::io;
#[allow(unused_imports)]
use std::collections::BTreeSet;
pub use swagger::auth::Authorization;
use swagger::{ApiError, XSpanId, XSpanIdString, Has, RequestParser};
use swagger::auth::Scopes;
use {Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
};
#[allow(unused_imports)]
use models;
pub mod context;
header! { (Warning, "Warning") => [String] }
mod paths {
extern crate regex;
lazy_static! {
pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(&[
{{#pathSet}}
r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}"{{^-last}},{{/-last}}
{{/pathSet}}
]).unwrap();
}
{{#pathSet}}
pub static ID_{{{PATH_ID}}}: usize = {{{index}}};
{{#hasPathParams}}
lazy_static! {
pub static ref REGEX_{{{PATH_ID}}}: regex::Regex = regex::Regex::new(r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}").unwrap();
}
{{/hasPathParams}}
{{/pathSet}}
}
pub struct NewService {
api_impl: Arc,
marker: PhantomData,
}
impl NewService
where
T: Api + Clone + 'static,
C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + 'static
{
pub fn new>>(api_impl: U) -> NewService {
NewService{api_impl: api_impl.into(), marker: PhantomData}
}
}
impl hyper::server::NewService for NewService
where
T: Api + Clone + 'static,
C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + 'static
{
type Request = (Request, C);
type Response = Response;
type Error = Error;
type Instance = Service;
fn new_service(&self) -> Result {
Ok(Service::new(self.api_impl.clone()))
}
}
pub struct Service {
api_impl: Arc,
marker: PhantomData,
}
impl Service
where
T: Api + Clone + 'static,
C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + 'static {
pub fn new>>(api_impl: U) -> Service {
Service{api_impl: api_impl.into(), marker: PhantomData}
}
}
impl hyper::server::Service for Service
where
T: Api + Clone + 'static,
C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + 'static
{
type Request = (Request, C);
type Response = Response;
type Error = Error;
type Future = Box>;
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());
// This match statement is duplicated below in `parse_operation_id()`.
// Please update both places if changing how this code is autogenerated.
match &method {
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
&hyper::Method::{{vendorExtensions.HttpMethod}} if path.matched(paths::ID_{{vendorExtensions.PATH_ID}}) => {
{{#hasAuthMethods}}
{
let authorization = match (&context as &Has>).get() {
&Some(ref authorization) => authorization,
&None => return Box::new(future::ok(Response::new()
.with_status(StatusCode::Forbidden)
.with_body("Unauthenticated"))),
};
{{#authMethods}}
{{#isOAuth}}
// Authorization
if let Scopes::Some(ref scopes) = authorization.scopes {
let required_scopes: BTreeSet = vec![
{{#scopes}}
"{{{scope}}}".to_string(), // {{{description}}}
{{/scopes}}
].into_iter().collect();
if !required_scopes.is_subset(scopes) {
let missing_scopes = required_scopes.difference(scopes);
return Box::new(future::ok(Response::new()
.with_status(StatusCode::Forbidden)
.with_body(missing_scopes.fold(
"Insufficient authorization, missing scopes".to_string(),
|s, scope| format!("{} {}", s, scope)
))
));
}
}
{{/isOAuth}}
{{/authMethods}}
}
{{/hasAuthMethods}}
{{#vendorExtensions}}{{#hasPathParams}}
// Path parameters
let path = uri.path().to_string();
let path_params =
paths::REGEX_{{{PATH_ID}}}
.captures(&path)
.unwrap_or_else(||
panic!("Path {} matched RE {{{PATH_ID}}} in set but failed match against \"{}\"", path, paths::REGEX_{{{PATH_ID}}}.as_str())
);
{{/hasPathParams}}{{/vendorExtensions}}
{{#pathParams}}
let param_{{{paramName}}} = match percent_encoding::percent_decode(path_params["{{{baseName}}}"].as_bytes()).decode_utf8() {
Ok(param_{{{paramName}}}) => match param_{{{paramName}}}.parse::<{{{dataType}}}>() {
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter {{{baseName}}}: {}", 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["{{{baseName}}}"]))))
};
{{/pathParams}}
{{#headerParams}}{{#-first}}
// Header parameters
{{/-first}}
header! { (Request{{vendorExtensions.typeName}}, "{{{baseName}}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} }
{{#required}}
let param_{{{paramName}}} = match headers.get::() {
Some(param_{{{paramName}}}) => param_{{{paramName}}}.0.clone(),
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing or invalid required header {{{baseName}}}"))),
};
{{/required}}
{{^required}}
let param_{{{paramName}}} = headers.get::().map(|header| header.0.clone());
{{/required}}{{/headerParams}}
{{#queryParams}}{{#-first}}
// 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::>();
{{/-first}}
let param_{{{paramName}}} = query_params.iter().filter(|e| e.0 == "{{{baseName}}}").map(|e| e.1.to_owned())
{{#isListContainer}}
.filter_map(|param_{{{paramName}}}| param_{{{paramName}}}.parse::<{{{baseType}}}>().ok())
.collect::>();
{{^required}}
let param_{{{paramName}}} = if !param_{{{paramName}}}.is_empty() {
Some(param_{{{paramName}}})
} else {
None
};
{{/required}}
{{/isListContainer}}{{^isListContainer}}
.nth(0);
{{#required}}
let param_{{{paramName}}} = match param_{{{paramName}}} {
Some(param_{{{paramName}}}) => match param_{{{paramName}}}.parse::<{{{dataType}}}>() {
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {}", e)))),
},
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required query parameter {{{baseName}}}"))),
};
{{/required}}{{^required}}
let param_{{{paramName}}} = param_{{{paramName}}}.and_then(|param_{{{paramName}}}| param_{{{paramName}}}.parse::<{{{baseType}}}>().ok());
{{/required}}
{{/isListContainer}}
{{/queryParams}}
{{#bodyParams}}{{#-first}}
// 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> {
match result {
Ok(body) => {
{{#vendorExtensions}}{{^consumesPlainText}}
let mut unused_elements = Vec::new();
{{/consumesPlainText}}
let param_{{{paramName}}}: Option<{{{dataType}}}> = if !body.is_empty() {
{{#consumesXml}}
let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body);
{{/consumesXml}}{{#consumesJson}}
let deserializer = &mut serde_json::Deserializer::from_slice(&*body);
{{/consumesJson}}{{^consumesPlainText}}
match serde_ignored::deserialize(deserializer, |path| {
warn!("Ignoring unknown field in body: {}", path);
unused_elements.push(path.to_string());
}) {
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
{{#required}}
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter {{{baseName}}} - doesn't match schema: {}", e)))),
{{/required}}{{^required}}
Err(_) => None,
{{/required}}
}
{{/consumesPlainText}}{{#consumesPlainText}}
match String::from_utf8(body.to_vec()) {
Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}),
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter {{{baseName}}} - not valid UTF-8: {}", e)))),
}
{{/consumesPlainText}}{{/vendorExtensions}}
} else {
None
};
{{#required}}
let param_{{{paramName}}} = match param_{{{paramName}}} {
Some(param_{{{paramName}}}) => param_{{{paramName}}},
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter {{{baseName}}}"))),
};
{{/required}}
{{/-first}}{{/bodyParams}}
{{^bodyParams}}{{#vendorExtensions}}
Box::new({
{{
{{#formParams}}{{#-first}}
// Form parameters
{{/-first}}
let param_{{{paramName}}} = {{^isContainer}}{{#vendorExtensions}}{{{example}}};{{/vendorExtensions}}{{/isContainer}}{{#isListContainer}}{{#required}}Vec::new();{{/required}}{{^required}}None;{{/required}}{{/isListContainer}}{{#isMapContainer}}None;{{/isMapContainer}}
{{/formParams}}
{{/vendorExtensions}}{{/bodyParams}}
Box::new(api_impl.{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}({{#allParams}}param_{{{paramName}}}{{#isListContainer}}.as_ref(){{/isListContainer}}, {{/allParams}}&context)
.then(move |result| {
let mut response = Response::new();
response.headers_mut().set(XSpanId((&context as &Has).get().0.to_string()));
{{#bodyParams}}{{#vendorExtensions}}{{^consumesPlainText}}
if !unused_elements.is_empty() {
response.headers_mut().set(Warning(format!("Ignoring unknown fields in body: {:?}", unused_elements)));
}
{{/consumesPlainText}}{{/vendorExtensions}}{{/bodyParams}}
match result {
Ok(rsp) => match rsp {
{{#responses}}
{{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}
{{#dataType}}{{^headers}}
(body)
{{/headers}}{{#headers}}
{{#-first}}
{
body,
{{/-first}}
{{{name}}}{{^-last}}, {{/-last}}
{{#-last}}
}
{{/-last}}
{{/headers}}{{/dataType}}
{{^dataType}}{{#headers}}{{#-first}}
{
{{/-first}}
{{{name}}}{{^-last}}, {{/-last}}
{{#-last}}
}
{{/-last}}
{{/headers}}{{/dataType}}
=> {
response.set_status(StatusCode::try_from({{{code}}}).unwrap());
{{#headers}}
header! { (Response{{{nameInCamelCase}}}, "{{{baseName}}}") => [{{{dataType}}}] }
response.headers_mut().set(Response{{{nameInCamelCase}}}({{{name}}}));
{{/headers}}
{{#produces}}{{#-first}}{{#dataType}}
response.headers_mut().set(ContentType(mimetypes::responses::{{#vendorExtensions}}{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}.clone()));
{{/dataType}}{{/-first}}{{/produces}}
{{#dataType}}
{{#vendorExtensions}}{{#producesXml}}{{^has_namespace}}
let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize");
{{/has_namespace}}{{#has_namespace}}
let mut namespaces = BTreeMap::new();
// An empty string is used to indicate a global namespace in xmltree.
namespaces.insert("".to_string(), models::namespaces::{{{uppercase_data_type}}}.clone());
let body = serde_xml_rs::to_string_with_namespaces(&body, namespaces).expect("impossible to fail to serialize");
{{/has_namespace}}{{/producesXml}}{{#producesJson}}
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
{{/producesJson}}{{/vendorExtensions}}
response.set_body(body);
{{/dataType}}
},
{{/responses}}
},
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)
}
))
{{^bodyParams}}{{#vendorExtensions}}
}}
}) as Box>
{{/vendorExtensions}}{{/bodyParams}}
{{#bodyParams}}{{#-first}}
},
Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter {{{baseName}}}: {}", e)))),
}
})
) as Box>
{{/-first}}{{/bodyParams}}
},
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
_ => Box::new(future::ok(Response::new().with_status(StatusCode::NotFound))) as Box>,
}
}
}
impl Clone for Service
{
fn clone(&self) -> Self {
Service {
api_impl: self.api_impl.clone(),
marker: self.marker.clone(),
}
}
}
/// Request parser for `Api`.
pub struct ApiRequestParser;
impl RequestParser for ApiRequestParser {
fn parse_operation_id(request: &Request) -> Result<&'static str, ()> {
let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path());
match request.method() {
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
&hyper::Method::{{{vendorExtensions.HttpMethod}}} if path.matched(paths::ID_{{{vendorExtensions.PATH_ID}}}) => Ok("{{{operationId}}}"),
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} _ => Err(()),
}
}
}