quote/
ident_fragment.rs

1use proc_macro2::{Ident, Span};
2use std::fmt;
3
4/// Specialized formatting trait used by `format_ident!`.
5///
6/// [`Ident`] arguments formatted using this trait will have their `r#` prefix
7/// stripped, if present.
8///
9/// See [`format_ident!`] for more information.
10pub trait IdentFragment {
11    /// Format this value as an identifier fragment.
12    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;
13
14    /// Span associated with this `IdentFragment`.
15    ///
16    /// If non-`None`, may be inherited by formatted identifiers.
17    fn span(&self) -> Option<Span> {
18        None
19    }
20}
21
22impl<'a, T: IdentFragment + ?Sized> IdentFragment for &'a T {
23    fn span(&self) -> Option<Span> {
24        <T as IdentFragment>::span(*self)
25    }
26
27    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28        IdentFragment::fmt(*self, f)
29    }
30}
31
32impl<'a, T: IdentFragment + ?Sized> IdentFragment for &'a mut T {
33    fn span(&self) -> Option<Span> {
34        <T as IdentFragment>::span(*self)
35    }
36
37    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38        IdentFragment::fmt(*self, f)
39    }
40}
41
42impl IdentFragment for Ident {
43    fn span(&self) -> Option<Span> {
44        Some(self.span())
45    }
46
47    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48        let id = self.to_string();
49        if id.starts_with("r#") {
50            fmt::Display::fmt(&id[2..], f)
51        } else {
52            fmt::Display::fmt(&id[..], f)
53        }
54    }
55}
56
57// Limited set of types which this is implemented for, as we want to avoid types
58// which will often include non-identifier characters in their `Display` impl.
59macro_rules! ident_fragment_display {
60    ($($T:ty),*) => {
61        $(
62            impl IdentFragment for $T {
63                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64                    fmt::Display::fmt(self, f)
65                }
66            }
67        )*
68    }
69}
70
71ident_fragment_display!(bool, str, String);
72ident_fragment_display!(u8, u16, u32, u64, u128, usize);