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
4use crate::fallback;
5use crate::imp;
6use crate::marker::Marker;
7use crate::Span;
8use 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)]
15pub struct DelimSpan {
16 inner: DelimSpanEnum,
17 _marker: Marker,
18}
19
20#[derive(Copy, Clone)]
21enum 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
31impl 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
80impl Debug for DelimSpan {
81 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82 Debug::fmt(&self.join(), f)
83 }
84}
85