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