sql_parse/
span.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13use alloc::{boxed::Box, vec::Vec};
14
15/// Byte span of ast fragment
16pub type Span = core::ops::Range<usize>;
17
18/// Compute an optional byte span of an ast fragment
19
20pub trait OptSpanned {
21    /// Compute an optional byte span of an ast fragment
22    fn opt_span(&self) -> Option<Span>;
23
24    /// Compute the minimal span containing both self and other
25    /// if either is missing return the other
26    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
35/// Compute byte span of an ast fragment
36pub trait Spanned {
37    /// Compute byte span of an ast fragment
38    fn span(&self) -> Span;
39
40    /// Compute the minimal span containing both self and other
41    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}