From 1f7a25543c64b45847c5a15c70982b4010a4f93a Mon Sep 17 00:00:00 2001
From: Vincent Lafeychine <vincent.lafeychine@proton.me>
Date: Sun, 30 Oct 2022 17:43:15 +0100
Subject: [PATCH] chore(location): Move location out of error file + Improve
 struct

---
 kernel/src/error.rs    | 30 ++++--------------------------
 kernel/src/lib.rs      |  4 +++-
 kernel/src/location.rs | 15 +++++++++++++++
 parser/src/parser.rs   | 14 +++++++-------
 proost/src/process.rs  |  8 ++++----
 5 files changed, 33 insertions(+), 38 deletions(-)
 create mode 100644 kernel/src/location.rs

diff --git a/kernel/src/error.rs b/kernel/src/error.rs
index 50c2def1..e98be68d 100644
--- a/kernel/src/error.rs
+++ b/kernel/src/error.rs
@@ -1,37 +1,15 @@
-use crate::term::Term;
+use crate::{term::Term, Location};
 use derive_more::Display;
 
-// TODO #19
-#[derive(Clone, Debug, Display, PartialEq, Eq)]
-#[display(fmt = "{}:{}-{}:{}", line1, column1, line2, column2)]
-// Line/column position
-pub struct Loc {
-    pub line1: usize,
-    pub column1: usize,
-    pub line2: usize,
-    pub column2: usize,
-}
-
-impl Loc {
-    pub fn new(x1: usize, y1: usize, x2: usize, y2: usize) -> Loc {
-        Loc {
-            line1: x1,
-            column1: y1,
-            line2: x2,
-            column2: y2,
-        }
-    }
-}
-
 // TODO #19
 /// Type representing kernel errors, is used by the toplevel to pretty-print errors.
 #[derive(Clone, Debug, Display, PartialEq, Eq)]
 pub enum KernelError {
-    // cannot parse command
+    /// cannot parse command
     #[display(fmt = "cannot parse: {}", _1)]
-    CannotParse(Loc, String),
+    CannotParse(Location, String),
 
-    // s is already defined
+    /// s is already defined
     #[display(fmt = "{} is already defined", _0)]
     AlreadyDefined(String),
 
diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs
index 331f2a82..9d323af5 100644
--- a/kernel/src/lib.rs
+++ b/kernel/src/lib.rs
@@ -6,6 +6,7 @@
 mod command;
 mod environment;
 mod error;
+mod location;
 mod term;
 mod type_checker;
 
@@ -14,5 +15,6 @@ pub use num_bigint;
 
 pub use command::Command;
 pub use environment::Environment;
-pub use error::{KernelError, Loc};
+pub use error::KernelError;
+pub use location::{Location, Position};
 pub use term::Term;
diff --git a/kernel/src/location.rs b/kernel/src/location.rs
new file mode 100644
index 00000000..43f6d3df
--- /dev/null
+++ b/kernel/src/location.rs
@@ -0,0 +1,15 @@
+use derive_more::{Constructor, Display, From};
+
+#[derive(Clone, Constructor, Debug, Default, Display, Eq, PartialEq, From)]
+#[display(fmt = "{}:{}", line, column)]
+pub struct Position {
+    pub line: usize,
+    pub column: usize,
+}
+
+#[derive(Clone, Constructor, Debug, Default, Display, Eq, PartialEq, From)]
+#[display(fmt = "{}-{}", start, end)]
+pub struct Location {
+    pub start: Position,
+    pub end: Position,
+}
diff --git a/parser/src/parser.rs b/parser/src/parser.rs
index 06cf0d30..bb50b840 100644
--- a/parser/src/parser.rs
+++ b/parser/src/parser.rs
@@ -1,5 +1,5 @@
 use kernel::num_bigint::BigUint;
-use kernel::{Command, KernelError, Loc, Term};
+use kernel::{Command, KernelError, Location, Term};
 use pest::error::{Error, LineColLocation};
 use pest::iterators::Pair;
 use pest::{Parser, Span};
@@ -10,10 +10,11 @@ use std::collections::VecDeque;
 struct CommandParser;
 
 /// convert pest locations to kernel locations
-fn convert_span(span: Span) -> Loc {
+fn convert_span(span: Span) -> Location {
     let (x1, y1) = span.start_pos().line_col();
     let (x2, y2) = span.end_pos().line_col();
-    Loc::new(x1, y1, x2, y2)
+
+    ((x1, y1), (x2, y2)).into()
 }
 
 /// build terms from errorless pest's output
@@ -169,11 +170,10 @@ fn convert_error(err: Error<Rule>) -> KernelError {
                 left = y;
                 right = y;
             }
-            Loc::new(x, left, x, right)
+            Location::new((x, left).into(), (x, right).into())
         }
-        // unreachable in the current pest version but may change in the future
-        // if this is the case, this line should be used in place of an unreachable macro:
-        LineColLocation::Span((x1, y1), (x2, y2)) => Loc::new(x1, y1, x2, y2),
+
+        LineColLocation::Span(start, end) => Location::new(start.into(), end.into()),
     };
 
     // extracting the message from the pest output
diff --git a/proost/src/process.rs b/proost/src/process.rs
index 8c9c8fd0..9c28131c 100644
--- a/proost/src/process.rs
+++ b/proost/src/process.rs
@@ -17,15 +17,15 @@ pub fn print_repl(res: Result<Option<Term>, KernelError>) {
         Err(err) => {
             let string = match err {
                 KernelError::CannotParse(loc, message) => {
-                    if loc.column1 == loc.column2 {
-                        format!("{:0w1$}^\n{m}", "", w1 = loc.column1 - 1, m = message)
+                    if loc.start.column == loc.end.column {
+                        format!("{:0w1$}^\n{m}", "", w1 = loc.start.column - 1, m = message)
                     } else {
                         format!(
                             "{:0w1$}^{:-<w2$}^\n{m}",
                             "",
                             "",
-                            w1 = loc.column1 - 1,
-                            w2 = loc.column2 - loc.column1 - 1,
+                            w1 = loc.start.column - 1,
+                            w2 = loc.end.column - loc.start.column - 1,
                             m = message
                         )
                     }
-- 
GitLab