blob: 16d0dbfbbf5bc866afabc712cd93a47df1c4f67e [file] [log] [blame]
David Tolnayac51b362018-08-30 23:59:52 -07001//! Extension traits to provide parsing methods on foreign types.
David Tolnay94d304f2018-08-30 23:43:53 -07002//!
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 /// ```rust
David Tolnaya1c98072018-09-06 08:58:10 -070021 /// #[macro_use]
22 /// extern crate syn;
23 ///
David Tolnay67fea042018-11-24 14:50:20 -080024 /// use syn::{Error, Ident, Result};
David Tolnayac51b362018-08-30 23:59:52 -070025 /// use syn::ext::IdentExt;
David Tolnay67fea042018-11-24 14:50:20 -080026 /// use syn::parse::ParseStream;
David Tolnay94d304f2018-08-30 23:43:53 -070027 ///
28 /// // Parses input that looks like `name = NAME` where `NAME` can be
29 /// // any identifier.
30 /// //
31 /// // Examples:
32 /// //
33 /// // name = anything
34 /// // name = impl
David Tolnayac51b362018-08-30 23:59:52 -070035 /// fn parse_dsl(input: ParseStream) -> Result<Ident> {
36 /// let name_token: Ident = input.parse()?;
37 /// if name_token != "name" {
38 /// return Err(Error::new(name_token.span(), "expected `name`"));
39 /// }
40 /// input.parse::<Token![=]>()?;
41 /// let name = input.call(Ident::parse_any)?;
42 /// Ok(name)
43 /// }
David Tolnay94d304f2018-08-30 23:43:53 -070044 /// #
45 /// # fn main() {}
46 /// ```
47 fn parse_any(input: ParseStream) -> Result<Self>;
48}
49
50impl IdentExt for Ident {
51 fn parse_any(input: ParseStream) -> Result<Self> {
52 input.step(|cursor| match cursor.ident() {
53 Some((ident, rest)) => Ok((ident, rest)),
54 None => Err(cursor.error("expected ident")),
55 })
56 }
57}
58
59mod private {
60 use proc_macro2::Ident;
61
62 pub trait Sealed {}
63
64 impl Sealed for Ident {}
65}