From 8f6bc5af77007251988bcadbf91e2bee5f5129bd Mon Sep 17 00:00:00 2001 From: Jimmy Cuadra Date: Fri, 11 May 2018 08:50:39 -0700 Subject: [PATCH] Fix remaining compiler errors. --- src/api/metadata.rs | 65 ++++++++++++++++++++++++++++++++--------- src/api/mod.rs | 62 ++++++++++++++++++++++----------------- src/api/request.rs | 61 +++++++++++++++++++-------------------- src/api/response.rs | 70 ++++++++++++++++++++++++--------------------- 4 files changed, 156 insertions(+), 102 deletions(-) diff --git a/src/api/metadata.rs b/src/api/metadata.rs index 68290d0c..a2847c54 100644 --- a/src/api/metadata.rs +++ b/src/api/metadata.rs @@ -22,43 +22,82 @@ impl From for Metadata { let mut requires_authentication = None; for field in expr.fields { - let Member::Named(identifier) = field.member; + let identifier = match field.member { + Member::Named(identifier) => identifier, + _ => panic!("expected Member::Named"), + }; match identifier.as_ref() { "description" => { - let Expr::Lit(expr_lit) = field.expr; - let Lit::Str(lit_str) = expr_lit.lit; + let expr_lit = match field.expr { + Expr::Lit(expr_lit) => expr_lit, + _ => panic!("expected Expr::Lit"), + }; + let lit_str = match expr_lit.lit { + Lit::Str(lit_str) => lit_str, + _ => panic!("expected Lit::Str"), + }; description = Some(lit_str.value()); } "method" => { - let Expr::Path(expr_path) = field.expr; + let expr_path = match field.expr { + Expr::Path(expr_path) => expr_path, + _ => panic!("expected Expr::Path"), + }; let path = expr_path.path; let segments = path.segments; if segments.len() != 1 { panic!("ruma_api! expects a one component path for `metadata` `method`"); } let pair = segments.first().unwrap(); // safe because we just checked - let Pair::End(method_name) = pair; + let method_name = match pair { + Pair::End(method_name) => method_name, + _ => panic!("expected Pair::End"), + }; method = Some(method_name.ident.to_string()); } "name" => { - let Expr::Lit(expr_lit) = field.expr; - let Lit::Str(lit_str) = expr_lit.lit; + let expr_lit = match field.expr { + Expr::Lit(expr_lit) => expr_lit, + _ => panic!("expected Expr::Lit"), + }; + let lit_str = match expr_lit.lit { + Lit::Str(lit_str) => lit_str, + _ => panic!("expected Lit::Str"), + }; name = Some(lit_str.value()); } "path" => { - let Expr::Lit(expr_lit) = field.expr; - let Lit::Str(lit_str) = expr_lit.lit; + let expr_lit = match field.expr { + Expr::Lit(expr_lit) => expr_lit, + _ => panic!("expected Expr::Lit"), + }; + let lit_str = match expr_lit.lit { + Lit::Str(lit_str) => lit_str, + _ => panic!("expected Lit::Str"), + }; path = Some(lit_str.value()); } "rate_limited" => { - let Expr::Lit(expr_lit) = field.expr; - let Lit::Bool(lit_bool) = expr_lit.lit; + let expr_lit = match field.expr { + Expr::Lit(expr_lit) => expr_lit, + _ => panic!("expected Expr::Lit"), + }; + let lit_bool = match expr_lit.lit { + Lit::Bool(lit_bool) => lit_bool, + _ => panic!("expected Lit::Bool"), + }; rate_limited = Some(lit_bool.value) } "requires_authentication" => { - let Expr::Lit(expr_lit) = field.expr; - let Lit::Bool(lit_bool) = expr_lit.lit; + let expr_lit = match field.expr { + Expr::Lit(expr_lit) => expr_lit, + _ => panic!("expected Expr::Lit"), + }; + let lit_bool = match expr_lit.lit { + Lit::Bool(lit_bool) => lit_bool, + _ => panic!("expected Lit::Bool"), + }; requires_authentication = Some(lit_bool.value) } _ => panic!("ruma_api! metadata included unexpected field"), diff --git a/src/api/mod.rs b/src/api/mod.rs index 8a4967e6..1f72ef0d 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,7 +1,7 @@ use quote::{ToTokens, Tokens}; use syn::punctuated::Pair; use syn::synom::Synom; -use syn::{Expr, FieldValue, Ident, Meta}; +use syn::{Expr, FieldValue, Ident, Member, Meta}; mod metadata; mod request; @@ -18,7 +18,10 @@ pub fn strip_serde_attrs(field_value: &FieldValue) -> FieldValue { let meta = attr.interpret_meta() .expect("ruma_api! could not parse field attributes"); - let Meta::List(meta_list) = meta; + let meta_list = match meta { + Meta::List(meta_list) => meta_list, + _ => panic!("expected Meta::List"), + }; if meta_list.ident.as_ref() != "serde" { return true; @@ -52,13 +55,16 @@ impl From> for Api { _ => panic!("ruma_api! blocks should use struct syntax"), }; - let segments = expr.path.segments; + let segments = expr.path.segments.clone(); if segments.len() != 1 { panic!("ruma_api! blocks must be one of: metadata, request, or response"); } - let Pair::End(last_segment) = segments.last().unwrap(); + let last_segment = match segments.last().unwrap() { + Pair::End(last_segment) => last_segment, + _ => panic!("expected Pair::End"), + }; match last_segment.ident.as_ref() { "metadata" => metadata = Some(expr.into()), @@ -138,23 +144,21 @@ impl ToTokens for Api { }; for segment in path_str[1..].split('/') { - tokens.append(quote! { + tokens.append_all(quote! { path_segments.push }); - tokens.append("("); - if segment.starts_with(':') { - tokens.append("&request_path."); - tokens.append(&segment[1..]); - tokens.append(".to_string()"); - } else { - tokens.append("\""); - tokens.append(segment); - tokens.append("\""); - } + let what_is_this = &segment[1..]; - tokens.append(");"); + tokens.append_all(quote! { + (&request_path.#what_is_this.to_string()); + }); + } else { + tokens.append_all(quote! { + ("#segment"); + }); + } } tokens @@ -179,7 +183,10 @@ impl ToTokens for Api { }; let add_body_to_request = if let Some(field) = self.request.newtype_body_field() { - let field_name = field.ident.as_ref().expect("expected body field to have a name"); + let field_name = match field.member { + Member::Named(field_name) => field_name, + _ => panic!("expected Member::Named"), + }; quote! { let request_body = RequestBody(request.#field_name); @@ -201,10 +208,13 @@ impl ToTokens for Api { }; let deserialize_response_body = if let Some(field) = self.response.newtype_body_field() { - let field_type = &field.ty; + let field_type = match field.expr { + Expr::Path(ref field_type) => field_type, + _ => panic!("expected Expr::Path"), + }; let mut tokens = Tokens::new(); - tokens.append(quote! { + tokens.append_all(quote! { let future_response = hyper_response.body() .fold::<_, _, Result<_, ::std::io::Error>>(Vec::new(), |mut bytes, chunk| { bytes.write_all(&chunk)?; @@ -218,13 +228,13 @@ impl ToTokens for Api { }) }); - tokens.append(".and_then(move |response_body| {"); + tokens.append_all(".and_then(move |response_body| {".into_tokens()); tokens } else if self.response.has_body_fields() { let mut tokens = Tokens::new(); - tokens.append(quote! { + tokens.append_all(quote! { let future_response = hyper_response.body() .fold::<_, _, Result<_, ::std::io::Error>>(Vec::new(), |mut bytes, chunk| { bytes.write_all(&chunk)?; @@ -238,23 +248,23 @@ impl ToTokens for Api { }) }); - tokens.append(".and_then(move |response_body| {"); + tokens.append_all(".and_then(move |response_body| {".into_tokens()); tokens } else { let mut tokens = Tokens::new(); - tokens.append(quote! { + tokens.append_all(quote! { let future_response = ::futures::future::ok(()) }); - tokens.append(".and_then(move |_| {"); + tokens.append_all(".and_then(move |_| {".into_tokens()); tokens }; let mut closure_end = Tokens::new(); - closure_end.append("});"); + closure_end.append_all("});".into_tokens()); let extract_headers = if self.response.has_header_fields() { quote! { @@ -270,7 +280,7 @@ impl ToTokens for Api { Tokens::new() }; - tokens.append(quote! { + tokens.append_all(quote! { #[allow(unused_imports)] use std::io::Write as _Write; diff --git a/src/api/request.rs b/src/api/request.rs index b2ce32ea..b6f5b0cd 100644 --- a/src/api/request.rs +++ b/src/api/request.rs @@ -1,6 +1,6 @@ use quote::{ToTokens, Tokens}; use syn::synom::Synom; -use syn::{ExprStruct, Field, FieldValue, FieldsNamed, Meta, NestedMeta}; +use syn::{ExprStruct, Field, FieldValue, FieldsNamed, Member, Meta, NestedMeta}; use api::strip_serde_attrs; @@ -54,9 +54,12 @@ impl Request { let mut tokens = Tokens::new(); for field in self.fields.iter().flat_map(|f| f.field_(request_field_kind)) { - let field_name = field.ident.as_ref().expect("expected body field to have a name"); + let field_name = match field.member { + Member::Named(field_name) => field_name, + _ => panic!("expected Member::Named"), + }; - tokens.append(quote! { + tokens.append_all(quote! { #field_name: request.#field_name, }); } @@ -76,7 +79,10 @@ impl From for Request { let meta = attr.interpret_meta() .expect("ruma_api! could not parse request field attributes"); - let Meta::List(meta_list) = meta; + let meta_list = match meta { + Meta::List(meta_list) => meta_list, + _ => panic!("expected Meta::List"), + }; if meta_list.ident.as_ref() != "ruma_api" { return true; @@ -132,109 +138,102 @@ impl From for Request { impl ToTokens for Request { fn to_tokens(&self, mut tokens: &mut Tokens) { - tokens.append(quote! { + tokens.append_all(quote! { /// Data for a request to this API endpoint. #[derive(Debug)] pub struct Request }); if self.fields.len() == 0 { - tokens.append(";"); + tokens.append_all(";".into_tokens()); } else { - tokens.append("{"); + tokens.append_all("{".into_tokens()); for request_field in self.fields.iter() { strip_serde_attrs(request_field.field()).to_tokens(&mut tokens); - tokens.append(","); + tokens.append_all(",".into_tokens()); } - tokens.append("}"); + tokens.append_all("}".into_tokens()); } if let Some(newtype_body_field) = self.newtype_body_field() { let mut field = newtype_body_field.clone(); + let expr = field.expr; - field.ident = None; - - tokens.append(quote! { + tokens.append_all(quote! { /// Data in the request body. #[derive(Debug, Serialize)] - struct RequestBody + struct RequestBody(#expr); }); - - tokens.append("("); - - field.to_tokens(&mut tokens); - - tokens.append(");"); } else if self.has_body_fields() { - tokens.append(quote! { + tokens.append_all(quote! { /// Data in the request body. #[derive(Debug, Serialize)] struct RequestBody }); - tokens.append("{"); + tokens.append_all("{".into_tokens()); for request_field in self.fields.iter() { match *request_field { RequestField::Body(ref field) => { field.to_tokens(&mut tokens); - tokens.append(","); + tokens.append_all(",".into_tokens()); } _ => {} } } - tokens.append("}"); + tokens.append_all("}".into_tokens()); } if self.has_path_fields() { - tokens.append(quote! { + tokens.append_all(quote! { /// Data in the request path. #[derive(Debug, Serialize)] struct RequestPath }); - tokens.append("{"); + tokens.append_all("{".into_tokens()); for request_field in self.fields.iter() { match *request_field { RequestField::Path(ref field) => { field.to_tokens(&mut tokens); - tokens.append(","); + tokens.append_all(",".into_tokens()); } _ => {} } } - tokens.append("}"); + tokens.append_all("}".into_tokens()); } if self.has_query_fields() { - tokens.append(quote! { + tokens.append_all(quote! { /// Data in the request's query string. #[derive(Debug, Serialize)] struct RequestQuery }); - tokens.append("{"); + tokens.append_all("{".into_tokens()); for request_field in self.fields.iter() { match *request_field { RequestField::Query(ref field) => { field.to_tokens(&mut tokens); - tokens.append(","); + tokens.append_all(",".into_tokens()); } _ => {} } } - tokens.append("}"); + tokens.append_all("}".into_tokens()); } } } diff --git a/src/api/response.rs b/src/api/response.rs index 79ddfcb4..b7b7c514 100644 --- a/src/api/response.rs +++ b/src/api/response.rs @@ -1,5 +1,5 @@ use quote::{ToTokens, Tokens}; -use syn::{ExprStruct, Field, FieldValue, FieldsNamed, Meta, NestedMeta}; +use syn::{Expr, ExprStruct, Field, FieldValue, FieldsNamed, Member, Meta, NestedMeta}; use api::strip_serde_attrs; @@ -26,28 +26,38 @@ impl Response { for response_field in self.fields.iter() { match *response_field { ResponseField::Body(ref field) => { - let field_name = field.ident.as_ref() - .expect("expected body field to have a name"); + let field_name = match field.member { + Member::Named(field_name) => field_name, + _ => panic!("expected Member::Named"), + }; - tokens.append(quote! { + tokens.append_all(quote! { #field_name: response_body.#field_name, }); } ResponseField::Header(ref field) => { - let field_name = field.ident.as_ref() - .expect("expected body field to have a name"); - let field_type = &field.ty; + let field_name = match field.member { + Member::Named(field_name) => field_name, + _ => panic!("expected Member::Named"), + }; - tokens.append(quote! { + let field_type = match field.expr { + Expr::Path(ref field_type) => field_type, + _ => panic!("expected Expr::Path"), + }; + + tokens.append_all(quote! { #field_name: headers.remove::<#field_type>() .expect("missing expected request header"), }); } ResponseField::NewtypeBody(ref field) => { - let field_name = field.ident.as_ref() - .expect("expected body field to have a name"); + let field_name = match field.member { + Member::Named(field_name) => field_name, + _ => panic!("expected Member::Named"), + }; - tokens.append(quote! { + tokens.append_all(quote! { #field_name: response_body, }); } @@ -57,7 +67,7 @@ impl Response { tokens } - pub fn newtype_body_field(&self) -> Option<&Field> { + pub fn newtype_body_field(&self) -> Option<&FieldValue> { for response_field in self.fields.iter() { match *response_field { ResponseField::NewtypeBody(ref field) => { @@ -84,7 +94,10 @@ impl From for Response { let meta = attr.interpret_meta() .expect("ruma_api! could not parse response field attributes"); - let Meta::List(meta_list) = meta; + let meta_list = match meta { + Meta::List(meta_list) => meta_list, + _ => panic!("expected Meta::List"), + }; if meta_list.ident.as_ref() != "ruma_api" { return true; @@ -141,63 +154,56 @@ impl From for Response { impl ToTokens for Response { fn to_tokens(&self, mut tokens: &mut Tokens) { - tokens.append(quote! { + tokens.append_all(quote! { /// Data in the response from this API endpoint. #[derive(Debug)] pub struct Response }); if self.fields.len() == 0 { - tokens.append(";"); + tokens.append_all(";".into_tokens()); } else { - tokens.append("{"); + tokens.append_all("{".into_tokens()); for response_field in self.fields.iter() { strip_serde_attrs(response_field.field()).to_tokens(&mut tokens); - tokens.append(","); + tokens.append_all(",".into_tokens()); } - tokens.append("}"); + tokens.append_all("}".into_tokens()); } if let Some(newtype_body_field) = self.newtype_body_field() { let mut field = newtype_body_field.clone(); + let expr = field.expr; - field.ident = None; - - tokens.append(quote! { + tokens.append_all(quote! { /// Data in the response body. #[derive(Debug, Deserialize)] - struct ResponseBody + struct ResponseBody(#expr); }); - - tokens.append("("); - - field.to_tokens(&mut tokens); - - tokens.append(");"); } else if self.has_body_fields() { - tokens.append(quote! { + tokens.append_all(quote! { /// Data in the response body. #[derive(Debug, Deserialize)] struct ResponseBody }); - tokens.append("{"); + tokens.append_all("{".into_tokens()); for response_field in self.fields.iter() { match *response_field { ResponseField::Body(ref field) => { field.to_tokens(&mut tokens); - tokens.append(","); + tokens.append_all(",".into_tokens()); } _ => {} } } - tokens.append("}"); + tokens.append_all("}".into_tokens()); } } }