re_parse_macros/
lib.rs

1extern crate proc_macro;
2extern crate quote;
3extern crate syn;
4extern crate proc_macro2;
5
6use proc_macro::TokenStream;
7use proc_macro2::Span;
8
9use syn::*;
10use quote::quote;
11
12#[proc_macro_derive(ReParse, attributes(re_parse))]
13pub fn re_parse_macro_derive(item: TokenStream) -> TokenStream {
14    let mut item = parse_macro_input!(item as DeriveInput);
15
16    let regex = item.attrs.iter()
17        .flat_map(|x| x.parse_meta() )
18        .filter_map(|x| match x { Meta::List(y) => Some(y), _ => None })
19        .filter(|x| x.ident == "re_parse" )
20        .flat_map(|x| x.nested.into_iter() )
21        .filter_map(|x| match x { NestedMeta::Meta(y) => Some(y), _ => None })
22        .filter_map(|x| match x { Meta::NameValue(y) => Some(y), _ => None })
23        .find(|x| x.ident == "regex" )
24        .and_then(|x| match x.lit { Lit::Str(y) => Some(y.value()), _ => None })
25        .unwrap();
26
27    let item_ident = &item.ident;
28
29    let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl();
30
31    let impl_inner = quote! { 
32        impl #impl_generics std::str::FromStr for #item_ident #ty_generics #where_clause {
33            type Err = _re_parse::Error;
34            fn from_str(s: &str) -> Result<Self, Self::Err> {
35                _re_parse::lazy_static! {
36                    static ref RE: _re_parse::Regex = Regex::new(#regex).unwrap();
37                }
38
39                Ok(_re_parse::with_pattern_from_str(&*RE, s)?)
40            }
41        }
42    };
43
44    // panic!("{}", &impl_inner);
45
46    let dummy_const = Ident::new(
47        &format!("_IMPL_FromStr_FOR_{}", item.ident.to_string()),
48        Span::call_site()
49    );
50
51    let out = quote!{
52        #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
53        const #dummy_const: () = {
54            #[allow(unknown_lints)]
55            #[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
56            extern crate re_parse as _re_parse;
57            #impl_inner
58        };
59    };
60
61    out.into()
62}