proc_macro_tool/
span.rs

1use proc_macro::{Group, Ident, Literal, Punct, Span, TokenTree};
2
3/// General implementations of [`TokenTree::span`]
4pub trait GetSpan: Sized {
5    /// Call [`TokenTree::span`]
6    #[must_use]
7    fn span(&self) -> Span;
8
9    /// `*dst = self.span()`
10    #[must_use]
11    fn span_as(self, dst: &mut impl SetSpan) -> Self {
12        dst.set_span(self.span());
13        self
14    }
15
16    /// For [`Group`], it will return ([`span_open`], [`span_close`])
17    ///
18    /// [`span_open`]: Group::span_open
19    /// [`span_close`]: Group::span_close
20    #[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
58/// General implementations of [`TokenTree::set_span`]
59pub trait SetSpan: GetSpan + Sized {
60    /// Call [`TokenTree::set_span`]
61    fn set_span(&mut self, span: Span);
62
63    /// Like `{let mut x = this; x.set_span(span); x}`
64    #[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}