1use alloc::{boxed::Box, vec::Vec};
14
15pub type Span = core::ops::Range<usize>;
17
18pub trait OptSpanned {
20 fn opt_span(&self) -> Option<Span>;
22
23 fn opt_join_span(&self, other: &impl OptSpanned) -> Option<Span> {
26 if let Some(l) = self.opt_span() {
27 Some(l.join_span(other))
28 } else {
29 other.opt_span()
30 }
31 }
32}
33
34pub trait Spanned {
36 fn span(&self) -> Span;
38
39 fn join_span(&self, other: &impl OptSpanned) -> Span {
41 let l = self.span();
42 if let Some(r) = other.opt_span() {
43 usize::min(l.start, r.start)..usize::max(l.end, r.end)
44 } else {
45 l
46 }
47 }
48}
49
50impl<T: Spanned> OptSpanned for T {
51 fn opt_span(&self) -> Option<Span> {
52 Some(self.span())
53 }
54}
55
56impl Spanned for Span {
57 fn span(&self) -> Span {
58 self.clone()
59 }
60}
61
62impl<T: Spanned> Spanned for Box<T> {
63 fn span(&self) -> Span {
64 self.as_ref().span()
65 }
66}
67
68impl<T: OptSpanned> OptSpanned for Option<T> {
69 fn opt_span(&self) -> Option<Span> {
70 match &self {
71 Some(v) => v.opt_span(),
72 None => None,
73 }
74 }
75}
76
77impl<T: OptSpanned> OptSpanned for Vec<T> {
78 fn opt_span(&self) -> Option<Span> {
79 self.iter().fold(None, |a, b| a.opt_join_span(b))
80 }
81}
82
83impl<T: OptSpanned> OptSpanned for [T] {
84 fn opt_span(&self) -> Option<Span> {
85 self.iter().fold(None, |a, b| a.opt_join_span(b))
86 }
87}
88
89impl<S: Spanned> Spanned for (usize, S) {
90 fn span(&self) -> Span {
91 self.1.span()
92 }
93}
94
95impl<S: Spanned> Spanned for (usize, usize, S) {
96 fn span(&self) -> Span {
97 self.2.span()
98 }
99}
100
101impl<S: Spanned> Spanned for (u32, S) {
102 fn span(&self) -> Span {
103 self.1.span()
104 }
105}
106
107impl<S: Spanned> Spanned for (u64, S) {
108 fn span(&self) -> Span {
109 self.1.span()
110 }
111}
112
113impl<S: Spanned> Spanned for (f64, S) {
114 fn span(&self) -> Span {
115 self.1.span()
116 }
117}
118
119impl<S: Spanned> Spanned for (bool, S) {
120 fn span(&self) -> Span {
121 self.1.span()
122 }
123}
124
125impl<S: Spanned> Spanned for (&str, S) {
126 fn span(&self) -> Span {
127 self.1.span()
128 }
129}
130
131impl<'a, S: Spanned> Spanned for (alloc::borrow::Cow<'a, str>, S) {
132 fn span(&self) -> Span {
133 self.1.span()
134 }
135}
136
137impl<S: Spanned, O: OptSpanned> Spanned for (S, O) {
138 fn span(&self) -> Span {
139 self.0.join_span(&self.1)
140 }
141}
142
143impl<T1: Spanned, T2: OptSpanned, T3: OptSpanned> Spanned for (T1, T2, T3) {
144 fn span(&self) -> Span {
145 self.0.join_span(&self.1).join_span(&self.2)
146 }
147}