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 | open: proc_macro::Span, |
26 | close: proc_macro::Span, |
27 | }, |
28 | Fallback(fallback::Span), |
29 | } |
30 | |
31 | impl DelimSpan { |
32 | pub(crate) fn new(group: &imp::Group) -> Self { |
33 | #[cfg (wrap_proc_macro)] |
34 | let inner = match group { |
35 | imp::Group::Compiler(group) => DelimSpanEnum::Compiler { |
36 | join: group.span(), |
37 | open: group.span_open(), |
38 | close: group.span_close(), |
39 | }, |
40 | imp::Group::Fallback(group) => DelimSpanEnum::Fallback(group.span()), |
41 | }; |
42 | |
43 | #[cfg (not(wrap_proc_macro))] |
44 | let inner = DelimSpanEnum::Fallback(group.span()); |
45 | |
46 | DelimSpan { |
47 | inner, |
48 | _marker: Marker, |
49 | } |
50 | } |
51 | |
52 | /// Returns a span covering the entire delimited group. |
53 | pub fn join(&self) -> Span { |
54 | match &self.inner { |
55 | #[cfg (wrap_proc_macro)] |
56 | DelimSpanEnum::Compiler { join, .. } => Span::_new(imp::Span::Compiler(*join)), |
57 | DelimSpanEnum::Fallback(span) => Span::_new_fallback(*span), |
58 | } |
59 | } |
60 | |
61 | /// Returns a span for the opening punctuation of the group only. |
62 | pub fn open(&self) -> Span { |
63 | match &self.inner { |
64 | #[cfg (wrap_proc_macro)] |
65 | DelimSpanEnum::Compiler { open, .. } => Span::_new(imp::Span::Compiler(*open)), |
66 | DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.first_byte()), |
67 | } |
68 | } |
69 | |
70 | /// Returns a span for the closing punctuation of the group only. |
71 | pub fn close(&self) -> Span { |
72 | match &self.inner { |
73 | #[cfg (wrap_proc_macro)] |
74 | DelimSpanEnum::Compiler { close, .. } => Span::_new(imp::Span::Compiler(*close)), |
75 | DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.last_byte()), |
76 | } |
77 | } |
78 | } |
79 | |
80 | impl Debug for DelimSpan { |
81 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
82 | Debug::fmt(&self.join(), f) |
83 | } |
84 | } |
85 | |