syn_pub_items/
ext.rs

1//! Extension traits to provide parsing methods on foreign types.
2//!
3//! *This module is available if Syn is built with the `"parsing"` feature.*
4
5use proc_macro2::Ident;
6
7use parse::{ParseStream, Result};
8
9/// Additional parsing methods for `Ident`.
10///
11/// This trait is sealed and cannot be implemented for types outside of Syn.
12///
13/// *This trait is available if Syn is built with the `"parsing"` feature.*
14pub trait IdentExt: Sized + private::Sealed {
15    /// Parses any identifier including keywords.
16    ///
17    /// This is useful when parsing a DSL which allows Rust keywords as
18    /// identifiers.
19    ///
20    /// ```edition2018
21    /// use syn::{Error, Ident, Result, Token};
22    /// use syn::ext::IdentExt;
23    /// use syn::parse::ParseStream;
24    ///
25    /// // Parses input that looks like `name = NAME` where `NAME` can be
26    /// // any identifier.
27    /// //
28    /// // Examples:
29    /// //
30    /// //     name = anything
31    /// //     name = impl
32    /// fn parse_dsl(input: ParseStream) -> Result<Ident> {
33    ///     let name_token: Ident = input.parse()?;
34    ///     if name_token != "name" {
35    ///         return Err(Error::new(name_token.span(), "expected `name`"));
36    ///     }
37    ///     input.parse::<Token![=]>()?;
38    ///     let name = input.call(Ident::parse_any)?;
39    ///     Ok(name)
40    /// }
41    /// ```
42    fn parse_any(input: ParseStream) -> Result<Self>;
43}
44
45impl IdentExt for Ident {
46    fn parse_any(input: ParseStream) -> Result<Self> {
47        input.step(|cursor| match cursor.ident() {
48            Some((ident, rest)) => Ok((ident, rest)),
49            None => Err(cursor.error("expected ident")),
50        })
51    }
52}
53
54mod private {
55    use proc_macro2::Ident;
56
57    pub trait Sealed {}
58
59    impl Sealed for Ident {}
60}