ExprStruct --> Metadata

This commit is contained in:
Jimmy Cuadra 2018-05-04 03:52:55 -07:00
parent 17b11d1a25
commit 4db09dac8d
2 changed files with 53 additions and 92 deletions

View File

@ -1,68 +1,22 @@
use std::convert::TryFrom;
use quote::{ToTokens, Tokens}; use quote::{ToTokens, Tokens};
use syn::synom::Synom; use syn::synom::Synom;
use syn::{Expr, Ident}; use syn::{Expr, ExprStruct, Ident, Member};
#[derive(Debug)]
pub struct Metadata { pub struct Metadata {
pub description: Tokens, pub description: Expr,
pub method: Tokens, pub method: Expr,
pub name: Tokens, pub name: Expr,
pub path: Tokens, pub path: Expr,
pub rate_limited: Tokens, pub rate_limited: Expr,
pub requires_authentication: Tokens, pub requires_authentication: Expr,
} }
impl Synom for Metadata { impl TryFrom<ExprStruct> for Metadata {
named!(parse -> Self, do_parse!( type Error = &'static str;
ident: syn!(Ident) >>
cond_reduce!(ident == "description") >>
punct!(:) >>
description: syn!(Expr) >>
punct!(,) >>
ident: syn!(Ident) >> fn try_from(expr: ExprStruct) -> Result<Self, Self::Error> {
cond_reduce!(ident == "method") >>
punct!(:) >>
method: syn!(Expr) >>
punct!(,) >>
ident: syn!(Ident) >>
cond_reduce!(ident == "name") >>
punct!(:) >>
name: syn!(Expr) >>
punct!(,) >>
ident: syn!(Ident) >>
cond_reduce!(ident == "path") >>
punct!(:) >>
path: syn!(Expr) >>
punct!(,) >>
ident: syn!(Ident) >>
cond_reduce!(ident == "rate_limited") >>
punct!(:) >>
rate_limited: syn!(Expr) >>
punct!(,) >>
ident: syn!(Ident) >>
cond_reduce!(ident == "requires_authentication") >>
punct!(:) >>
requires_authentication: syn!(Expr) >>
punct!(,) >>
(Metadata {
description,
method,
name,
path,
rate_limited,
requires_authentication,
})
));
}
impl From<Vec<(Ident, Expr)>> for Metadata {
fn from(fields: Vec<(Ident, Expr)>) -> Self {
let mut description = None; let mut description = None;
let mut method = None; let mut method = None;
let mut name = None; let mut name = None;
@ -70,43 +24,51 @@ impl From<Vec<(Ident, Expr)>> for Metadata {
let mut rate_limited = None; let mut rate_limited = None;
let mut requires_authentication = None; let mut requires_authentication = None;
for field in fields { for field in expr.fields {
let (identifier, expression) = field; let Member::Named(identifier) = field.member;
if identifier == Ident::new("description") { match identifier.as_ref() {
description = Some(tokens_for(expression)); "description" => description = Some(field.expr),
} else if identifier == Ident::new("method") { "method" => method = Some(field.expr),
method = Some(tokens_for(expression)); "name" => name = Some(field.expr),
} else if identifier == Ident::new("name") { "path" => path = Some(field.expr),
name = Some(tokens_for(expression)); "rate_limited" => rate_limited = Some(field.expr),
} else if identifier == Ident::new("path") { "requires_authentication" => requires_authentication = Some(field.expr),
path = Some(tokens_for(expression)); _ => return Err("ruma_api! metadata included unexpected field"),
} else if identifier == Ident::new("rate_limited") {
rate_limited = Some(tokens_for(expression));
} else if identifier == Ident::new("requires_authentication") {
requires_authentication = Some(tokens_for(expression));
} else {
panic!("ruma_api! metadata included unexpected field: {}", identifier);
} }
} }
Metadata { if description.is_none() {
description: description.expect("ruma_api! metadata is missing description"), return Err("ruma_api! metadata is missing description");
method: method.expect("ruma_api! metadata is missing method"),
name: name.expect("ruma_api! metadata is missing name"),
path: path.expect("ruma_api! metadata is missing path"),
rate_limited: rate_limited.expect("ruma_api! metadata is missing rate_limited"),
requires_authentication: requires_authentication
.expect("ruma_api! metadata is missing requires_authentication"),
}
}
} }
/// Helper method for turning a value into tokens. if method.is_none() {
fn tokens_for<T>(value: T) -> Tokens where T: ToTokens { return Err("ruma_api! metadata is missing method");
let mut tokens = Tokens::new(); }
value.to_tokens(&mut tokens); if name.is_none() {
return Err("ruma_api! metadata is missing name");
tokens }
if path.is_none() {
return Err("ruma_api! metadata is missing path");
}
if rate_limited.is_none() {
return Err("ruma_api! metadata is missing rate_limited");
}
if requires_authentication.is_none() {
return Err("ruma_api! metadata is missing requires_authentication");
}
Ok(Metadata {
description: description.unwrap(),
method: method.unwrap(),
name: name.unwrap(),
path: path.unwrap(),
rate_limited: rate_limited.unwrap(),
requires_authentication: requires_authentication.unwrap(),
})
}
} }

View File

@ -35,7 +35,6 @@ use self::response::Response;
// field // field
// } // }
#[derive(Debug)]
pub struct Api { pub struct Api {
metadata: Metadata, metadata: Metadata,
request: Request, request: Request,