1#[cfg(test)]
2mod tests;
3
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7use core::clone::Clone;
8use core::cmp::{Eq, Ord, PartialEq, PartialOrd};
9use core::convert::{From, Into};
10use core::default::Default;
11use core::fmt;
12use core::fmt::{Debug, Display};
13use core::hash::Hash;
14use core::marker::Copy;
15use core::ops::{Range, RangeFrom, RangeTo};
16
17#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19#[derive(PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
20pub struct Pos {
21 pub line: usize,
23 pub column: usize,
25}
26impl Pos {
27 #[inline]
29 pub const fn zero() -> Self {
30 Self::new_same(0)
31 }
32 #[inline]
34 pub const fn new(line: usize, column: usize) -> Self {
35 Self { line, column }
36 }
37 #[inline]
39 pub const fn new_same(value: usize) -> Self {
40 Self::new(value, value)
41 }
42}
43
44impl Display for Pos {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 write!(f, "at {}:{}", self.line, self.column)
47 }
48}
49
50impl Debug for Pos {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 write!(f, "{{ at {}:{} }}", self.line, self.column)
53 }
54}
55
56impl Default for Pos {
57 #[inline(always)]
58 fn default() -> Self {
59 Self::zero()
60 }
61}
62
63impl From<(usize, usize)> for Pos {
64 #[inline]
65 fn from((line, column): (usize, usize)) -> Self {
66 Self::new(line, column)
67 }
68}
69impl From<[usize; 2]> for Pos {
70 #[inline]
71 fn from([line, column]: [usize; 2]) -> Self {
72 Self::new(line, column)
73 }
74}
75impl Into<(usize, usize)> for Pos {
76 #[inline]
77 fn into(self) -> (usize, usize) {
78 (self.line, self.column)
79 }
80}
81impl Into<[usize; 2]> for Pos {
82 #[inline]
83 fn into(self) -> [usize; 2] {
84 [self.line, self.column]
85 }
86}
87impl From<usize> for Pos {
88 #[inline]
89 fn from(value: usize) -> Self {
90 Self::new_same(value)
91 }
92}
93impl Into<usize> for Pos {
94 #[inline]
95 fn into(self) -> usize {
96 self.line
97 }
98}
99impl From<[usize; 1]> for Pos {
100 #[inline]
101 fn from([value]: [usize; 1]) -> Self {
102 Self::new_same(value)
103 }
104}
105impl Into<[usize; 1]> for Pos {
106 #[inline]
107 fn into(self) -> [usize; 1] {
108 [self.line]
109 }
110}
111impl From<()> for Pos {
112 #[inline]
113 fn from(_: ()) -> Self {
114 Self::zero()
115 }
116}
117impl<T> From<[T; 0]> for Pos {
118 #[inline]
119 fn from(_: [T; 0]) -> Self {
120 Self::zero()
121 }
122}
123
124pub const fn pos(line: usize, column: usize) -> Pos {
126 Pos::new(line, column)
127}
128
129#[macro_export]
140macro_rules! posof {
141 ($a:expr, $b:expr) => {
142 $crate::pos($a, $b)
143 };
144 ($a:expr) => {
145 $crate::Pos::from($a)
146 };
147}
148
149#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
153#[derive(PartialEq, Eq, Clone, Copy, Hash, PartialOrd, Ord)]
154pub struct Loc {
155 pub from: Pos,
157 pub to: Pos,
159}
160impl Loc {
161 #[inline]
163 pub const fn new(from: Pos, to: Pos) -> Self {
164 Self { from, to }
165 }
166 #[inline]
168 pub const fn new_at(
169 from_line: usize,
170 from_column: usize,
171 to_line: usize,
172 to_column: usize,
173 ) -> Self {
174 Self::new(
175 Pos::new(from_line, from_column),
176 Pos::new(to_line, to_column),
177 )
178 }
179 #[inline]
181 pub const fn zero() -> Self {
182 Self::new_same_pos(Pos::zero())
183 }
184 #[inline]
186 pub const fn new_same(value: usize) -> Self {
187 Self::new_same_pos(Pos::new_same(value))
188 }
189 #[inline]
191 pub const fn new_same_pos(pos: Pos) -> Self {
192 Self::new(pos, pos)
193 }
194}
195
196impl Display for Loc {
197 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
198 write!(
199 f,
200 "at {}:{} to {}:{}",
201 self.from.line, self.from.column, self.to.line, self.to.column,
202 )
203 }
204}
205
206impl Debug for Loc {
207 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208 write!(
209 f,
210 "{{ at {}:{} to {}:{} }}",
211 self.from.line, self.from.column, self.to.line, self.to.column,
212 )
213 }
214}
215
216impl Default for Loc {
217 #[inline(always)]
218 fn default() -> Self {
219 Self::zero()
220 }
221}
222
223impl From<(usize, usize, usize, usize)> for Loc {
225 #[inline]
226 fn from((a1, b1, a2, b2): (usize, usize, usize, usize)) -> Self {
227 Self::new_at(a1, b1, a2, b2)
228 }
229}
230impl Into<(usize, usize, usize, usize)> for Loc {
231 #[inline]
232 fn into(self) -> (usize, usize, usize, usize) {
233 (
234 self.from.line,
235 self.from.column,
236 self.to.line,
237 self.to.column,
238 )
239 }
240}
241impl From<[usize; 4]> for Loc {
242 #[inline]
243 fn from([a1, b1, a2, b2]: [usize; 4]) -> Self {
244 Self::new_at(a1, b1, a2, b2)
245 }
246}
247impl Into<[usize; 4]> for Loc {
248 fn into(self) -> [usize; 4] {
249 [
250 self.from.line,
251 self.from.column,
252 self.to.line,
253 self.to.column,
254 ]
255 }
256}
257impl Into<[[usize; 2]; 2]> for Loc {
258 #[inline]
259 fn into(self) -> [[usize; 2]; 2] {
260 [
261 [self.from.line, self.from.column],
262 [self.to.line, self.to.column],
263 ]
264 }
265}
266impl Into<[(usize, usize); 2]> for Loc {
267 #[inline]
268 fn into(self) -> [(usize, usize); 2] {
269 [
270 (self.from.line, self.from.column),
271 (self.to.line, self.to.column),
272 ]
273 }
274}
275impl Into<[usize; 2]> for Loc {
276 #[inline]
277 fn into(self) -> [usize; 2] {
278 [self.from.line, self.from.column]
279 }
280}
281impl From<usize> for Loc {
282 #[inline]
283 fn from(value: usize) -> Self {
284 Self::new_same(value)
285 }
286}
287impl Into<usize> for Loc {
288 #[inline]
289 fn into(self) -> usize {
290 self.from.line
291 }
292}
293impl Into<[usize; 1]> for Loc {
294 #[inline]
295 fn into(self) -> [usize; 1] {
296 [self.from.line]
297 }
298}
299impl From<()> for Loc {
300 #[inline]
301 fn from(_: ()) -> Self {
302 Self::zero()
303 }
304}
305impl<T> From<[T; 0]> for Loc {
306 #[inline]
307 fn from(_: [T; 0]) -> Self {
308 Self::zero()
309 }
310}
311impl<T: Into<Pos>> From<Range<T>> for Loc {
315 #[inline]
316 fn from(r: Range<T>) -> Self {
317 Self::new(r.start.into(), r.end.into())
318 }
319}
320impl<T: From<Pos>> Into<Range<T>> for Loc {
321 #[inline]
322 fn into(self) -> Range<T> {
323 self.from.into()..self.to.into()
324 }
325}
326impl<T: Into<Pos>> From<RangeTo<T>> for Loc {
327 #[inline]
328 fn from(r: RangeTo<T>) -> Self {
329 Self::new(Pos::zero(), r.end.into())
330 }
331}
332impl<T: From<Pos>> Into<RangeTo<T>> for Loc {
333 #[inline]
334 fn into(self) -> RangeTo<T> {
335 ..self.to.into()
336 }
337}
338impl<T: From<Pos>> Into<RangeFrom<T>> for Loc {
339 #[inline]
340 fn into(self) -> RangeFrom<T> {
341 self.from.into()..
342 }
343}
344impl<T: Into<Pos>> From<(T, T)> for Loc {
348 #[inline]
349 fn from((from, to): (T, T)) -> Self {
350 Self::new(from.into(), to.into())
351 }
352}
353impl<T: From<Pos>> Into<(T, T)> for Loc {
354 #[inline]
355 fn into(self) -> (T, T) {
356 (self.from.into(), self.to.into())
357 }
358}
359impl<T: Into<Pos>> From<[T; 2]> for Loc {
360 #[inline]
361 fn from([from, to]: [T; 2]) -> Self {
362 Self::new(from.into(), to.into())
363 }
364}
365impl<T: From<Pos>> Into<[T; 2]> for Loc {
366 #[inline]
367 fn into(self) -> [T; 2] {
368 [self.from.into(), self.to.into()]
369 }
370}
371impl From<Pos> for Loc {
372 #[inline]
373 fn from(pos: Pos) -> Self {
374 Self::new_same_pos(pos)
375 }
376}
377impl Into<Pos> for Loc {
378 #[inline]
379 fn into(self) -> Pos {
380 self.from
381 }
382}
383impl<T: Into<Pos>> From<[T; 1]> for Loc {
384 #[inline]
385 fn from([pos]: [T; 1]) -> Self {
386 Self::new_same_pos(pos.into())
387 }
388}
389impl<T: From<Pos>> Into<[T; 1]> for Loc {
390 #[inline]
391 fn into(self) -> [T; 1] {
392 [self.from.into()]
393 }
394}
395#[inline]
399pub const fn loc(from: Pos, to: Pos) -> Loc {
400 Loc::new(from, to)
401}
402
403#[macro_export]
418macro_rules! locof {
419 ($from:expr, $to:expr) => {
420 $crate::loc($from.into(), $to.into())
421 };
422 ($a:expr, $b:expr, $c:expr, $d:expr) => {
423 $crate::loc(pos($a, $b), pos($c, $d))
424 };
425 ($v:expr) => {
426 $crate::Loc::from($v)
427 };
428}
429
430#[macro_export]
443macro_rules! pos {
444 () => {
445 $crate::pos(line!() as usize, column!() as usize)
446 };
447}