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