1use crate::alloc;
2use crate::ast::Span;
3use crate::parse::NonZeroId;
4
5pub use rune_macros::OptionSpanned;
7
8pub use rune_macros::Spanned;
10
11pub trait Spanned {
13 fn span(&self) -> Span;
15}
16
17impl Spanned for syntree::Span<u32> {
18 fn span(&self) -> Span {
19 Span::new(self.start, self.end)
20 }
21}
22
23impl<A, B> Spanned for (A, B)
24where
25 A: Spanned,
26 B: OptionSpanned,
27{
28 fn span(&self) -> Span {
29 if let Some(end) = self.1.option_span() {
30 self.0.span().join(end)
31 } else {
32 self.0.span()
33 }
34 }
35}
36
37impl Spanned for Span {
38 fn span(&self) -> Span {
39 *self
40 }
41}
42
43impl<T> Spanned for alloc::Box<T>
44where
45 T: Spanned,
46{
47 #[inline]
48 fn span(&self) -> Span {
49 Spanned::span(&**self)
50 }
51}
52
53impl<T> Spanned for &T
54where
55 T: ?Sized + Spanned,
56{
57 fn span(&self) -> Span {
58 Spanned::span(*self)
59 }
60}
61
62impl<T> Spanned for &mut T
63where
64 T: ?Sized + Spanned,
65{
66 fn span(&self) -> Span {
67 Spanned::span(*self)
68 }
69}
70
71impl<S> Spanned for (S, NonZeroId)
72where
73 S: Spanned,
74{
75 fn span(&self) -> Span {
76 self.0.span()
77 }
78}
79
80pub trait OptionSpanned {
82 fn option_span(&self) -> Option<Span>;
84}
85
86impl<T> OptionSpanned for [T]
89where
90 T: Spanned,
91{
92 fn option_span(&self) -> Option<Span> {
93 let span = self.first()?.span();
94
95 if let Some(last) = self.last() {
96 Some(span.join(last.span()))
97 } else {
98 Some(span)
99 }
100 }
101}
102
103impl<T> OptionSpanned for Option<T>
104where
105 T: Spanned,
106{
107 #[inline]
108 fn option_span(&self) -> Option<Span> {
109 Some(self.as_ref()?.span())
110 }
111}
112
113impl<T> OptionSpanned for alloc::Box<T>
114where
115 T: OptionSpanned,
116{
117 #[inline]
118 fn option_span(&self) -> Option<Span> {
119 OptionSpanned::option_span(&**self)
120 }
121}