about summary refs log tree commit diff
path: root/src/error.rs
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2022-03-03 01:57:25 +0100
committerMel <einebeere@gmail.com>2022-03-03 01:57:25 +0100
commit8f7e3d1d2cd43d30ccc16799fcf69058ccc5a717 (patch)
treea2ef0772d8f982c832df1762219557adb67d69d6 /src/error.rs
parent8abea71c7662016c98583a8d075a693eb4efa5e0 (diff)
downloadrabbithole-8f7e3d1d2cd43d30ccc16799fcf69058ccc5a717.tar.zst
rabbithole-8f7e3d1d2cd43d30ccc16799fcf69058ccc5a717.zip
Re-arrange error locations
Diffstat (limited to 'src/error.rs')
-rw-r--r--src/error.rs110
1 files changed, 67 insertions, 43 deletions
diff --git a/src/error.rs b/src/error.rs
index 227a4b0..ed92355 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,10 +1,14 @@
-use crate::{interpret::walker::WalkerError, lex::token::Location, parse::parser::ParserError};
+use crate::{
+    interpret::walker::WalkerError,
+    lex::token::Location,
+    parse::parser::{ParserError, ParserErrorLocation},
+};
 use colored::Colorize;
 use std::fmt::Display;
 
-pub struct RHError {
-    pub at: ErrorLocation,
-    pub kind: RHErrorKind,
+pub enum RHError {
+    Parse(ParserError),
+    Run(WalkerError),
 }
 
 impl RHError {
@@ -16,16 +20,6 @@ impl RHError {
     }
 }
 
-pub enum RHErrorKind {
-    Parse(ParserError),
-    Run(WalkerError),
-}
-
-pub enum ErrorLocation {
-    Specific(Location),
-    Eof,
-}
-
 pub struct RHErrorWithSource<'source> {
     error: RHError,
     source: &'source str,
@@ -33,45 +27,27 @@ pub struct RHErrorWithSource<'source> {
 
 impl Display for RHErrorWithSource<'_> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        let (error_title, error_string) = match &self.error.kind {
-            RHErrorKind::Parse(parser_error) => (
+        let (error_title, error_string) = match &self.error {
+            RHError::Parse(parser_error) => (
                 "Encountered error during parsing",
-                format!("{}", parser_error),
+                format!("{}", parser_error.kind),
             ),
-            RHErrorKind::Run(walker_error) => {
-                ("Encountered runtime error", format!("{}", walker_error))
-            }
-        };
-
-        let weird_source_error_msg =
-            "Found error but could not get it's location in source, how does this even happen?";
-
-        let (line_number, line_column, source_line) = match self.error.at {
-            ErrorLocation::Specific(location) => (
-                location.row,
-                location.col,
-                self.source
-                    .lines()
-                    .nth(location.row)
-                    .expect(weird_source_error_msg),
+            RHError::Run(walker_error) => (
+                "Encountered runtime error",
+                format!("{}", walker_error.kind),
             ),
-            ErrorLocation::Eof => {
-                let lines = self.source.lines();
-                let (line_count, _) = lines.size_hint();
-                let last_line = lines.last().expect(weird_source_error_msg);
-
-                (line_count, last_line.len(), last_line)
-            }
         };
 
-        let arrow_pad_len = line_column + 3 + line_number.to_string().len();
+        let at = MappedErrorLocation::new(self);
+
+        let arrow_pad_len = at.line_column + 3 + at.line_number.to_string().len();
 
         writeln!(f, "{} {}:\n", " Error ".on_red(), error_title)?;
         writeln!(
             f,
             "{}{}",
-            format!("{} | ", line_number).dimmed(),
-            source_line
+            format!("{} | ", at.line_number).dimmed(),
+            at.source_line
         )?;
         writeln!(f, "{}{}", " ".repeat(arrow_pad_len), "^".red())?;
         writeln!(f, "{}", error_string)?;
@@ -79,3 +55,51 @@ impl Display for RHErrorWithSource<'_> {
         Ok(())
     }
 }
+
+pub struct MappedErrorLocation<'s> {
+    line_number: usize,
+    line_column: usize,
+    source_line: &'s str,
+}
+
+impl<'s> MappedErrorLocation<'s> {
+    const SOURCE_MISSING_ERROR_LOCATION: &'static str =
+        "Found error but could not get it's location in source, how does this even happen?";
+
+    fn new(from: &'s RHErrorWithSource<'s>) -> MappedErrorLocation<'s> {
+        match &from.error {
+            RHError::Parse(error) => match &error.at {
+                ParserErrorLocation::Specific(at) => Self::at_location(from, at),
+                ParserErrorLocation::Eof => Self::last_line(from),
+            },
+            RHError::Run(error) => Self::at_location(from, &error.at),
+        }
+    }
+
+    fn last_line(from: &'s RHErrorWithSource<'s>) -> MappedErrorLocation<'s> {
+        let lines = from.source.lines();
+        let (line_count, _) = lines.size_hint();
+        let last_line = lines.last().expect(Self::SOURCE_MISSING_ERROR_LOCATION);
+
+        MappedErrorLocation {
+            line_number: line_count,
+            line_column: last_line.len(),
+            source_line: last_line,
+        }
+    }
+
+    fn at_location(
+        from: &'s RHErrorWithSource<'s>,
+        location: &'s Location,
+    ) -> MappedErrorLocation<'s> {
+        MappedErrorLocation {
+            line_number: location.row,
+            line_column: location.col,
+            source_line: from
+                .source
+                .lines()
+                .nth(location.row)
+                .expect(Self::SOURCE_MISSING_ERROR_LOCATION),
+        }
+    }
+}