Add request body to hyper requests.

This commit is contained in:
Jimmy Cuadra 2017-05-13 22:01:09 -07:00
parent ef3ee2d2f3
commit f48f1c1bee
4 changed files with 82 additions and 6 deletions

View File

@ -18,6 +18,11 @@ path = "../ruma-api"
features = ["full"]
version = "0.11.11"
[dev-dependencies]
serde = "1.0.4"
serde_derive = "1.0.4"
serde_json = "1.0.2"
[lib]
doctest = false
proc-macro = true

View File

@ -32,6 +32,23 @@ impl ToTokens for Api {
tokens
};
let add_body_to_request = if self.request.has_body_fields() {
let request_body_init_fields = self.request.request_body_init_fields();
quote! {
let request_body = RequestBody {
#request_body_init_fields
};
hyper_request.set_body(
::serde_json::to_vec(&request_body)
.expect("failed to serialize request body to JSON")
);
}
} else {
Tokens::new()
};
tokens.append(quote! {
use std::convert::TryFrom;
@ -45,12 +62,14 @@ impl ToTokens for Api {
type Error = ();
fn try_from(request: Request) -> Result<Self, Self::Error> {
Ok(
::hyper::Request::new(
let mut hyper_request = ::hyper::Request::new(
::hyper::#method,
"/".parse().expect("failed to parse request URI"),
)
)
);
#add_body_to_request
Ok(hyper_request)
}
}

View File

@ -10,6 +10,29 @@ impl Request {
pub fn has_body_fields(&self) -> bool {
self.fields.iter().any(|field| field.is_body())
}
pub fn request_body_init_fields(&self) -> Tokens {
let mut tokens = Tokens::new();
for request_field in self.body_fields() {
let field = match *request_field {
RequestField::Body(ref field) => field,
_ => panic!("expected body field"),
};
let field_name = field.ident.as_ref().expect("expected body field to have a name");
tokens.append(quote! {
#field_name: request.#field_name,
});
}
tokens
}
fn body_fields(&self) -> RequestBodyFields {
RequestBodyFields::new(&self.fields)
}
}
impl From<Vec<Field>> for Request {
@ -112,3 +135,30 @@ impl RequestField {
}
}
}
#[derive(Debug)]
pub struct RequestBodyFields<'a> {
fields: &'a [RequestField],
index: usize,
}
impl<'a> RequestBodyFields<'a> {
pub fn new(fields: &'a [RequestField]) -> Self {
RequestBodyFields {
fields,
index: 0,
}
}
}
impl<'a> Iterator for RequestBodyFields<'a> {
type Item = &'a RequestField;
fn next(&mut self) -> Option<&'a RequestField> {
let value = self.fields.get(self.index);
self.index += 1;
value
}
}

View File

@ -3,6 +3,8 @@
extern crate hyper;
extern crate ruma_api;
extern crate ruma_api_macros;
extern crate serde;
#[macro_use] extern crate serde_derive;
pub mod get_supported_versions {
use ruma_api_macros::ruma_api;