Extension method to unraw an ident
diff --git a/src/ext.rs b/src/ext.rs
index ca6d70d..8d679e7 100644
--- a/src/ext.rs
+++ b/src/ext.rs
@@ -6,9 +6,10 @@
use parse::{ParseStream, Result};
-/// Additional parsing methods for `Ident`.
+/// Additional methods for `Ident` not provided by proc-macro2 or libproc_macro.
///
-/// This trait is sealed and cannot be implemented for types outside of Syn.
+/// This trait is sealed and cannot be implemented for types outside of Syn. It
+/// is implemented only for `proc_macro2::Ident`.
///
/// *This trait is available if Syn is built with the `"parsing"` feature.*
pub trait IdentExt: Sized + private::Sealed {
@@ -17,6 +18,8 @@
/// This is useful when parsing a DSL which allows Rust keywords as
/// identifiers.
///
+ /// # Example
+ ///
/// ```edition2018
/// use syn::{Error, Ident, Result, Token};
/// use syn::ext::IdentExt;
@@ -40,6 +43,35 @@
/// }
/// ```
fn parse_any(input: ParseStream) -> Result<Self>;
+
+ /// Strips the raw marker `r#`, if any, from the beginning of an ident.
+ ///
+ /// - unraw(`x`) = `x`
+ /// - unraw(`move`) = `move`
+ /// - unraw(`r#move`) = `move`
+ ///
+ /// # Example
+ ///
+ /// In the case of interop with other languages like Python that have a
+ /// different set of keywords than Rust, we might come across macro input
+ /// that involves raw identifiers to refer to ordinary variables in the
+ /// other language with a name that happens to be a Rust keyword.
+ ///
+ /// The function below appends an identifier from the caller's input onto a
+ /// fixed prefix. Without using `unraw()`, this would tend to produce
+ /// invalid identifiers like `__pyo3_get_r#move`.
+ ///
+ /// ```edition2018
+ /// use proc_macro2::Span;
+ /// use syn::Ident;
+ /// use syn::ext::IdentExt;
+ ///
+ /// fn ident_for_getter(variable: &Ident) -> Ident {
+ /// let getter = format!("__pyo3_get_{}", variable.unraw());
+ /// Ident::new(&getter, Span::call_site())
+ /// }
+ /// ```
+ fn unraw(&self) -> Ident;
}
impl IdentExt for Ident {
@@ -49,6 +81,15 @@
None => Err(cursor.error("expected ident")),
})
}
+
+ fn unraw(&self) -> Ident {
+ let string = self.to_string();
+ if string.starts_with("r#") {
+ Ident::new(&string[2..], self.span())
+ } else {
+ self.clone()
+ }
+ }
}
mod private {