1use core::convert::{AsRef, AsMut};
27use core::ops::ControlFlow;
28use core::fmt::{Formatter, Display, Debug};
29use core::error::Error;
30use core::write;
31
32#[derive(Clone, Copy, PartialEq, Eq, Debug, Ord, PartialOrd)]
41pub struct Position {
42 r : u32,
43 c : u32,
44}
45
46impl Position{
47 #[must_use]
49 pub const fn line(&self) -> u32 {
50 self.r
51 }
52 #[must_use]
54 pub const fn column(&self) -> u32 {
55 self.c
56 }
57 #[must_use]
61 pub const fn unpack(self) -> (u32, u32) {
62 (self.r, self.c)
63 }
64 #[must_use]
66 pub const fn new(line : u32, column : u32) -> Self {
67 Self{
68 r : line,
69 c : column
70 }
71 }
72 #[must_use]
74 pub const fn new_zero() -> Self {
75 Self::new(0, 0)
76 }
77}
78
79impl Display for Position {
80 fn fmt(&self, fmt : &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81 write!(fmt, "Line: {}, column: {}", self.r, self.c)
82 }
83}
84impl Default for Position {
85 fn default() -> Self {
87 Self::new_zero()
88 }
89}
90
91pub trait Posable{
95 fn get_pos(&self) -> Position;
97
98 fn line(&self) -> u32 {
100 self.get_pos().r
101 }
102 fn column(&self) -> u32 {
104 self.get_pos().c
105 }
106}
107
108pub trait PosableMut : Posable {
110 fn get_pos_mut(&mut self) -> &mut Position;
114
115 fn progress(&mut self, nrow : i32, ncol : i32) {
117 let pos = self.get_pos_mut();
118 pos.r = pos.r.saturating_add_signed(nrow);
119 pos.c = pos.c.saturating_add_signed(ncol);
120 }
121 fn seek_start(&mut self) {
123 *self.get_pos_mut() = Position::new_zero();
124 }
125}
126
127impl<T, E> Posable for Result<T, E> where T : Posable, E : Posable {
128 fn get_pos(&self) -> Position {
129 match self {
130 Ok(e) => e.get_pos(),
131 Err(e) => e.get_pos()
132 }
133 }
134}
135impl<T, E> PosableMut for Result<T, E> where T : PosableMut, E : PosableMut {
136 fn get_pos_mut(&mut self) -> &mut Position {
137 match self {
138 Ok(e) => e.get_pos_mut(),
139 Err(e) => e.get_pos_mut()
140 }
141 }
142}
143
144#[derive(Clone, Copy, Debug)]
149pub struct Pos<T> {
150 el : T,
151 pos : Position,
152}
153
154impl<T> AsRef<T> for Pos<T> {
155 fn as_ref(&self) -> &T {
156 &self.el
157 }
158}
159impl<T> AsMut<T> for Pos<T> {
160 fn as_mut(&mut self) -> &mut T {
161 &mut self.el
162 }
163}
164
165impl<T> Display for Pos<T> where T : Display {
166 fn fmt(&self, fmt : &mut Formatter<'_>) -> core::fmt::Result {
167 write!(fmt, "{}: {}", self.pos, self.el)
168 }
169}
170
171impl<T> Error for Pos<T> where T : Error {
172 fn source(&self) -> Option<&(dyn Error + 'static)> {
173 self.el.source()
174 }
175}
176
177impl<T> Posable for Pos<T>{
178 fn get_pos(&self) -> Position {
179 self.pos
180 }
181}
182
183impl<T> PosableMut for Pos<T>{
184 fn get_pos_mut(&mut self) -> &mut Position {
185 &mut self.pos
186 }
187}
188
189impl<T> Pos<T> {
190 pub const fn new(el : T, pos : Position) -> Self {
192 Self{el, pos}
193 }
194 pub const fn new_pos(el : T, line : u32, column : u32) -> Self {
196 Self{
197 el,
198 pos : Position{
199 r : line,
200 c : column,
201 }
202 }
203 }
204 pub fn take(self) -> T {
206 self.el
207 }
208 pub fn take_pos(self) -> Position {
210 self.pos
211 }
212 pub fn take_all(self) -> (T, Position) {
214 (self.el, self.pos)
215 }
216
217 pub fn test<TF : FnOnce(&T) -> bool>(&self, f : TF) -> bool {
219 f(&self.el)
220 }
221 pub fn test_pos<TF : FnOnce(&T, &Position) -> bool>(&self, f : TF) -> bool {
223 f(&self.el, &self.pos)
224 }
225 pub fn map<U, MF : FnOnce(T) -> U>(self, f : MF) -> Pos<U> {
227 Pos{
228 el : f(self.el),
229 pos : self.pos,
230 }
231 }
232 pub fn map_pos<U, MF : FnOnce(T, Position) -> (U, Position)>(self, f : MF) -> Pos<U> {
234 let (nel, npos) = f(self.el, self.pos);
235 Pos{
236 el : nel,
237 pos : npos,
238 }
239 }
240
241 pub const fn make_ref(&self) -> Pos<&T> {
243 Pos{
244 el : &(self.el),
245 pos : self.pos,
246 }
247 }
248 pub const fn make_mut(&mut self) -> Pos<&mut T> {
250 Pos{
251 el : &mut(self.el),
252 pos : self.pos,
253 }
254 }
255}
256
257impl<T, E> Pos<Result<T, E>> {
258 pub fn branch(self) -> ControlFlow<Pos<Result<core::convert::Infallible, E>>, Pos<T>>{
262 let pos = self.pos;
263 match self.el {
264 Ok(t) => ControlFlow::Continue(Pos{
265 el : t,
266 pos,
267 }),
268 Err(e) => ControlFlow::Break(Pos{
269 el : Err(e),
270 pos,
271 }),
272 }
273 }
274
275 #[allow(clippy::missing_errors_doc)]
278 pub fn throw(self) -> Result<Pos<T>, Pos<E>> {
279 let pos = self.pos;
280 match self.el {
281 Ok(t) => Ok(Pos{
282 el : t,
283 pos,
284 }),
285 Err(e) => Err(Pos{
286 el : e,
287 pos,
288 }),
289 }
290 }
291 #[allow(clippy::missing_errors_doc)]
294 pub fn throw_el(self) -> Result<Pos<T>, E> {
295 match self.el {
296 Ok(el) => Ok(Pos{el, pos : self.pos}),
297 Err(e) => Err(e),
298 }
299 }
300 #[allow(clippy::missing_errors_doc)]
303 pub fn throw_err(self) -> Result<T, Pos<E>> {
304 match self.el {
305 Ok(t) => Ok(t),
306 Err(el) => Err(Pos{el, pos : self.pos}),
307 }
308 }
309}
310
311#[cfg(feature = "nightly-features")]
312impl<T> core::ops::Try for Pos<T> where T : core::ops::Try {
313 type Output = Pos<T::Output>;
314 type Residual = Pos<T::Residual>;
315
316 fn from_output(output : Self::Output) -> Self {
317 Self{
318 el : T::from_output(output.el),
319 pos : output.pos
320 }
321 }
322 fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
323 match self.el.branch() {
324 ControlFlow::Break(e) => ControlFlow::Break(Pos::new(e, self.pos)),
325 ControlFlow::Continue(e) => ControlFlow::Continue(Pos::new(e, self.pos))
326 }
327 }
328}
329#[cfg(feature = "nightly-features")]
330impl<T, R> core::ops::FromResidual<Pos<R>> for Pos<T> where T : core::ops::FromResidual<R> {
331 fn from_residual(output : Pos<R>) -> Self {
332 Self{
333 el : T::from_residual(output.el),
334 pos : output.pos
335 }
336 }
337}
338#[cfg(feature = "nightly-features")]
339impl<T, R> core::ops::Residual<Pos<R>> for Pos<T> where T : core::ops::Residual<R> {
340 type TryType = Pos<T::TryType>;
341}