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