Add newtype body field support for responses.
This commit is contained in:
parent
58fab938b0
commit
35362e78a6
23
src/api.rs
23
src/api.rs
@ -54,7 +54,28 @@ impl ToTokens for Api {
|
|||||||
Tokens::new()
|
Tokens::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let deserialize_response_body = if self.response.has_body_fields() {
|
let deserialize_response_body = if let Some(field) = self.response.newtype_body_field() {
|
||||||
|
let field_type = &field.ty;
|
||||||
|
let mut tokens = Tokens::new();
|
||||||
|
|
||||||
|
tokens.append(quote! {
|
||||||
|
let future_response = hyper_response.body()
|
||||||
|
.fold::<_, _, Result<_, ::std::io::Error>>(Vec::new(), |mut bytes, chunk| {
|
||||||
|
bytes.write_all(&chunk)?;
|
||||||
|
|
||||||
|
Ok(bytes)
|
||||||
|
})
|
||||||
|
.map_err(::ruma_api::Error::from)
|
||||||
|
.and_then(|bytes| {
|
||||||
|
::serde_json::from_slice::<#field_type>(bytes.as_slice())
|
||||||
|
.map_err(::ruma_api::Error::from)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
tokens.append(".and_then(|response_body| {");
|
||||||
|
|
||||||
|
tokens
|
||||||
|
} else if self.response.has_body_fields() {
|
||||||
let mut tokens = Tokens::new();
|
let mut tokens = Tokens::new();
|
||||||
|
|
||||||
tokens.append(quote! {
|
tokens.append(quote! {
|
||||||
|
@ -38,15 +38,40 @@ impl Response {
|
|||||||
.expect("missing expected request header: {}", #field_name),
|
.expect("missing expected request header: {}", #field_name),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
ResponseField::NewtypeBody(ref field) => {
|
||||||
|
let field_name = field.ident.as_ref()
|
||||||
|
.expect("expected body field to have a name");
|
||||||
|
|
||||||
|
tokens.append(quote! {
|
||||||
|
#field_name: response_body,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens
|
tokens
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn newtype_body_field(&self) -> Option<&Field> {
|
||||||
|
for response_field in self.fields.iter() {
|
||||||
|
match *response_field {
|
||||||
|
ResponseField::NewtypeBody(ref field) => {
|
||||||
|
|
||||||
|
return Some(field);
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<Field>> for Response {
|
impl From<Vec<Field>> for Response {
|
||||||
fn from(fields: Vec<Field>) -> Self {
|
fn from(fields: Vec<Field>) -> Self {
|
||||||
|
let mut has_newtype_body = false;
|
||||||
|
|
||||||
let response_fields = fields.into_iter().map(|mut field| {
|
let response_fields = fields.into_iter().map(|mut field| {
|
||||||
let mut response_field_kind = ResponseFieldKind::Body;
|
let mut response_field_kind = ResponseFieldKind::Body;
|
||||||
|
|
||||||
@ -67,7 +92,10 @@ impl From<Vec<Field>> for Response {
|
|||||||
NestedMetaItem::MetaItem(ref meta_item) => {
|
NestedMetaItem::MetaItem(ref meta_item) => {
|
||||||
match *meta_item {
|
match *meta_item {
|
||||||
MetaItem::Word(ref ident) => {
|
MetaItem::Word(ref ident) => {
|
||||||
if ident == "header" {
|
if ident == "body" {
|
||||||
|
has_newtype_body = true;
|
||||||
|
response_field_kind = ResponseFieldKind::NewtypeBody;
|
||||||
|
} else if ident == "header" {
|
||||||
response_field_kind = ResponseFieldKind::Header;
|
response_field_kind = ResponseFieldKind::Header;
|
||||||
} else {
|
} else {
|
||||||
panic!(
|
panic!(
|
||||||
@ -90,8 +118,15 @@ impl From<Vec<Field>> for Response {
|
|||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
match response_field_kind {
|
match response_field_kind {
|
||||||
ResponseFieldKind::Body => ResponseField::Body(field),
|
ResponseFieldKind::Body => {
|
||||||
|
if has_newtype_body {
|
||||||
|
panic!("ruma_api! responses cannot have both normal body fields and a newtype body field");
|
||||||
|
} else {
|
||||||
|
return ResponseField::Body(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
ResponseFieldKind::Header => ResponseField::Header(field),
|
ResponseFieldKind::Header => ResponseField::Header(field),
|
||||||
|
ResponseFieldKind::NewtypeBody => ResponseField::NewtypeBody(field),
|
||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
@ -118,6 +153,7 @@ impl ToTokens for Response {
|
|||||||
match *response {
|
match *response {
|
||||||
ResponseField::Body(ref field) => field.to_tokens(&mut tokens),
|
ResponseField::Body(ref field) => field.to_tokens(&mut tokens),
|
||||||
ResponseField::Header(ref field) => field.to_tokens(&mut tokens),
|
ResponseField::Header(ref field) => field.to_tokens(&mut tokens),
|
||||||
|
ResponseField::NewtypeBody(ref field) => field.to_tokens(&mut tokens),
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens.append(",");
|
tokens.append(",");
|
||||||
@ -153,6 +189,7 @@ impl ToTokens for Response {
|
|||||||
pub enum ResponseField {
|
pub enum ResponseField {
|
||||||
Body(Field),
|
Body(Field),
|
||||||
Header(Field),
|
Header(Field),
|
||||||
|
NewtypeBody(Field),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResponseField {
|
impl ResponseField {
|
||||||
@ -167,4 +204,5 @@ impl ResponseField {
|
|||||||
enum ResponseFieldKind {
|
enum ResponseFieldKind {
|
||||||
Body,
|
Body,
|
||||||
Header,
|
Header,
|
||||||
|
NewtypeBody,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user