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