Use a custom parser for the raw input.
This commit is contained in:
		
							parent
							
								
									8f6bc5af77
								
							
						
					
					
						commit
						38746660b6
					
				| @ -1,7 +1,5 @@ | ||||
| use quote::{ToTokens, Tokens}; | ||||
| use syn::punctuated::Pair; | ||||
| use syn::synom::Synom; | ||||
| use syn::{Expr, ExprStruct, Ident, Lit, Member}; | ||||
| use syn::{Expr, FieldValue, Lit, Member}; | ||||
| 
 | ||||
| pub struct Metadata { | ||||
|     pub description: String, | ||||
| @ -12,8 +10,8 @@ pub struct Metadata { | ||||
|     pub requires_authentication: bool, | ||||
| } | ||||
| 
 | ||||
| impl From<ExprStruct> for Metadata { | ||||
|     fn from(expr: ExprStruct) -> Self { | ||||
| impl From<Vec<FieldValue>> for Metadata { | ||||
|     fn from(field_values: Vec<FieldValue>) -> Self { | ||||
|         let mut description = None; | ||||
|         let mut method = None; | ||||
|         let mut name = None; | ||||
| @ -21,15 +19,15 @@ impl From<ExprStruct> for Metadata { | ||||
|         let mut rate_limited = None; | ||||
|         let mut requires_authentication = None; | ||||
| 
 | ||||
|         for field in expr.fields { | ||||
|             let identifier = match field.member { | ||||
|         for field_value in field_values { | ||||
|             let identifier = match field_value.member { | ||||
|                 Member::Named(identifier) => identifier, | ||||
|                 _ => panic!("expected Member::Named"), | ||||
|             }; | ||||
| 
 | ||||
|             match identifier.as_ref() { | ||||
|                 "description" => { | ||||
|                     let expr_lit = match field.expr { | ||||
|                     let expr_lit = match field_value.expr { | ||||
|                         Expr::Lit(expr_lit) => expr_lit, | ||||
|                         _ => panic!("expected Expr::Lit"), | ||||
|                     }; | ||||
| @ -40,7 +38,7 @@ impl From<ExprStruct> for Metadata { | ||||
|                     description = Some(lit_str.value()); | ||||
|                 } | ||||
|                 "method" => { | ||||
|                     let expr_path = match field.expr { | ||||
|                     let expr_path = match field_value.expr { | ||||
|                         Expr::Path(expr_path) => expr_path, | ||||
|                         _ => panic!("expected Expr::Path"), | ||||
|                     }; | ||||
| @ -57,7 +55,7 @@ impl From<ExprStruct> for Metadata { | ||||
|                     method = Some(method_name.ident.to_string()); | ||||
|                 } | ||||
|                 "name" => { | ||||
|                     let expr_lit = match field.expr { | ||||
|                     let expr_lit = match field_value.expr { | ||||
|                         Expr::Lit(expr_lit) => expr_lit, | ||||
|                         _ => panic!("expected Expr::Lit"), | ||||
|                     }; | ||||
| @ -68,7 +66,7 @@ impl From<ExprStruct> for Metadata { | ||||
|                     name = Some(lit_str.value()); | ||||
|                 } | ||||
|                 "path" => { | ||||
|                     let expr_lit = match field.expr { | ||||
|                     let expr_lit = match field_value.expr { | ||||
|                         Expr::Lit(expr_lit) => expr_lit, | ||||
|                         _ => panic!("expected Expr::Lit"), | ||||
|                     }; | ||||
| @ -79,7 +77,7 @@ impl From<ExprStruct> for Metadata { | ||||
|                     path = Some(lit_str.value()); | ||||
|                 } | ||||
|                 "rate_limited" => { | ||||
|                     let expr_lit = match field.expr { | ||||
|                     let expr_lit = match field_value.expr { | ||||
|                         Expr::Lit(expr_lit) => expr_lit, | ||||
|                         _ => panic!("expected Expr::Lit"), | ||||
|                     }; | ||||
| @ -90,7 +88,7 @@ impl From<ExprStruct> for Metadata { | ||||
|                     rate_limited = Some(lit_bool.value) | ||||
|                 } | ||||
|                 "requires_authentication" => { | ||||
|                     let expr_lit = match field.expr { | ||||
|                     let expr_lit = match field_value.expr { | ||||
|                         Expr::Lit(expr_lit) => expr_lit, | ||||
|                         _ => panic!("expected Expr::Lit"), | ||||
|                     }; | ||||
|  | ||||
							
								
								
									
										103
									
								
								src/api/mod.rs
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								src/api/mod.rs
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| use quote::{ToTokens, Tokens}; | ||||
| use syn::punctuated::Pair; | ||||
| use syn::punctuated::Punctuated; | ||||
| use syn::synom::Synom; | ||||
| use syn::{Expr, FieldValue, Ident, Member, Meta}; | ||||
| use syn::{Field, FieldValue, Meta}; | ||||
| 
 | ||||
| mod metadata; | ||||
| mod request; | ||||
| @ -11,10 +11,10 @@ use self::metadata::Metadata; | ||||
| use self::request::Request; | ||||
| use self::response::Response; | ||||
| 
 | ||||
| pub fn strip_serde_attrs(field_value: &FieldValue) -> FieldValue { | ||||
|     let mut field_value = field_value.clone(); | ||||
| pub fn strip_serde_attrs(field: &Field) -> Field { | ||||
|     let mut field = field.clone(); | ||||
| 
 | ||||
|     field_value.attrs = field_value.attrs.into_iter().filter(|attr| { | ||||
|     field.attrs = field.attrs.into_iter().filter(|attr| { | ||||
|         let meta = attr.interpret_meta() | ||||
|             .expect("ruma_api! could not parse field attributes"); | ||||
| 
 | ||||
| @ -30,7 +30,7 @@ pub fn strip_serde_attrs(field_value: &FieldValue) -> FieldValue { | ||||
|         false | ||||
|     }).collect(); | ||||
| 
 | ||||
|     field_value | ||||
|     field | ||||
| } | ||||
| 
 | ||||
| pub struct Api { | ||||
| @ -39,59 +39,13 @@ pub struct Api { | ||||
|     response: Response, | ||||
| } | ||||
| 
 | ||||
| impl From<Vec<Expr>> for Api { | ||||
|     fn from(exprs: Vec<Expr>) -> Self { | ||||
|         if exprs.len() != 3 { | ||||
|             panic!("ruma_api! expects 3 blocks: metadata, request, and response"); | ||||
|         } | ||||
| 
 | ||||
|         let mut metadata = None; | ||||
|         let mut request = None; | ||||
|         let mut response = None; | ||||
| 
 | ||||
|         for expr in exprs { | ||||
|             let expr = match expr { | ||||
|                 Expr::Struct(expr) => expr, | ||||
|                 _ => panic!("ruma_api! blocks should use struct syntax"), | ||||
|             }; | ||||
| 
 | ||||
|             let segments = expr.path.segments.clone(); | ||||
| 
 | ||||
|             if segments.len() != 1 { | ||||
|                 panic!("ruma_api! blocks must be one of: metadata, request, or response"); | ||||
|             } | ||||
| 
 | ||||
|             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()), | ||||
|                 "request" => request = Some(expr.into()), | ||||
|                 "response" => response = Some(expr.into()), | ||||
|                 _ => panic!("ruma_api! blocks must be one of: metadata, request, or response"), | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if metadata.is_none() { | ||||
|             panic!("ruma_api! is missing metadata"); | ||||
|         } | ||||
| 
 | ||||
|         if request.is_none() { | ||||
|             panic!("ruma_api! is missing request"); | ||||
|         } | ||||
| 
 | ||||
|         if response.is_none() { | ||||
|             panic!("ruma_api! is missing response"); | ||||
|         } | ||||
| 
 | ||||
| impl From<RawApi> for Api { | ||||
|     fn from(raw_api: RawApi) -> Self { | ||||
|         Api { | ||||
|             metadata: metadata.unwrap(), | ||||
|             request: request.unwrap(), | ||||
|             response: response.unwrap(), | ||||
|             metadata: raw_api.metadata.into(), | ||||
|             request: raw_api.request.into(), | ||||
|             response: raw_api.response.into(), | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -183,10 +137,7 @@ impl ToTokens for Api { | ||||
|         }; | ||||
| 
 | ||||
|         let add_body_to_request = if let Some(field) = self.request.newtype_body_field() { | ||||
|             let field_name = match field.member { | ||||
|                 Member::Named(field_name) => field_name, | ||||
|                 _ => panic!("expected Member::Named"), | ||||
|             }; | ||||
|             let field_name = field.ident.expect("expected field to have an identifier"); | ||||
| 
 | ||||
|             quote! { | ||||
|                 let request_body = RequestBody(request.#field_name); | ||||
| @ -208,10 +159,8 @@ impl ToTokens for Api { | ||||
|         }; | ||||
| 
 | ||||
|         let deserialize_response_body = if let Some(field) = self.response.newtype_body_field() { | ||||
|             let field_type = match field.expr { | ||||
|                 Expr::Path(ref field_type) => field_type, | ||||
|                 _ => panic!("expected Expr::Path"), | ||||
|             }; | ||||
|             let field_type = &field.ty; | ||||
| 
 | ||||
|             let mut tokens = Tokens::new(); | ||||
| 
 | ||||
|             tokens.append_all(quote! { | ||||
| @ -362,15 +311,27 @@ impl ToTokens for Api { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct Exprs { | ||||
|     pub inner: Vec<Expr>, | ||||
| type ParseMetadata = Punctuated<FieldValue, Token![,]>; | ||||
| type ParseFields = Punctuated<Field, Token![,]>; | ||||
| 
 | ||||
| pub struct RawApi { | ||||
|     pub metadata: Vec<FieldValue>, | ||||
|     pub request: Vec<Field>, | ||||
|     pub response: Vec<Field>, | ||||
| } | ||||
| 
 | ||||
| impl Synom for Exprs { | ||||
| impl Synom for RawApi { | ||||
|     named!(parse -> Self, do_parse!( | ||||
|         exprs: many0!(syn!(Expr)) >> | ||||
|         (Exprs { | ||||
|             inner: exprs, | ||||
|         custom_keyword!(metadata) >> | ||||
|         metadata: braces!(ParseMetadata::parse_terminated) >> | ||||
|         custom_keyword!(request) >> | ||||
|         request: braces!(call!(ParseFields::parse_terminated_with, Field::parse_named)) >> | ||||
|         custom_keyword!(response) >> | ||||
|         response: braces!(call!(ParseFields::parse_terminated_with, Field::parse_named)) >> | ||||
|         (RawApi { | ||||
|             metadata: metadata.1.into_iter().collect(), | ||||
|             request: request.1.into_iter().collect(), | ||||
|             response: response.1.into_iter().collect(), | ||||
|         }) | ||||
|     )); | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| use quote::{ToTokens, Tokens}; | ||||
| use syn::synom::Synom; | ||||
| use syn::{ExprStruct, Field, FieldValue, FieldsNamed, Member, Meta, NestedMeta}; | ||||
| use syn::{Field, Meta, NestedMeta}; | ||||
| 
 | ||||
| use api::strip_serde_attrs; | ||||
| 
 | ||||
| @ -25,7 +24,7 @@ impl Request { | ||||
|         self.fields.iter().filter(|field| field.is_path()).count() | ||||
|     } | ||||
| 
 | ||||
|     pub fn newtype_body_field(&self) -> Option<&FieldValue> { | ||||
|     pub fn newtype_body_field(&self) -> Option<&Field> { | ||||
|         for request_field in self.fields.iter() { | ||||
|             match *request_field { | ||||
|                 RequestField::NewtypeBody(ref field) => { | ||||
| @ -54,10 +53,7 @@ impl Request { | ||||
|         let mut tokens = Tokens::new(); | ||||
| 
 | ||||
|         for field in self.fields.iter().flat_map(|f| f.field_(request_field_kind)) { | ||||
|             let field_name = match field.member { | ||||
|                 Member::Named(field_name) => field_name, | ||||
|                 _ => panic!("expected Member::Named"), | ||||
|             }; | ||||
|             let field_name = field.ident.expect("expected field to have an identifier"); | ||||
| 
 | ||||
|             tokens.append_all(quote! { | ||||
|                 #field_name: request.#field_name, | ||||
| @ -68,14 +64,14 @@ impl Request { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl From<ExprStruct> for Request { | ||||
|     fn from(expr: ExprStruct) -> Self { | ||||
| impl From<Vec<Field>> for Request { | ||||
|     fn from(fields: Vec<Field>) -> Self { | ||||
|         let mut has_newtype_body = false; | ||||
| 
 | ||||
|         let fields = expr.fields.into_iter().map(|mut field_value| { | ||||
|         let fields = fields.into_iter().map(|mut field| { | ||||
|             let mut field_kind = RequestFieldKind::Body; | ||||
| 
 | ||||
|             field_value.attrs = field_value.attrs.into_iter().filter(|attr| { | ||||
|             field.attrs = field.attrs.into_iter().filter(|attr| { | ||||
|                 let meta = attr.interpret_meta() | ||||
|                     .expect("ruma_api! could not parse request field attributes"); | ||||
| 
 | ||||
| @ -127,7 +123,7 @@ impl From<ExprStruct> for Request { | ||||
|                 ); | ||||
|             } | ||||
| 
 | ||||
|             RequestField::new(field_kind, field_value) | ||||
|             RequestField::new(field_kind, field) | ||||
|         }).collect(); | ||||
| 
 | ||||
|         Request { | ||||
| @ -160,12 +156,12 @@ impl ToTokens for Request { | ||||
| 
 | ||||
|         if let Some(newtype_body_field) = self.newtype_body_field() { | ||||
|             let mut field = newtype_body_field.clone(); | ||||
|             let expr = field.expr; | ||||
|             let ty = field.ty; | ||||
| 
 | ||||
|             tokens.append_all(quote! { | ||||
|                 /// Data in the request body.
 | ||||
|                 #[derive(Debug, Serialize)] | ||||
|                 struct RequestBody(#expr); | ||||
|                 struct RequestBody(#ty); | ||||
|             }); | ||||
|         } else if self.has_body_fields() { | ||||
|             tokens.append_all(quote! { | ||||
| @ -239,15 +235,15 @@ impl ToTokens for Request { | ||||
| } | ||||
| 
 | ||||
| pub enum RequestField { | ||||
|     Body(FieldValue), | ||||
|     Header(FieldValue), | ||||
|     NewtypeBody(FieldValue), | ||||
|     Path(FieldValue), | ||||
|     Query(FieldValue), | ||||
|     Body(Field), | ||||
|     Header(Field), | ||||
|     NewtypeBody(Field), | ||||
|     Path(Field), | ||||
|     Query(Field), | ||||
| } | ||||
| 
 | ||||
| impl RequestField { | ||||
|     fn new(kind: RequestFieldKind, field: FieldValue) -> RequestField { | ||||
|     fn new(kind: RequestFieldKind, field: Field) -> RequestField { | ||||
|         match kind { | ||||
|             RequestFieldKind::Body => RequestField::Body(field), | ||||
|             RequestFieldKind::Header => RequestField::Header(field), | ||||
| @ -279,7 +275,7 @@ impl RequestField { | ||||
|         self.kind() == RequestFieldKind::Query | ||||
|     } | ||||
| 
 | ||||
|     fn field(&self) -> &FieldValue { | ||||
|     fn field(&self) -> &Field { | ||||
|         match *self { | ||||
|             RequestField::Body(ref field) => field, | ||||
|             RequestField::Header(ref field) => field, | ||||
| @ -289,7 +285,7 @@ impl RequestField { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn field_(&self, kind: RequestFieldKind) -> Option<&FieldValue> { | ||||
|     fn field_(&self, kind: RequestFieldKind) -> Option<&Field> { | ||||
|         if self.kind() == kind { | ||||
|             Some(self.field()) | ||||
|         } else { | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| use quote::{ToTokens, Tokens}; | ||||
| use syn::{Expr, ExprStruct, Field, FieldValue, FieldsNamed, Member, Meta, NestedMeta}; | ||||
| use syn::{Field, Meta, NestedMeta}; | ||||
| 
 | ||||
| use api::strip_serde_attrs; | ||||
| 
 | ||||
| @ -26,25 +26,15 @@ impl Response { | ||||
|         for response_field in self.fields.iter() { | ||||
|             match *response_field { | ||||
|                 ResponseField::Body(ref field) => { | ||||
|                     let field_name = match field.member { | ||||
|                         Member::Named(field_name) => field_name, | ||||
|                         _ => panic!("expected Member::Named"), | ||||
|                     }; | ||||
|                     let field_name = field.ident.expect("expected field to have an identifier"); | ||||
| 
 | ||||
|                     tokens.append_all(quote! { | ||||
|                         #field_name: response_body.#field_name, | ||||
|                     }); | ||||
|                 } | ||||
|                 ResponseField::Header(ref field) => { | ||||
|                     let field_name = match field.member { | ||||
|                         Member::Named(field_name) => field_name, | ||||
|                         _ => panic!("expected Member::Named"), | ||||
|                     }; | ||||
| 
 | ||||
|                     let field_type = match field.expr { | ||||
|                         Expr::Path(ref field_type) => field_type, | ||||
|                         _ => panic!("expected Expr::Path"), | ||||
|                     }; | ||||
|                     let field_name = field.ident.expect("expected field to have an identifier"); | ||||
|                     let field_type = &field.ty; | ||||
| 
 | ||||
|                     tokens.append_all(quote! { | ||||
|                         #field_name: headers.remove::<#field_type>() | ||||
| @ -52,10 +42,7 @@ impl Response { | ||||
|                     }); | ||||
|                 } | ||||
|                 ResponseField::NewtypeBody(ref field) => { | ||||
|                     let field_name = match field.member { | ||||
|                         Member::Named(field_name) => field_name, | ||||
|                         _ => panic!("expected Member::Named"), | ||||
|                     }; | ||||
|                     let field_name = field.ident.expect("expected field to have an identifier"); | ||||
| 
 | ||||
|                     tokens.append_all(quote! { | ||||
|                         #field_name: response_body, | ||||
| @ -67,7 +54,7 @@ impl Response { | ||||
|         tokens | ||||
|     } | ||||
| 
 | ||||
|     pub fn newtype_body_field(&self) -> Option<&FieldValue> { | ||||
|     pub fn newtype_body_field(&self) -> Option<&Field> { | ||||
|         for response_field in self.fields.iter() { | ||||
|             match *response_field { | ||||
|                 ResponseField::NewtypeBody(ref field) => { | ||||
| @ -83,14 +70,14 @@ impl Response { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| impl From<ExprStruct> for Response { | ||||
|     fn from(expr: ExprStruct) -> Self { | ||||
| impl From<Vec<Field>> for Response { | ||||
|     fn from(fields: Vec<Field>) -> Self { | ||||
|         let mut has_newtype_body = false; | ||||
| 
 | ||||
|         let fields = expr.fields.into_iter().map(|mut field_value| { | ||||
|         let fields = fields.into_iter().map(|mut field| { | ||||
|             let mut field_kind = ResponseFieldKind::Body; | ||||
| 
 | ||||
|             field_value.attrs = field_value.attrs.into_iter().filter(|attr| { | ||||
|             field.attrs = field.attrs.into_iter().filter(|attr| { | ||||
|                 let meta = attr.interpret_meta() | ||||
|                     .expect("ruma_api! could not parse response field attributes"); | ||||
| 
 | ||||
| @ -138,11 +125,11 @@ impl From<ExprStruct> for Response { | ||||
|                     if has_newtype_body { | ||||
|                         panic!("ruma_api! responses cannot have both normal body fields and a newtype body field"); | ||||
|                     } else { | ||||
|                         return ResponseField::Body(field_value); | ||||
|                         return ResponseField::Body(field); | ||||
|                     } | ||||
|                 } | ||||
|                 ResponseFieldKind::Header => ResponseField::Header(field_value), | ||||
|                 ResponseFieldKind::NewtypeBody => ResponseField::NewtypeBody(field_value), | ||||
|                 ResponseFieldKind::Header => ResponseField::Header(field), | ||||
|                 ResponseFieldKind::NewtypeBody => ResponseField::NewtypeBody(field), | ||||
|             } | ||||
|         }).collect(); | ||||
| 
 | ||||
| @ -176,12 +163,12 @@ impl ToTokens for Response { | ||||
| 
 | ||||
|         if let Some(newtype_body_field) = self.newtype_body_field() { | ||||
|             let mut field = newtype_body_field.clone(); | ||||
|             let expr = field.expr; | ||||
|             let ty = field.ty; | ||||
| 
 | ||||
|             tokens.append_all(quote! { | ||||
|                 /// Data in the response body.
 | ||||
|                 #[derive(Debug, Deserialize)] | ||||
|                 struct ResponseBody(#expr); | ||||
|                 struct ResponseBody(#ty); | ||||
|             }); | ||||
|         } else if self.has_body_fields() { | ||||
|             tokens.append_all(quote! { | ||||
| @ -209,13 +196,13 @@ impl ToTokens for Response { | ||||
| } | ||||
| 
 | ||||
| pub enum ResponseField { | ||||
|     Body(FieldValue), | ||||
|     Header(FieldValue), | ||||
|     NewtypeBody(FieldValue), | ||||
|     Body(Field), | ||||
|     Header(Field), | ||||
|     NewtypeBody(Field), | ||||
| } | ||||
| 
 | ||||
| impl ResponseField { | ||||
|     fn field(&self) -> &FieldValue { | ||||
|     fn field(&self) -> &Field { | ||||
|         match *self { | ||||
|             ResponseField::Body(ref field) => field, | ||||
|             ResponseField::Header(ref field) => field, | ||||
|  | ||||
							
								
								
									
										12
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/lib.rs
									
									
									
									
									
								
							| @ -4,9 +4,8 @@ | ||||
| //! See the documentation for the `ruma_api!` macro for usage details.
 | ||||
| 
 | ||||
| #![deny(missing_debug_implementations)] | ||||
| #![feature(proc_macro, try_from)] | ||||
| #![feature(proc_macro)] | ||||
| #![recursion_limit="256"] | ||||
| #![allow(warnings)] | ||||
| 
 | ||||
| extern crate proc_macro; | ||||
| #[macro_use] extern crate quote; | ||||
| @ -14,11 +13,10 @@ extern crate ruma_api; | ||||
| #[macro_use] extern crate syn; | ||||
| 
 | ||||
| use proc_macro::TokenStream; | ||||
| use std::convert::TryFrom; | ||||
| 
 | ||||
| use quote::{ToTokens, Tokens}; | ||||
| use quote::ToTokens; | ||||
| 
 | ||||
| use api::{Api, Exprs}; | ||||
| use api::{Api, RawApi}; | ||||
| 
 | ||||
| mod api; | ||||
| 
 | ||||
| @ -195,9 +193,9 @@ mod api; | ||||
| /// ```
 | ||||
| #[proc_macro] | ||||
| pub fn ruma_api(input: TokenStream) -> TokenStream { | ||||
|     let exprs: Exprs = syn::parse(input).expect("ruma_api! failed to parse input"); | ||||
|     let raw_api: RawApi = syn::parse(input).expect("ruma_api! failed to parse input"); | ||||
| 
 | ||||
|     let api = Api::from(exprs.inner); | ||||
|     let api = Api::from(raw_api); | ||||
| 
 | ||||
|     api.into_tokens().into() | ||||
| } | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| #![feature(associated_consts, proc_macro, try_from)] | ||||
| 
 | ||||
| extern crate futures; | ||||
| extern crate hyper; | ||||
| extern crate ruma_api; | ||||
| extern crate ruma_api_macros; | ||||
| extern crate serde; | ||||
| @ -17,7 +16,7 @@ pub mod some_endpoint { | ||||
|     ruma_api! { | ||||
|         metadata { | ||||
|             description: "Does something.", | ||||
|             method: Method::Get, // A `hyper::Method` value. No need to import the name.
 | ||||
|             method: GET, // An `http::Method` constant. No imports required.
 | ||||
|             name: "some_endpoint", | ||||
|             path: "/_matrix/some/endpoint/:baz", | ||||
|             rate_limited: false, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user