1 //! Items which do not have a correspondence to any API in the proc_macro crate, 2 //! but are necessary to include in proc-macro2. 3 4 use crate::fallback; 5 use crate::imp; 6 use crate::marker::Marker; 7 use crate::Span; 8 use core::fmt::{self, Debug}; 9 10 /// An object that holds a [`Group`]'s `span_open()` and `span_close()` together 11 /// (in a more compact representation than holding those 2 spans individually. 12 /// 13 /// [`Group`]: crate::Group 14 #[derive(Copy, Clone)] 15 pub struct DelimSpan { 16 inner: DelimSpanEnum, 17 _marker: Marker, 18 } 19 20 #[derive(Copy, Clone)] 21 enum DelimSpanEnum { 22 #[cfg(wrap_proc_macro)] 23 Compiler { 24 join: proc_macro::Span, 25 #[cfg(not(no_group_open_close))] 26 open: proc_macro::Span, 27 #[cfg(not(no_group_open_close))] 28 close: proc_macro::Span, 29 }, 30 Fallback(fallback::Span), 31 } 32 33 impl DelimSpan { new(group: &imp::Group) -> Self34 pub(crate) fn new(group: &imp::Group) -> Self { 35 #[cfg(wrap_proc_macro)] 36 let inner = match group { 37 imp::Group::Compiler(group) => DelimSpanEnum::Compiler { 38 join: group.span(), 39 #[cfg(not(no_group_open_close))] 40 open: group.span_open(), 41 #[cfg(not(no_group_open_close))] 42 close: group.span_close(), 43 }, 44 imp::Group::Fallback(group) => DelimSpanEnum::Fallback(group.span()), 45 }; 46 47 #[cfg(not(wrap_proc_macro))] 48 let inner = DelimSpanEnum::Fallback(group.span()); 49 50 DelimSpan { 51 inner, 52 _marker: Marker, 53 } 54 } 55 56 /// Returns a span covering the entire delimited group. join(&self) -> Span57 pub fn join(&self) -> Span { 58 match &self.inner { 59 #[cfg(wrap_proc_macro)] 60 DelimSpanEnum::Compiler { join, .. } => Span::_new(imp::Span::Compiler(*join)), 61 DelimSpanEnum::Fallback(span) => Span::_new_fallback(*span), 62 } 63 } 64 65 /// Returns a span for the opening punctuation of the group only. open(&self) -> Span66 pub fn open(&self) -> Span { 67 match &self.inner { 68 #[cfg(wrap_proc_macro)] 69 DelimSpanEnum::Compiler { 70 #[cfg(not(no_group_open_close))] 71 open, 72 #[cfg(no_group_open_close)] 73 join: open, 74 .. 75 } => Span::_new(imp::Span::Compiler(*open)), 76 DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.first_byte()), 77 } 78 } 79 80 /// Returns a span for the closing punctuation of the group only. close(&self) -> Span81 pub fn close(&self) -> Span { 82 match &self.inner { 83 #[cfg(wrap_proc_macro)] 84 DelimSpanEnum::Compiler { 85 #[cfg(not(no_group_open_close))] 86 close, 87 #[cfg(no_group_open_close)] 88 join: close, 89 .. 90 } => Span::_new(imp::Span::Compiler(*close)), 91 DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.last_byte()), 92 } 93 } 94 } 95 96 impl Debug for DelimSpan { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result97 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 98 Debug::fmt(&self.join(), f) 99 } 100 } 101