syn_solidity/yul/ident/
mod.rs

1use crate::Spanned;
2use proc_macro2::{Ident, Span};
3use quote::ToTokens;
4use std::fmt;
5use syn::{
6    ext::IdentExt,
7    parse::{Parse, ParseStream},
8    Result,
9};
10
11mod path;
12pub use path::YulPath;
13
14/// A Yul identifier.
15///
16/// Solidity Reference:
17/// <https://docs.soliditylang.org/en/latest/grammar.html#a4.SolidityLexer.YulIdentifier>
18#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
19#[repr(transparent)]
20pub struct YulIdent(pub Ident);
21
22impl quote::IdentFragment for YulIdent {
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        self.0.fmt(f)
25    }
26
27    fn span(&self) -> Option<Span> {
28        Some(self.0.span())
29    }
30}
31
32impl fmt::Display for YulIdent {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        self.0.fmt(f)
35    }
36}
37
38impl fmt::Debug for YulIdent {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        f.debug_tuple("YulIdent").field(&self.0).finish()
41    }
42}
43
44impl<T: ?Sized + AsRef<str>> PartialEq<T> for YulIdent {
45    fn eq(&self, other: &T) -> bool {
46        self.0 == other
47    }
48}
49
50impl From<Ident> for YulIdent {
51    fn from(value: Ident) -> Self {
52        Self(value)
53    }
54}
55
56impl From<YulIdent> for Ident {
57    fn from(value: YulIdent) -> Self {
58        value.0
59    }
60}
61
62impl From<&str> for YulIdent {
63    fn from(value: &str) -> Self {
64        Self::new(value)
65    }
66}
67
68impl Parse for YulIdent {
69    fn parse(input: ParseStream<'_>) -> Result<Self> {
70        Self::parse_any(input)
71    }
72}
73
74impl ToTokens for YulIdent {
75    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
76        self.0.to_tokens(tokens);
77    }
78}
79
80impl Spanned for YulIdent {
81    fn span(&self) -> Span {
82        self.0.span()
83    }
84
85    fn set_span(&mut self, span: Span) {
86        self.0.set_span(span);
87    }
88}
89
90impl YulIdent {
91    pub fn new(s: &str) -> Self {
92        Self(Ident::new(s, Span::call_site()))
93    }
94
95    pub fn new_spanned(s: &str, span: Span) -> Self {
96        Self(Ident::new(s, span))
97    }
98
99    /// Returns the identifier as a string, without the `r#` prefix if present.
100    pub fn as_string(&self) -> String {
101        let mut s = self.0.to_string();
102        if s.starts_with("r#") {
103            s = s[2..].to_string();
104        }
105        s
106    }
107
108    /// Parses any identifier including keywords.
109    pub fn parse_any(input: ParseStream<'_>) -> Result<Self> {
110        input.call(Ident::parse_any).map(Self)
111    }
112
113    /// Peeks any identifier including keywords.
114    pub fn peek_any(input: ParseStream<'_>) -> bool {
115        input.peek(Ident::peek_any)
116    }
117
118    pub fn parse_opt(input: ParseStream<'_>) -> Result<Option<Self>> {
119        if Self::peek_any(input) {
120            input.parse().map(Some)
121        } else {
122            Ok(None)
123        }
124    }
125}