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
16extern 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 let out = macro_utils::rewrap_macro_parameters(input_tokens);
129 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
207macro_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#[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_;