reifydb_type/fragment/
borrowed.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the MIT, see license.md file
3
4use super::{OwnedFragment, StatementColumn, StatementLine};
5
6/// Borrowed fragment - zero-copy for parsing
7#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
8pub enum BorrowedFragment<'a> {
9	/// No fragment information available
10	None,
11
12	/// Fragment from a RQL statement with position information
13	Statement {
14		text: &'a str,
15		line: StatementLine,
16		column: StatementColumn,
17	},
18
19	/// Fragment from internal/runtime code
20	Internal {
21		text: &'a str,
22	},
23}
24
25impl<'a> BorrowedFragment<'a> {
26	/// Create a new borrowed fragment with default position
27	pub fn new(text: &'a str) -> Self {
28		Self::Statement {
29			text,
30			line: StatementLine(1),
31			column: StatementColumn(0),
32		}
33	}
34
35	/// Create a new Internal fragment
36	pub fn new_internal(text: &'a str) -> Self {
37		BorrowedFragment::Internal {
38			text,
39		}
40	}
41
42	/// Compatibility: expose fragment field
43	pub fn fragment(&self) -> &str {
44		self.text()
45	}
46}
47
48impl<'a> BorrowedFragment<'a> {
49	/// Get the text value of the fragment
50	pub fn text(&self) -> &str {
51		match self {
52			BorrowedFragment::None => "",
53			BorrowedFragment::Statement {
54				text,
55				..
56			}
57			| BorrowedFragment::Internal {
58				text,
59				..
60			} => text,
61		}
62	}
63
64	/// Get line position
65	pub fn line(&self) -> StatementLine {
66		match self {
67			BorrowedFragment::Statement {
68				line,
69				..
70			} => *line,
71			_ => StatementLine(1),
72		}
73	}
74
75	/// Get column position
76	pub fn column(&self) -> StatementColumn {
77		match self {
78			BorrowedFragment::Statement {
79				column,
80				..
81			} => *column,
82			_ => StatementColumn(0),
83		}
84	}
85
86	/// Convert to owned variant
87	pub fn into_owned(self) -> OwnedFragment {
88		match self {
89			BorrowedFragment::None => OwnedFragment::None,
90			BorrowedFragment::Statement {
91				text,
92				line,
93				column,
94			} => OwnedFragment::Statement {
95				text: text.to_string(),
96				line,
97				column,
98			},
99			BorrowedFragment::Internal {
100				text,
101			} => OwnedFragment::Internal {
102				text: text.to_string(),
103			},
104		}
105	}
106
107	/// Get a sub-fragment starting at the given offset with the given
108	/// length
109	pub fn sub_fragment(&self, offset: usize, length: usize) -> OwnedFragment {
110		let text = self.text();
111		let end = std::cmp::min(offset + length, text.len());
112		let sub_text = if offset < text.len() {
113			&text[offset..end]
114		} else {
115			""
116		};
117
118		match self {
119			BorrowedFragment::None => OwnedFragment::None,
120			BorrowedFragment::Statement {
121				line,
122				column,
123				..
124			} => OwnedFragment::Statement {
125				text: sub_text.to_string(),
126				line: *line,
127				column: StatementColumn(column.0 + offset as u32),
128			},
129			BorrowedFragment::Internal {
130				..
131			} => OwnedFragment::Internal {
132				text: sub_text.to_string(),
133			},
134		}
135	}
136}
137
138// Implement methods for &BorrowedFragment as well
139impl<'a> BorrowedFragment<'a> {
140	/// Clone and convert to owned
141	pub fn to_owned(&self) -> OwnedFragment {
142		(*self).into_owned()
143	}
144}