Refactor request module to reduce code duplication
This commit is contained in:
		
							parent
							
								
									170e00a487
								
							
						
					
					
						commit
						5180297d81
					
				| @ -155,7 +155,9 @@ impl ToTokens for Api { | |||||||
|                 fn try_from(request: Request) -> Result<Self, Self::Error> { |                 fn try_from(request: Request) -> Result<Self, Self::Error> { | ||||||
|                     let metadata = Endpoint::METADATA; |                     let metadata = Endpoint::METADATA; | ||||||
| 
 | 
 | ||||||
|                     // The homeserver url has to be overwritten in the calling code.
 |                     // Use dummy homeserver url which has to be overwritten in
 | ||||||
|  |                     // the calling code. Previously (with hyper::Uri) this was
 | ||||||
|  |                     // not required, but Url::parse only accepts absolute urls.
 | ||||||
|                     let mut url = ::url::Url::parse("http://invalid-host-please-change/").unwrap(); |                     let mut url = ::url::Url::parse("http://invalid-host-please-change/").unwrap(); | ||||||
|                     url.set_path(metadata.path); |                     url.set_path(metadata.path); | ||||||
|                     #set_request_query |                     #set_request_query | ||||||
|  | |||||||
| @ -19,7 +19,6 @@ impl Request { | |||||||
|         for request_field in self.fields.iter() { |         for request_field in self.fields.iter() { | ||||||
|             match *request_field { |             match *request_field { | ||||||
|                 RequestField::NewtypeBody(ref field) => { |                 RequestField::NewtypeBody(ref field) => { | ||||||
| 
 |  | ||||||
|                     return Some(field); |                     return Some(field); | ||||||
|                 } |                 } | ||||||
|                 _ => continue, |                 _ => continue, | ||||||
| @ -30,14 +29,17 @@ impl Request { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn request_body_init_fields(&self) -> Tokens { |     pub fn request_body_init_fields(&self) -> Tokens { | ||||||
|  |         self.struct_init_fields(RequestFieldKind::Body) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn request_query_init_fields(&self) -> Tokens { | ||||||
|  |         self.struct_init_fields(RequestFieldKind::Query) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn struct_init_fields(&self, request_field_kind: RequestFieldKind) -> Tokens { | ||||||
|         let mut tokens = Tokens::new(); |         let mut tokens = Tokens::new(); | ||||||
| 
 | 
 | ||||||
|         for request_field in self.body_fields() { |         for field in self.fields.iter().flat_map(|f| f.field_(request_field_kind)) { | ||||||
|             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"); |             let field_name = field.ident.as_ref().expect("expected body field to have a name"); | ||||||
| 
 | 
 | ||||||
|             tokens.append(quote! { |             tokens.append(quote! { | ||||||
| @ -47,33 +49,6 @@ impl Request { | |||||||
| 
 | 
 | ||||||
|         tokens |         tokens | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     pub fn request_query_init_fields(&self) -> Tokens { |  | ||||||
|         let mut tokens = Tokens::new(); |  | ||||||
| 
 |  | ||||||
|         for query_field in self.query_fields() { |  | ||||||
|             let field = match *query_field { |  | ||||||
|                 RequestField::Query(ref field) => field, |  | ||||||
|                 _ => panic!("expected query field"), |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             let field_name = field.ident.as_ref().expect("expected query field to have a name"); |  | ||||||
| 
 |  | ||||||
|             tokens.append(quote! { |  | ||||||
|                 #field_name: request.#field_name, |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         tokens |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn body_fields(&self) -> RequestBodyFields { |  | ||||||
|         RequestBodyFields::new(&self.fields) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn query_fields(&self) -> RequestQueryFields { |  | ||||||
|         RequestQueryFields::new(&self.fields) |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl From<Vec<Field>> for Request { | impl From<Vec<Field>> for Request { | ||||||
| @ -127,19 +102,14 @@ impl From<Vec<Field>> for Request { | |||||||
|                 false |                 false | ||||||
|             }).collect(); |             }).collect(); | ||||||
| 
 | 
 | ||||||
|             match request_field_kind { |             if request_field_kind == RequestFieldKind::Body { | ||||||
|                 RequestFieldKind::Body => { |                 assert!( | ||||||
|                     if has_newtype_body { |                     !has_newtype_body, | ||||||
|                         panic!("ruma_api! requests cannot have both normal body fields and a newtype body field"); |                     "ruma_api! requests cannot have both normal body fields and a newtype body field" | ||||||
|                     } else { |                 ); | ||||||
|                         return RequestField::Body(field); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 RequestFieldKind::Header => RequestField::Header(field), |  | ||||||
|                 RequestFieldKind::NewtypeBody => RequestField::NewtypeBody(field), |  | ||||||
|                 RequestFieldKind::Path => RequestField::Path(field), |  | ||||||
|                 RequestFieldKind::Query => RequestField::Query(field), |  | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             RequestField::new(request_field_kind, field) | ||||||
|         }).collect(); |         }).collect(); | ||||||
| 
 | 
 | ||||||
|         Request { |         Request { | ||||||
| @ -162,14 +132,7 @@ impl ToTokens for Request { | |||||||
|             tokens.append("{"); |             tokens.append("{"); | ||||||
| 
 | 
 | ||||||
|             for request_field in self.fields.iter() { |             for request_field in self.fields.iter() { | ||||||
|                 match *request_field { |                 request_field.field().to_tokens(&mut tokens); | ||||||
|                     RequestField::Body(ref field) => field.to_tokens(&mut tokens), |  | ||||||
|                     RequestField::Header(ref field) => field.to_tokens(&mut tokens), |  | ||||||
|                     RequestField::NewtypeBody(ref field) => field.to_tokens(&mut tokens), |  | ||||||
|                     RequestField::Path(ref field) => field.to_tokens(&mut tokens), |  | ||||||
|                     RequestField::Query(ref field) => field.to_tokens(&mut tokens), |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 tokens.append(","); |                 tokens.append(","); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -250,21 +213,54 @@ pub enum RequestField { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl RequestField { | impl RequestField { | ||||||
|     fn is_body(&self) -> bool { |     fn new(kind: RequestFieldKind, field: Field) -> RequestField { | ||||||
|         match *self { |         match kind { | ||||||
|             RequestField::Body(_) => true, |             RequestFieldKind::Body => RequestField::Body(field), | ||||||
|             _ => false, |             RequestFieldKind::Header => RequestField::Header(field), | ||||||
|  |             RequestFieldKind::NewtypeBody => RequestField::NewtypeBody(field), | ||||||
|  |             RequestFieldKind::Path => RequestField::Path(field), | ||||||
|  |             RequestFieldKind::Query => RequestField::Query(field), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn is_query(&self) -> bool { |     fn kind(&self) -> RequestFieldKind { | ||||||
|         match *self { |         match *self { | ||||||
|             RequestField::Query(_) => true, |             RequestField::Body(_) => RequestFieldKind::Body, | ||||||
|             _ => false, |             RequestField::Header(_) => RequestFieldKind::Header, | ||||||
|  |             RequestField::NewtypeBody(_) => RequestFieldKind::NewtypeBody, | ||||||
|  |             RequestField::Path(_) => RequestFieldKind::Path, | ||||||
|  |             RequestField::Query(_) => RequestFieldKind::Query, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn is_body(&self) -> bool { | ||||||
|  |         self.kind() == RequestFieldKind::Body | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn is_query(&self) -> bool { | ||||||
|  |         self.kind() == RequestFieldKind::Query | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn field(&self) -> &Field { | ||||||
|  |         match *self { | ||||||
|  |             RequestField::Body(ref field) => field, | ||||||
|  |             RequestField::Header(ref field) => field, | ||||||
|  |             RequestField::NewtypeBody(ref field) => field, | ||||||
|  |             RequestField::Path(ref field) => field, | ||||||
|  |             RequestField::Query(ref field) => field, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn field_(&self, kind: RequestFieldKind) -> Option<&Field> { | ||||||
|  |         if self.kind() == kind { | ||||||
|  |             Some(self.field()) | ||||||
|  |         } else { | ||||||
|  |             None | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(Clone, Copy, PartialEq, Eq)] | ||||||
| enum RequestFieldKind { | enum RequestFieldKind { | ||||||
|     Body, |     Body, | ||||||
|     Header, |     Header, | ||||||
| @ -272,65 +268,3 @@ enum RequestFieldKind { | |||||||
|     Path, |     Path, | ||||||
|     Query, |     Query, | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #[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> { |  | ||||||
|         while let Some(value) = self.fields.get(self.index) { |  | ||||||
|             self.index += 1; |  | ||||||
| 
 |  | ||||||
|             if value.is_body() { |  | ||||||
|                 return Some(value); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         None |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub struct RequestQueryFields<'a> { |  | ||||||
|     fields: &'a [RequestField], |  | ||||||
|     index: usize, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl<'a> RequestQueryFields<'a> { |  | ||||||
|     pub fn new(fields: &'a [RequestField]) -> Self { |  | ||||||
|         RequestQueryFields { |  | ||||||
|             fields, |  | ||||||
|             index: 0, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl<'a> Iterator for RequestQueryFields<'a> { |  | ||||||
|     type Item = &'a RequestField; |  | ||||||
| 
 |  | ||||||
|     fn next(&mut self) -> Option<&'a RequestField> { |  | ||||||
|         while let Some(value) = self.fields.get(self.index) { |  | ||||||
|             self.index += 1; |  | ||||||
| 
 |  | ||||||
|             if value.is_query() { |  | ||||||
|                 return Some(value); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         None |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user