core_extensions_proc_macros/
lib.rs

1#![no_std]
2
3extern crate proc_macro;
4
5#[cfg(not(test))]
6use proc_macro as used_proc_macro;
7
8#[cfg(any(test, feature = "derive"))]
9extern crate proc_macro2;
10
11#[cfg(test)]
12use proc_macro2 as used_proc_macro;
13
14extern crate alloc;
15
16// #[cfg(test)]
17extern crate std;
18
19use crate::used_proc_macro::{Delimiter, Group, Punct, Spacing, Span, TokenStream, TokenTree};
20
21use core::iter::once;
22
23#[cfg(feature = "derive")]
24use proc_macro2::TokenStream as TokenStream2;
25
26#[cfg(feature = "derive")]
27mod derive;
28
29#[cfg(feature = "derive")]
30#[proc_macro_derive(ConstDefault, attributes(cdef))]
31pub fn derive_const_default(input: proc_macro::TokenStream) -> TokenStream {
32    syn::parse(input)
33        .and_then(crate::derive::const_default_derive::derive_impl)
34        .unwrap_or_else(syn::Error::into_compile_error)
35        .into()
36}
37
38#[cfg(feature = "derive")]
39#[proc_macro_derive(TransparentNewtype, attributes(twrap))]
40pub fn derive_transparent_newtype(input: proc_macro::TokenStream) -> TokenStream {
41    syn::parse(input)
42        .and_then(crate::derive::transparent_newtype_derive::derive_impl)
43        .unwrap_or_else(syn::Error::into_compile_error)
44        .into()
45}
46
47
48
49
50#[cfg(test)]
51mod test_utils;
52
53#[cfg(test)]
54mod tests;
55
56mod parsing_shared;
57
58mod splitting_generics;
59
60#[cfg(feature = "macro_utils")]
61#[macro_use]
62mod macro_utils_shared;
63
64#[cfg(feature = "macro_utils")]
65mod macro_utils;
66
67#[cfg(feature = "item_parsing")]
68mod item_parsing;
69
70
71#[cfg(feature = "macro_utils")]
72use crate::macro_utils_shared::Error;
73
74#[cfg(feature = "macro_utils")]
75type Result<T> = core::result::Result<T, Error>;
76
77
78#[cfg(feature = "macro_utils")]
79#[proc_macro_attribute]
80pub fn macro_attr(attr: TokenStream, item: TokenStream) -> TokenStream {
81    crate::macro_utils::macro_attr(attr, item).unwrap_or_else(Error::into_compile_error)
82}
83
84
85#[doc(hidden)]
86#[proc_macro]
87pub fn __priv_unwrap_bound(
88    input_tokens: proc_macro::TokenStream
89) -> proc_macro::TokenStream {
90    let input_tokens: TokenStream = input_tokens.into();
91
92    let mut iter = input_tokens.into_iter();
93
94    let ty_tt = iter.next().expect("__priv_unwrap_bound expected more tokens");
95    
96    let group = match &ty_tt {
97        TokenTree::Group(group) if group.delimiter() == Delimiter::None => group,
98        x => panic!("Expected a none-delimited group, found:\n{}", x)
99    };
100
101    let mut last_is_plus = true;
102
103    let mut ty = group.stream()
104        .into_iter()
105        .inspect(|tt|{
106             last_is_plus = mmatches!(tt, TokenTree::Punct(punc) if punc.as_char() == '+');
107        })
108        .collect::<TokenStream>();
109
110    if !last_is_plus {
111        ty.extend(once(TokenTree::Punct(Punct::new('+', Spacing::Alone))))
112    }
113
114    let args = TokenStream::new();
115
116    parsing_shared::parse_path_and_args("__priv_unwrap_bound", &mut iter, args, |args| {
117        args.extend(once(TokenTree::Group(Group::new(Delimiter::Parenthesis, ty))));
118    }).into()
119}
120
121
122#[cfg(feature = "macro_utils")]
123#[doc(hidden)]
124#[proc_macro]
125pub fn __priv_rewrap_macro_parameters(input_tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
126    let input_tokens: TokenStream = input_tokens.into();
127    //std::println!("\n----------------------------\n\n{:?}", input_tokens);
128    let out = macro_utils::rewrap_macro_parameters(input_tokens);
129    //std::println!("\n\n{:?}", out);
130    out.into()
131}
132
133#[cfg(feature = "macro_utils")]
134#[proc_macro]
135pub fn count_tts(input_tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
136    let input_tokens: TokenStream = input_tokens.into();
137    let out = macro_utils::count_tts(input_tokens).unwrap_or_else(Error::into_compile_error); 
138    out.into()
139}
140
141#[cfg(feature = "macro_utils")]
142#[proc_macro]
143pub fn gen_ident_range(input_tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
144    let input_tokens: TokenStream = input_tokens.into();
145    let out = macro_utils::gen_ident_range(input_tokens).unwrap_or_else(Error::into_compile_error); 
146    out.into()
147}
148
149
150#[cfg(feature = "macro_utils")]
151#[proc_macro]
152pub fn tokens_method(input_tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
153    let input_tokens: TokenStream = input_tokens.into();
154    let out = macro_utils::tokens_method(input_tokens).unwrap_or_else(Error::into_compile_error); 
155    out.into()
156}
157
158
159
160#[doc(hidden)]
161#[proc_macro]
162pub fn __priv_split_generics(input_tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
163    split_generics(input_tokens.into()).into()
164}
165
166fn split_generics(input: TokenStream) -> TokenStream {
167    use crate::{
168        parsing_shared::out_parenthesized,
169        splitting_generics::{PostGenericsParser, SplitGenerics}
170    };
171
172    struct UnparsedPostGenerics {
173        output: TokenStream,
174        output_span: Span,
175    }
176
177    impl PostGenericsParser for UnparsedPostGenerics {
178        fn consume_token(&mut self, sg: &SplitGenerics, tt: TokenTree) {
179            self.output_span = sg.last_span();
180            self.output.extend(once(tt));
181        }
182        fn write_tokens(self, ts: &mut TokenStream) {
183            out_parenthesized(self.output, self.output_span, ts)
184        }
185    }
186
187    let mut input = input.into_iter();
188    let macro_invoc = parsing_shared::panicking_parse_macro_invocation(&mut input);
189
190    SplitGenerics::new(input).split_generics(macro_invoc, TokenStream::new(), UnparsedPostGenerics{
191        output: TokenStream::new(),
192        output_span: Span::call_site(),
193    })
194}
195
196#[cfg(feature = "item_parsing")]
197#[doc(hidden)]
198#[proc_macro]
199pub fn __priv_split_impl(input_tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
200    crate::item_parsing::split_impl(input_tokens.into()).into()
201}
202
203
204
205
206
207// MSRV is 1.41.0, matches was stabilized in 1.42.0
208macro_rules! mmatches {
209    ( $expr:expr, $pat:pat $(if $cond:expr)?)=>{
210        match $expr {
211            $pat  $(if $cond)? =>true,
212            _=>false
213        }
214    };
215} use mmatches;
216
217// Purely for performance
218#[allow(unused_macros)]
219macro_rules! try_ {
220    ( $expr:expr )=>{
221        match $expr {
222            Ok(x) => x,
223            Err(e) => return Err(e),
224        }
225    };
226    ( $expr:expr, map_err = |$e:tt| $map_err:expr )=>{
227        match $expr {
228            Ok(x) => x,
229            Err($e) => return Err($map_err),
230        }
231    };
232}
233#[allow(unused_imports)]
234use try_;