File Index
Files and directories
Sign in
FILE

ext.rs

File preview with syntax highlighting.

linux-6.19.14/rust/syn/ext.rs RUST
  1// SPDX-License-Identifier: Apache-2.0 OR MIT
  2
  3//! Extension traits to provide parsing methods on foreign types.
  4
  5use crate::buffer::Cursor;
  6use crate::error::Result;
  7use crate::parse::ParseStream;
  8use crate::parse::Peek;
  9use crate::sealed::lookahead;
 10use crate::token::CustomToken;
 11use proc_macro2::Ident;
 12
 13/// Additional methods for `Ident` not provided by proc-macro2 or libproc_macro.
 14///
 15/// This trait is sealed and cannot be implemented for types outside of Syn. It
 16/// is implemented only for `proc_macro2::Ident`.
 17pub trait IdentExt: Sized + private::Sealed {
 18    /// Parses any identifier including keywords.
 19    ///
 20    /// This is useful when parsing macro input which allows Rust keywords as
 21    /// identifiers.
 22    ///
 23    /// # Example
 24    ///
 25    /// ```
 26    /// use syn::{Error, Ident, Result, Token};
 27    /// use syn::ext::IdentExt;
 28    /// use syn::parse::ParseStream;
 29    ///
 30    /// mod kw {
 31    ///     syn::custom_keyword!(name);
 32    /// }
 33    ///
 34    /// // Parses input that looks like `name = NAME` where `NAME` can be
 35    /// // any identifier.
 36    /// //
 37    /// // Examples:
 38    /// //
 39    /// //     name = anything
 40    /// //     name = impl
 41    /// fn parse_dsl(input: ParseStream) -> Result<Ident> {
 42    ///     input.parse::<kw::name>()?;
 43    ///     input.parse::<Token![=]>()?;
 44    ///     let name = input.call(Ident::parse_any)?;
 45    ///     Ok(name)
 46    /// }
 47    /// ```
 48    fn parse_any(input: ParseStream) -> Result<Self>;
 49
 50    /// Peeks any identifier including keywords. Usage:
 51    /// `input.peek(Ident::peek_any)`
 52    ///
 53    /// This is different from `input.peek(Ident)` which only returns true in
 54    /// the case of an ident which is not a Rust keyword.
 55    #[allow(non_upper_case_globals)]
 56    const peek_any: private::PeekFn = private::PeekFn;
 57
 58    /// Strips the raw marker `r#`, if any, from the beginning of an ident.
 59    ///
 60    ///   - unraw(`x`) = `x`
 61    ///   - unraw(`move`) = `move`
 62    ///   - unraw(`r#move`) = `move`
 63    ///
 64    /// # Example
 65    ///
 66    /// In the case of interop with other languages like Python that have a
 67    /// different set of keywords than Rust, we might come across macro input
 68    /// that involves raw identifiers to refer to ordinary variables in the
 69    /// other language with a name that happens to be a Rust keyword.
 70    ///
 71    /// The function below appends an identifier from the caller's input onto a
 72    /// fixed prefix. Without using `unraw()`, this would tend to produce
 73    /// invalid identifiers like `__pyo3_get_r#move`.
 74    ///
 75    /// ```
 76    /// use proc_macro2::Span;
 77    /// use syn::Ident;
 78    /// use syn::ext::IdentExt;
 79    ///
 80    /// fn ident_for_getter(variable: &Ident) -> Ident {
 81    ///     let getter = format!("__pyo3_get_{}", variable.unraw());
 82    ///     Ident::new(&getter, Span::call_site())
 83    /// }
 84    /// ```
 85    fn unraw(&self) -> Ident;
 86}
 87
 88impl IdentExt for Ident {
 89    fn parse_any(input: ParseStream) -> Result<Self> {
 90        input.step(|cursor| match cursor.ident() {
 91            Some((ident, rest)) => Ok((ident, rest)),
 92            None => Err(cursor.error("expected ident")),
 93        })
 94    }
 95
 96    fn unraw(&self) -> Ident {
 97        let string = self.to_string();
 98        if let Some(string) = string.strip_prefix("r#") {
 99            Ident::new(string, self.span())
100        } else {
101            self.clone()
102        }
103    }
104}
105
106impl Peek for private::PeekFn {
107    type Token = private::IdentAny;
108}
109
110impl CustomToken for private::IdentAny {
111    fn peek(cursor: Cursor) -> bool {
112        cursor.ident().is_some()
113    }
114
115    fn display() -> &'static str {
116        "identifier"
117    }
118}
119
120impl lookahead::Sealed for private::PeekFn {}
121
122mod private {
123    use proc_macro2::Ident;
124
125    pub trait Sealed {}
126
127    impl Sealed for Ident {}
128
129    pub struct PeekFn;
130    pub struct IdentAny;
131
132    impl Copy for PeekFn {}
133    impl Clone for PeekFn {
134        fn clone(&self) -> Self {
135            *self
136        }
137    }
138}
~/ Read-only file preview.