1use proc_macro::{Group, Ident, Literal, Punct, Span, TokenTree};
2
3pub trait GetSpan: Sized {
5 #[must_use]
7 fn span(&self) -> Span;
8
9 #[must_use]
11 fn span_as(self, dst: &mut impl SetSpan) -> Self {
12 dst.set_span(self.span());
13 self
14 }
15
16 #[must_use]
21 fn span_region(&self) -> (Span, Span) {
22 (self.span(), self.span())
23 }
24}
25impl<T: GetSpan> GetSpan for &T {
26 fn span(&self) -> Span {
27 (**self).span()
28 }
29
30 fn span_region(&self) -> (Span, Span) {
31 (**self).span_region()
32 }
33}
34impl<T: GetSpan> GetSpan for &mut T {
35 fn span(&self) -> Span {
36 (**self).span()
37 }
38
39 fn span_region(&self) -> (Span, Span) {
40 (**self).span_region()
41 }
42}
43impl GetSpan for Group {
44 fn span(&self) -> Span {
45 self.span()
46 }
47
48 fn span_region(&self) -> (Span, Span) {
49 (self.span_open(), self.span_close())
50 }
51}
52impl GetSpan for Span {
53 fn span(&self) -> Span {
54 *self
55 }
56}
57
58pub trait SetSpan: GetSpan + Sized {
60 fn set_span(&mut self, span: Span);
62
63 #[must_use]
65 fn set_spaned(mut self, span: Span) -> Self {
66 self.set_span(span);
67 self
68 }
69}
70
71macro_rules! impl_set_span {
72 ($ty:ty) => {
73 impl GetSpan for $ty {
74 fn span(&self) -> Span {
75 self.span()
76 }
77 }
78 impl SetSpan for $ty {
79 fn set_span(&mut self, span: Span) {
80 self.set_span(span);
81 }
82 }
83 };
84}
85impl_set_span!(TokenTree);
86impl_set_span!(Ident);
87impl_set_span!(Punct);
88impl_set_span!(Literal);
89impl SetSpan for Group {
90 fn set_span(&mut self, span: Span) {
91 self.set_span(span);
92 }
93}
94impl<T: SetSpan> SetSpan for &mut T {
95 fn set_span(&mut self, span: Span) {
96 (*self).set_span(span);
97 }
98}
99impl SetSpan for Span {
100 fn set_span(&mut self, span: Span) {
101 *self = span
102 }
103}