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