1use crate::core::span::Span;
2use serde::{Deserialize, Serialize};
3use std::fmt::{Display, Formatter};
4use std::ops::Sub;
5
6#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Debug, Serialize, Deserialize)]
7pub struct Pos(usize);
8
9impl Pos {
10 pub fn start() -> Self {
11 Self(0)
12 }
13
14 pub fn end(input: &str) -> Self {
15 Self(input.len())
16 }
17
18 pub fn span_to(self, other: Self) -> Span {
19 Span::new(self, other)
20 }
21
22 pub fn next(self, input: &str) -> (Self, Option<(Span, char)>) {
23 match input[self.0..].chars().next() {
24 None => (self, None),
25 Some(c) => (
26 Self(self.0 + c.len_utf8()),
27 Some((Span::new(self, Self(self.0 + c.len_utf8())), c)),
28 ),
29 }
30 }
31
32 pub const fn invalid() -> Self {
33 Self(usize::MAX)
34 }
35}
36
37impl Display for Pos {
38 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
39 write!(f, "{}", self.0)
40 }
41}
42
43impl Sub<Pos> for Pos {
44 type Output = usize;
45
46 fn sub(self, rhs: Pos) -> Self::Output {
47 self.0 - rhs.0
48 }
49}
50
51impl From<Pos> for usize {
52 fn from(val: Pos) -> Self {
53 val.0
54 }
55}