1
0
Fork 0
mirror of https://gitlab.com/msrd0/gotham-restful.git synced 2025-04-20 06:54:46 +00:00
deprecated-gotham-restful/gotham_restful_derive/src/resource.rs

75 lines
1.8 KiB
Rust
Raw Normal View History

2020-04-15 21:41:24 +02:00
use crate::{
method::Method,
util::CollectToResult
};
2019-10-06 15:03:30 +02:00
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{
2020-05-03 23:25:48 +02:00
parenthesized,
2020-04-15 21:41:24 +02:00
parse::{Parse, ParseStream},
2019-10-06 15:03:30 +02:00
punctuated::Punctuated,
DeriveInput,
2020-04-15 21:41:24 +02:00
Error,
2019-10-06 15:03:30 +02:00
Ident,
2020-05-03 23:25:48 +02:00
Token
2019-10-06 15:03:30 +02:00
};
2020-04-15 21:41:24 +02:00
use std::{iter, str::FromStr};
2019-10-06 15:03:30 +02:00
2020-05-03 23:25:48 +02:00
struct MethodList(Punctuated<Ident, Token![,]>);
2019-10-06 15:03:30 +02:00
impl Parse for MethodList
{
2020-04-15 21:41:24 +02:00
fn parse(input: ParseStream) -> Result<Self, Error>
2019-10-06 15:03:30 +02:00
{
let content;
let _paren = parenthesized!(content in input);
2020-05-03 23:25:48 +02:00
let list = Punctuated::parse_separated_nonempty(&content)?;
2019-10-06 15:03:30 +02:00
Ok(Self(list))
}
}
2020-04-15 21:41:24 +02:00
fn expand(tokens : TokenStream) -> Result<TokenStream2, Error>
2019-10-06 15:03:30 +02:00
{
2019-10-14 02:17:25 +02:00
let krate = super::krate();
2020-05-03 23:43:42 +02:00
let input : DeriveInput = syn::parse(tokens)?;
2019-10-06 15:03:30 +02:00
let ident = input.ident;
2020-04-07 20:44:02 +00:00
let name = ident.to_string();
2019-10-06 15:03:30 +02:00
2020-04-15 21:41:24 +02:00
let methods = input.attrs.into_iter().filter(|attr|
2019-10-06 15:03:30 +02:00
attr.path.segments.iter().last().map(|segment| segment.ident.to_string()) == Some("rest_resource".to_string()) // TODO wtf
2020-04-15 21:41:24 +02:00
).map(|attr| {
syn::parse2(attr.tokens).map(|m : MethodList| m.0.into_iter())
}).flat_map(|list| match list {
Ok(iter) => Box::new(iter.map(|method| {
let method = Method::from_str(&method.to_string()).map_err(|err| Error::new(method.span(), err))?;
let mod_ident = method.mod_ident(&name);
let ident = method.setup_ident(&name);
Ok(quote!(#mod_ident::#ident(&mut route);))
})) as Box<dyn Iterator<Item = Result<TokenStream2, Error>>>,
Err(err) => Box::new(iter::once(Err(err)))
}).collect_to_result()?;
2019-10-06 15:03:30 +02:00
2020-04-15 21:41:24 +02:00
Ok(quote! {
2019-10-14 02:17:25 +02:00
impl #krate::Resource for #ident
2019-10-06 15:03:30 +02:00
{
fn name() -> String
{
stringify!(#ident).to_string()
}
2019-10-14 02:17:25 +02:00
fn setup<D : #krate::DrawResourceRoutes>(mut route : D)
2019-10-06 15:03:30 +02:00
{
#(#methods)*
}
}
2020-04-15 21:41:24 +02:00
})
}
pub fn expand_resource(tokens : TokenStream) -> TokenStream
{
expand(tokens)
.unwrap_or_else(|err| err.to_compile_error())
.into()
2019-10-06 15:03:30 +02:00
}