fmc_noise_multiversion_macros/
lib.rs1extern crate proc_macro;
3
4mod cfg;
5mod dispatcher;
6mod match_target;
7mod multiversion;
8mod target;
9mod util;
10
11use proc_macro2::TokenStream;
12use quote::{quote, ToTokens};
13use syn::{parse::Nothing, parse_macro_input, punctuated::Punctuated, ItemFn};
14
15#[proc_macro_attribute]
16pub fn multiversion(
17 attr: proc_macro::TokenStream,
18 input: proc_macro::TokenStream,
19) -> proc_macro::TokenStream {
20 let func = parse_macro_input!(input as ItemFn);
21 match multiversion::make_multiversioned_fn(attr.into(), func) {
22 Ok(tokens) => tokens.into_token_stream(),
23 Err(err) => err.to_compile_error(),
24 }
25 .into()
26}
27
28#[proc_macro_attribute]
29pub fn target(
30 attr: proc_macro::TokenStream,
31 input: proc_macro::TokenStream,
32) -> proc_macro::TokenStream {
33 let target = parse_macro_input!(attr as syn::LitStr);
34 let func = parse_macro_input!(input as ItemFn);
35 match target::make_target_fn(target, func) {
36 Ok(tokens) => tokens.into_token_stream(),
37 Err(err) => err.to_compile_error(),
38 }
39 .into()
40}
41
42#[proc_macro_attribute]
43pub fn inherit_target(
44 attr: proc_macro::TokenStream,
45 input: proc_macro::TokenStream,
46) -> proc_macro::TokenStream {
47 parse_macro_input!(attr as Nothing);
48 let func = parse_macro_input!(input as ItemFn);
49 quote! {
50 __multiversion::inherit_target! { #func }
51 }
52 .into()
53}
54
55#[proc_macro]
56pub fn selected_target(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
57 parse_macro_input!(input as Nothing);
58 quote! {
59 __multiversion::FEATURES
60 }
61 .into()
62}
63
64#[proc_macro_attribute]
65pub fn target_cfg(
66 attr: proc_macro::TokenStream,
67 input: proc_macro::TokenStream,
68) -> proc_macro::TokenStream {
69 let attr = TokenStream::from(attr);
70 let input = TokenStream::from(input);
71 quote! {
72 __multiversion::target_cfg!{ [#attr] #input }
73 }
74 .into()
75}
76
77#[proc_macro_attribute]
78pub fn target_cfg_attr(
79 attr: proc_macro::TokenStream,
80 input: proc_macro::TokenStream,
81) -> proc_macro::TokenStream {
82 let attr = TokenStream::from(attr);
83 let input = TokenStream::from(input);
84 quote! {
85 __multiversion::target_cfg_attr!{ [#attr] #input }
86 }
87 .into()
88}
89
90#[proc_macro]
91pub fn target_cfg_f(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
92 let input = TokenStream::from(input);
93 quote! {
94 __multiversion::target_cfg_f!{ #input }
95 }
96 .into()
97}
98
99#[proc_macro_attribute]
100pub fn target_cfg_impl(
101 attr: proc_macro::TokenStream,
102 input: proc_macro::TokenStream,
103) -> proc_macro::TokenStream {
104 let meta = parse_macro_input!(attr with Punctuated::parse_terminated);
105 let input = TokenStream::from(input);
106
107 let meta = cfg::transform(meta);
108 quote! {
109 #[cfg(#meta)]
110 #input
111 }
112 .into()
113}
114
115#[proc_macro_attribute]
116pub fn target_cfg_attr_impl(
117 attr: proc_macro::TokenStream,
118 input: proc_macro::TokenStream,
119) -> proc_macro::TokenStream {
120 let mut meta = parse_macro_input!(attr with Punctuated::parse_terminated);
121 let input = TokenStream::from(input);
122
123 let attr = meta.pop().unwrap();
124 let meta = cfg::transform(meta);
125 quote! {
126 #[cfg_attr(#meta, #attr)]
127 #input
128 }
129 .into()
130}
131
132#[proc_macro]
133pub fn target_cfg_f_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
134 let meta = parse_macro_input!(input with Punctuated::parse_terminated);
135
136 let meta = cfg::transform(meta);
137 quote! {
138 cfg!(#meta)
139 }
140 .into()
141}
142
143#[proc_macro]
144pub fn match_target(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
145 let input = TokenStream::from(input);
146 quote! {
147 __multiversion::match_target!{ #input }
148 }
149 .into()
150}
151
152#[proc_macro]
153pub fn match_target_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
154 let match_target = parse_macro_input!(input as match_target::MatchTarget);
155 match_target.into_token_stream().into()
156}