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
19pub trait OptSpanned {
20    /// Compute an optional byte span of an ast fragment
21    fn opt_span(&self) -> Option<Span>;
22
23    /// Compute the minimal span containing both self and other
24    /// if either is missing return the other
25    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
34/// Compute byte span of an ast fragment
35pub trait Spanned {
36    /// Compute byte span of an ast fragment
37    fn span(&self) -> Span;
38
39    /// Compute the minimal span containing both self and other
40    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}