1pub mod borrowed;
5pub mod owned;
6
7use std::ops::Deref;
8
9pub use borrowed::BorrowedFragment;
10pub use owned::OwnedFragment;
11use serde::{Deserialize, Serialize};
12
13#[repr(transparent)]
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
16pub struct StatementColumn(pub u32);
17
18impl Deref for StatementColumn {
19 type Target = u32;
20
21 fn deref(&self) -> &Self::Target {
22 &self.0
23 }
24}
25
26impl PartialEq<i32> for StatementColumn {
27 fn eq(&self, other: &i32) -> bool {
28 self.0 == *other as u32
29 }
30}
31
32#[repr(transparent)]
33#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
34pub struct StatementLine(pub u32);
35
36impl Deref for StatementLine {
37 type Target = u32;
38
39 fn deref(&self) -> &Self::Target {
40 &self.0
41 }
42}
43
44impl PartialEq<i32> for StatementLine {
45 fn eq(&self, other: &i32) -> bool {
46 self.0 == *other as u32
47 }
48}
49
50#[derive(Debug, Clone)]
52pub enum Fragment<'a> {
53 Owned(OwnedFragment),
54 Borrowed(BorrowedFragment<'a>),
55 None,
56}
57
58impl PartialEq<str> for Fragment<'_> {
59 fn eq(&self, other: &str) -> bool {
60 self.text() == other
61 }
62}
63
64impl PartialEq<&str> for Fragment<'_> {
65 fn eq(&self, other: &&str) -> bool {
66 self.text() == *other
67 }
68}
69
70impl PartialEq<String> for Fragment<'_> {
71 fn eq(&self, other: &String) -> bool {
72 self.text() == other.as_str()
73 }
74}
75
76impl PartialEq<String> for &Fragment<'_> {
77 fn eq(&self, other: &String) -> bool {
78 self.text() == other.as_str()
79 }
80}
81
82impl Fragment<'_> {
83 pub fn owned_internal(text: impl Into<String>) -> Self {
84 Fragment::Owned(OwnedFragment::Internal {
85 text: text.into(),
86 })
87 }
88
89 pub fn owned_empty() -> Self {
90 Fragment::Owned(OwnedFragment::testing_empty())
91 }
92
93 pub fn borrowed_internal(text: &str) -> Fragment<'_> {
94 Fragment::Borrowed(BorrowedFragment::Internal {
95 text,
96 })
97 }
98
99 pub fn none() -> Self {
100 Self::None
101 }
102
103 pub fn testing_empty() -> Fragment<'static> {
104 Fragment::Borrowed(BorrowedFragment::Internal {
105 text: "",
106 })
107 }
108}
109
110impl<'a> Fragment<'a> {
111 pub fn text(&self) -> &str {
113 match self {
114 Fragment::Owned(f) => f.text(),
115 Fragment::Borrowed(f) => f.text(),
116 Fragment::None => "",
117 }
118 }
119
120 pub fn line(&self) -> StatementLine {
122 match self {
123 Fragment::Owned(f) => f.line(),
124 Fragment::Borrowed(f) => f.line(),
125 Fragment::None => StatementLine(1),
126 }
127 }
128
129 pub fn column(&self) -> StatementColumn {
131 match self {
132 Fragment::Owned(f) => f.column(),
133 Fragment::Borrowed(f) => f.column(),
134 Fragment::None => StatementColumn(0),
135 }
136 }
137
138 pub fn into_owned(self) -> OwnedFragment {
140 match self {
141 Fragment::Owned(f) => f,
142 Fragment::Borrowed(f) => f.into_owned(),
143 Fragment::None => OwnedFragment::None,
144 }
145 }
146
147 pub fn to_static(self) -> Fragment<'static> {
149 Fragment::Owned(self.into_owned())
150 }
151
152 pub fn as_borrowed(&'a self) -> Fragment<'a> {
154 match self {
155 Fragment::Owned(owned) => match owned {
156 OwnedFragment::None => Fragment::None,
157 OwnedFragment::Statement {
158 text,
159 line,
160 column,
161 } => Fragment::Borrowed(BorrowedFragment::Statement {
162 text: text.as_str(),
163 line: *line,
164 column: *column,
165 }),
166 OwnedFragment::Internal {
167 text,
168 } => Fragment::Borrowed(BorrowedFragment::Internal {
169 text: text.as_str(),
170 }),
171 },
172 Fragment::Borrowed(b) => Fragment::Borrowed(*b),
173 Fragment::None => Fragment::None,
174 }
175 }
176
177 pub fn sub_fragment(&self, offset: usize, length: usize) -> OwnedFragment {
180 match self {
181 Fragment::Owned(f) => f.sub_fragment(offset, length),
182 Fragment::Borrowed(f) => f.sub_fragment(offset, length),
183 Fragment::None => OwnedFragment::None,
184 }
185 }
186
187 pub fn merge_all(fragments: impl IntoIterator<Item = Fragment<'a>>) -> Fragment<'a> {
190 let owned_fragments: Vec<OwnedFragment> = fragments.into_iter().map(|f| f.into_owned()).collect();
191 Fragment::Owned(OwnedFragment::merge_all(owned_fragments))
192 }
193}
194
195pub trait IntoFragment<'a> {
197 fn into_fragment(self) -> Fragment<'a>;
198}
199
200impl<F> IntoFragment<'static> for F
202where
203 F: Fn() -> OwnedFragment,
204{
205 fn into_fragment(self) -> Fragment<'static> {
206 Fragment::Owned(self())
207 }
208}
209
210impl IntoFragment<'static> for &OwnedFragment {
212 fn into_fragment(self) -> Fragment<'static> {
213 Fragment::Owned(self.clone())
214 }
215}
216
217pub trait LazyFragment<'a>: Copy {
220 fn fragment(&self) -> Fragment<'a>;
221}
222
223impl<'a, F> LazyFragment<'a> for F
225where
226 F: Fn() -> Fragment<'a> + Copy,
227{
228 fn fragment(&self) -> Fragment<'a> {
229 self()
230 }
231}
232
233impl<'a> LazyFragment<'a> for Fragment<'a>
236where
237 Fragment<'a>: Copy,
238{
239 fn fragment(&self) -> Fragment<'a> {
240 self.clone()
241 }
242}
243
244impl<'a, 'b> LazyFragment<'a> for &'b Fragment<'a>
246where
247 'a: 'b,
248{
249 fn fragment(&self) -> Fragment<'a> {
250 (*self).clone()
251 }
252}
253
254impl<'a> IntoFragment<'a> for Fragment<'a> {
256 fn into_fragment(self) -> Fragment<'a> {
257 self
258 }
259}
260
261impl<'a> IntoFragment<'a> for &'a Fragment<'a> {
263 fn into_fragment(self) -> Fragment<'a> {
264 self.as_borrowed()
265 }
266}
267
268impl IntoFragment<'_> for OwnedFragment {
270 fn into_fragment(self) -> Fragment<'static> {
271 Fragment::Owned(self)
272 }
273}
274
275impl<'a> IntoFragment<'a> for BorrowedFragment<'a> {
277 fn into_fragment(self) -> Fragment<'a> {
278 Fragment::Owned(self.into_owned())
279 }
280}
281
282impl IntoFragment<'_> for Option<OwnedFragment> {
284 fn into_fragment(self) -> Fragment<'static> {
285 match self {
286 Some(fragment) => Fragment::Owned(fragment),
287 None => Fragment::None,
288 }
289 }
290}
291
292impl From<Option<OwnedFragment>> for OwnedFragment {
294 fn from(fragment_opt: Option<OwnedFragment>) -> Self {
295 fragment_opt.unwrap_or_else(|| OwnedFragment::None)
296 }
297}
298
299impl<'a> From<&'a str> for Fragment<'a> {
301 fn from(s: &'a str) -> Self {
302 Fragment::Borrowed(BorrowedFragment::Internal {
303 text: s,
304 })
305 }
306}
307
308impl From<String> for Fragment<'static> {
310 fn from(s: String) -> Self {
311 Fragment::Owned(OwnedFragment::Internal {
312 text: s,
313 })
314 }
315}
316
317impl<'a> IntoFragment<'a> for &'a str {
320 fn into_fragment(self) -> Fragment<'a> {
321 Fragment::Borrowed(BorrowedFragment::Internal {
322 text: self,
323 })
324 }
325}
326
327impl<'a> IntoFragment<'a> for &'a String {
328 fn into_fragment(self) -> Fragment<'a> {
329 Fragment::Borrowed(BorrowedFragment::Internal {
330 text: self.as_str(),
331 })
332 }
333}
334
335impl IntoFragment<'_> for String {
336 fn into_fragment(self) -> Fragment<'static> {
337 Fragment::Owned(OwnedFragment::Internal {
338 text: self,
339 })
340 }
341}
342
343impl<'a> serde::Serialize for Fragment<'a> {
345 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
346 where
347 S: serde::Serializer,
348 {
349 self.clone().into_owned().serialize(serializer)
350 }
351}
352
353impl<'de, 'a> serde::Deserialize<'de> for Fragment<'a> {
355 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
356 where
357 D: serde::Deserializer<'de>,
358 {
359 let owned = OwnedFragment::deserialize(deserializer)?;
360 Ok(Fragment::Owned(owned))
361 }
362}
363
364impl<'a> PartialEq for Fragment<'a> {
366 fn eq(&self, other: &Self) -> bool {
367 self.text() == other.text()
369 }
370}
371
372impl<'a> Eq for Fragment<'a> {}
373
374impl<'a> std::hash::Hash for Fragment<'a> {
376 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
377 self.text().hash(state);
379 }
380}
381
382impl<'a> AsRef<str> for Fragment<'a> {
384 fn as_ref(&self) -> &str {
385 self.text()
386 }
387}