Skip to content

Commit 0f98def

Browse files
committed
Support renaming in custom_keyword macro
1 parent 6232266 commit 0f98def

File tree

2 files changed

+59
-15
lines changed

2 files changed

+59
-15
lines changed

src/custom_keyword.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@
1313
/// }
1414
/// ```
1515
///
16+
/// To specify a different name for the resulting Rust item, a name can be
17+
/// provided:
18+
///
19+
/// ```
20+
/// syn::custom_keyword!(whatever as Whatever);
21+
/// ```
22+
///
1623
/// The generated syntax tree node supports the following operations just like
1724
/// any built-in keyword token.
1825
///
@@ -89,6 +96,9 @@
8996
#[macro_export]
9097
macro_rules! custom_keyword {
9198
($ident:ident) => {
99+
$crate::custom_keyword!{$ident as $ident}
100+
};
101+
($keyword:ident as $ident:ident) => {
92102
#[allow(non_camel_case_types)]
93103
pub struct $ident {
94104
#[allow(dead_code)]
@@ -114,10 +124,10 @@ macro_rules! custom_keyword {
114124
}
115125
}
116126

117-
$crate::impl_parse_for_custom_keyword!($ident);
118-
$crate::impl_to_tokens_for_custom_keyword!($ident);
127+
$crate::impl_parse_for_custom_keyword!($keyword as $ident);
128+
$crate::impl_to_tokens_for_custom_keyword!($keyword as $ident);
119129
$crate::impl_clone_for_custom_keyword!($ident);
120-
$crate::impl_extra_traits_for_custom_keyword!($ident);
130+
$crate::impl_extra_traits_for_custom_keyword!($keyword as $ident);
121131
};
122132
};
123133
}
@@ -127,33 +137,33 @@ macro_rules! custom_keyword {
127137
#[doc(hidden)]
128138
#[macro_export]
129139
macro_rules! impl_parse_for_custom_keyword {
130-
($ident:ident) => {
140+
($keyword:ident as $ident:ident) => {
131141
// For peek.
132142
impl $crate::__private::CustomToken for $ident {
133143
fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool {
134144
if let $crate::__private::Some((ident, _rest)) = cursor.ident() {
135-
ident == $crate::__private::stringify!($ident)
145+
ident == $crate::__private::stringify!($keyword)
136146
} else {
137147
false
138148
}
139149
}
140150

141151
fn display() -> &'static $crate::__private::str {
142-
$crate::__private::concat!("`", $crate::__private::stringify!($ident), "`")
152+
$crate::__private::concat!("`", $crate::__private::stringify!($keyword), "`")
143153
}
144154
}
145155

146156
impl $crate::parse::Parse for $ident {
147157
fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> {
148158
input.step(|cursor| {
149159
if let $crate::__private::Some((ident, rest)) = cursor.ident() {
150-
if ident == $crate::__private::stringify!($ident) {
160+
if ident == $crate::__private::stringify!($keyword) {
151161
return $crate::__private::Ok(($ident { span: ident.span() }, rest));
152162
}
153163
}
154164
$crate::__private::Err(cursor.error($crate::__private::concat!(
155165
"expected `",
156-
$crate::__private::stringify!($ident),
166+
$crate::__private::stringify!($keyword),
157167
"`",
158168
)))
159169
})
@@ -167,18 +177,18 @@ macro_rules! impl_parse_for_custom_keyword {
167177
#[doc(hidden)]
168178
#[macro_export]
169179
macro_rules! impl_parse_for_custom_keyword {
170-
($ident:ident) => {};
180+
($keyword:ident as $ident:ident) => {};
171181
}
172182

173183
// Not public API.
174184
#[cfg(feature = "printing")]
175185
#[doc(hidden)]
176186
#[macro_export]
177187
macro_rules! impl_to_tokens_for_custom_keyword {
178-
($ident:ident) => {
188+
($keyword:ident as $ident:ident) => {
179189
impl $crate::__private::ToTokens for $ident {
180190
fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) {
181-
let ident = $crate::Ident::new($crate::__private::stringify!($ident), self.span);
191+
let ident = $crate::Ident::new($crate::__private::stringify!($keyword), self.span);
182192
$crate::__private::TokenStreamExt::append(tokens, ident);
183193
}
184194
}
@@ -190,7 +200,7 @@ macro_rules! impl_to_tokens_for_custom_keyword {
190200
#[doc(hidden)]
191201
#[macro_export]
192202
macro_rules! impl_to_tokens_for_custom_keyword {
193-
($ident:ident) => {};
203+
($keyword:ident as $ident:ident) => {};
194204
}
195205

196206
// Not public API.
@@ -223,14 +233,14 @@ macro_rules! impl_clone_for_custom_keyword {
223233
#[doc(hidden)]
224234
#[macro_export]
225235
macro_rules! impl_extra_traits_for_custom_keyword {
226-
($ident:ident) => {
236+
($keyword:ident as $ident:ident) => {
227237
impl $crate::__private::Debug for $ident {
228238
fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::FmtResult {
229239
$crate::__private::Formatter::write_str(
230240
f,
231241
$crate::__private::concat!(
232242
"Keyword [",
233-
$crate::__private::stringify!($ident),
243+
$crate::__private::stringify!($keyword),
234244
"]",
235245
),
236246
)
@@ -256,5 +266,5 @@ macro_rules! impl_extra_traits_for_custom_keyword {
256266
#[doc(hidden)]
257267
#[macro_export]
258268
macro_rules! impl_extra_traits_for_custom_keyword {
259-
($ident:ident) => {};
269+
($keyword:ident as $ident:ident) => {};
260270
}

tests/custom_keyword.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use proc_macro2::Span;
2+
use quote::quote;
3+
use syn::{
4+
custom_keyword,
5+
parse::{Parse, ParseStream, Parser},
6+
};
7+
8+
custom_keyword!(implicit);
9+
custom_keyword!(explicit as Explicit);
10+
11+
#[test]
12+
fn parsing() {
13+
(|input: ParseStream| {
14+
assert!(input.peek(implicit));
15+
implicit::parse(input).unwrap();
16+
assert!(input.peek(Explicit));
17+
Explicit::parse(input).unwrap();
18+
Ok(())
19+
})
20+
.parse2(quote!(implicit explicit))
21+
.unwrap();
22+
}
23+
24+
#[test]
25+
fn printing() {
26+
let implicit = implicit(Span::call_site());
27+
let explicit = Explicit(Span::call_site());
28+
29+
assert_eq!(
30+
format!("{implicit:?} {explicit:?}"),
31+
"Keyword [implicit] Keyword [explicit]"
32+
);
33+
assert_eq!(quote!(#implicit #explicit).to_string(), "implicit explicit");
34+
}

0 commit comments

Comments
 (0)