rune/ast/
spanned.rs
1use crate::alloc;
2use crate::ast::Span;
3use crate::parse::NonZeroId;
4
5pub use rune_macros::Spanned;
7
8pub use rune_macros::OptionSpanned;
10
11pub(crate) fn from_fn<F>(function: F) -> FromFn<F> {
13 FromFn { function }
14}
15
16#[derive(Clone, Copy)]
18pub(crate) struct FromFn<F> {
19 function: F,
20}
21
22impl<F> Spanned for FromFn<F>
23where
24 F: Fn() -> Span,
25{
26 #[inline]
27 fn span(&self) -> Span {
28 (self.function)()
29 }
30}
31
32pub trait Spanned {
34 fn span(&self) -> Span;
36}
37
38impl Spanned for syntree::Span<u32> {
39 fn span(&self) -> Span {
40 Span::new(self.start, self.end)
41 }
42}
43
44impl<A, B> Spanned for (A, B)
45where
46 A: Spanned,
47 B: OptionSpanned,
48{
49 fn span(&self) -> Span {
50 if let Some(end) = self.1.option_span() {
51 self.0.span().join(end)
52 } else {
53 self.0.span()
54 }
55 }
56}
57
58impl Spanned for Span {
59 fn span(&self) -> Span {
60 *self
61 }
62}
63
64#[cfg(feature = "alloc")]
65impl<T> Spanned for ::rust_alloc::boxed::Box<T>
66where
67 T: Spanned,
68{
69 fn span(&self) -> Span {
70 Spanned::span(&**self)
71 }
72}
73
74impl<T> Spanned for alloc::Box<T>
75where
76 T: Spanned,
77{
78 fn span(&self) -> Span {
79 Spanned::span(&**self)
80 }
81}
82
83impl<T> Spanned for &T
84where
85 T: ?Sized + Spanned,
86{
87 fn span(&self) -> Span {
88 Spanned::span(*self)
89 }
90}
91
92impl<T> Spanned for &mut T
93where
94 T: ?Sized + Spanned,
95{
96 fn span(&self) -> Span {
97 Spanned::span(*self)
98 }
99}
100
101impl<S> Spanned for (S, NonZeroId)
102where
103 S: Spanned,
104{
105 fn span(&self) -> Span {
106 self.0.span()
107 }
108}
109
110pub trait OptionSpanned {
112 fn option_span(&self) -> Option<Span>;
114}
115
116impl<T> OptionSpanned for [T]
119where
120 T: Spanned,
121{
122 fn option_span(&self) -> Option<Span> {
123 let span = self.first()?.span();
124
125 if let Some(last) = self.last() {
126 Some(span.join(last.span()))
127 } else {
128 Some(span)
129 }
130 }
131}
132
133impl<T> OptionSpanned for Option<T>
134where
135 T: Spanned,
136{
137 fn option_span(&self) -> Option<Span> {
138 Some(self.as_ref()?.span())
139 }
140}
141
142#[cfg(feature = "alloc")]
143impl<T> OptionSpanned for ::rust_alloc::boxed::Box<T>
144where
145 T: OptionSpanned,
146{
147 fn option_span(&self) -> Option<Span> {
148 OptionSpanned::option_span(&**self)
149 }
150}
151
152impl<T> OptionSpanned for alloc::Box<T>
153where
154 T: OptionSpanned,
155{
156 fn option_span(&self) -> Option<Span> {
157 OptionSpanned::option_span(&**self)
158 }
159}