1use proc_macro2::{Ident, Span};
2use std::fmt;
3
4pub trait IdentFragment {
11 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;
13
14 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
57macro_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);