reading_liner/
location.rs1use std::ops;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
5pub struct Offset(pub usize);
6
7impl Offset {
8 pub fn new(raw: usize) -> Self {
9 Self(raw)
10 }
11
12 pub fn raw(&self) -> usize {
13 self.0
14 }
15
16 fn plus(self, that: Self) -> Self {
17 Self(self.raw() + that.raw())
18 }
19
20 fn minus(self, that: Self) -> Self {
21 Self(self.raw() - that.raw())
22 }
23}
24
25impl From<usize> for Offset {
26 fn from(value: usize) -> Self {
27 Offset(value)
28 }
29}
30
31impl From<Offset> for usize {
32 fn from(value: Offset) -> Self {
33 value.raw()
34 }
35}
36
37impl Default for Offset {
38 fn default() -> Self {
39 Self(0)
40 }
41}
42
43impl ops::Add for Offset {
44 type Output = Offset;
45
46 fn add(self, rhs: Offset) -> Self::Output {
47 self.plus(rhs)
48 }
49}
50
51impl ops::Add<usize> for Offset {
52 type Output = Offset;
53
54 fn add(self, rhs: usize) -> Self::Output {
55 self.plus(Offset(rhs))
56 }
57}
58
59impl ops::AddAssign for Offset {
60 fn add_assign(&mut self, rhs: Self) {
61 self.0 += rhs.raw();
62 }
63}
64
65impl ops::AddAssign<usize> for Offset {
66 fn add_assign(&mut self, rhs: usize) {
67 self.0 += rhs;
68 }
69}
70
71impl ops::Sub for Offset {
72 type Output = Offset;
73
74 fn sub(self, rhs: Self) -> Self::Output {
75 self.minus(rhs)
76 }
77}
78
79impl ops::Sub<usize> for Offset {
80 type Output = Offset;
81
82 fn sub(self, rhs: usize) -> Self::Output {
83 self.minus(rhs.into())
84 }
85}
86
87pub trait OffsetRangeExt {
89 fn to_usize(self) -> ops::Range<usize>;
90}
91
92impl OffsetRangeExt for ops::Range<Offset> {
93 fn to_usize(self) -> ops::Range<usize> {
94 self.start.raw()..self.end.raw()
95 }
96}
97
98pub mod line_column {
99 use std::num::NonZeroUsize;
100
101 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
103 pub struct ZeroBased {
104 pub line: usize,
105 pub column: usize,
106 }
107
108 impl ZeroBased {
109 pub fn new(line: usize, column: usize) -> Self {
110 Self { line, column }
111 }
112
113 pub fn raw(&self) -> (usize, usize) {
114 (self.line, self.column)
115 }
116
117 pub fn one_based(&self) -> OneBased {
119 unsafe {
120 OneBased {
121 line: NonZeroUsize::new_unchecked(self.line + 1),
122 column: NonZeroUsize::new_unchecked(self.column + 1),
123 }
124 }
125 }
126 }
127
128 impl From<(usize, usize)> for ZeroBased {
129 fn from((line, column): (usize, usize)) -> Self {
130 ZeroBased { line, column }
131 }
132 }
133
134 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
136 pub struct OneBased {
137 pub line: NonZeroUsize,
138 pub column: NonZeroUsize,
139 }
140
141 impl OneBased {
142 pub fn new(line: usize, column: usize) -> Option<Self> {
143 let line = NonZeroUsize::new(line)?;
144 let column = NonZeroUsize::new(column)?;
145 Some(Self { line, column })
146 }
147
148 pub fn raw(&self) -> (usize, usize) {
149 (self.line.get(), self.column.get())
150 }
151
152 pub fn zero_based(&self) -> ZeroBased {
154 ZeroBased {
155 line: self.line.get() - 1,
156 column: self.column.get() - 1,
157 }
158 }
159 }
160
161 impl From<(NonZeroUsize, NonZeroUsize)> for OneBased {
162 fn from((line, column): (NonZeroUsize, NonZeroUsize)) -> Self {
163 OneBased { line, column }
164 }
165 }
166}