2023-08-22 15:40:50 +00:00
|
|
|
//! Error and Result types.
|
|
|
|
//!
|
|
|
|
//! To deal with errors from dependencies, either create a new error variant
|
2023-10-13 17:53:00 +00:00
|
|
|
//! or use the ToolFailure variant if the error can only occur inside a tool.
|
2023-09-29 11:17:11 +00:00
|
|
|
|
2023-12-30 07:04:39 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2023-12-29 19:01:54 +00:00
|
|
|
use tree_sitter::{LanguageError, Node, Point};
|
2023-11-15 00:31:04 +00:00
|
|
|
|
2024-01-01 13:52:25 +00:00
|
|
|
use crate::{value::Value, Type};
|
2023-08-22 15:40:50 +00:00
|
|
|
|
2023-12-10 18:47:05 +00:00
|
|
|
use std::{
|
|
|
|
fmt::{self, Formatter},
|
|
|
|
io,
|
|
|
|
num::ParseFloatError,
|
|
|
|
string::FromUtf8Error,
|
|
|
|
sync::PoisonError,
|
|
|
|
time,
|
|
|
|
};
|
2023-08-22 15:40:50 +00:00
|
|
|
|
|
|
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
|
|
|
2023-12-30 07:04:39 +00:00
|
|
|
#[derive(Clone, PartialEq, Serialize, Deserialize)]
|
2023-08-22 15:40:50 +00:00
|
|
|
pub enum Error {
|
2023-12-09 22:55:47 +00:00
|
|
|
WithContext {
|
|
|
|
error: Box<Error>,
|
2023-12-30 07:04:39 +00:00
|
|
|
#[serde(skip)]
|
2023-12-09 22:55:47 +00:00
|
|
|
location: Point,
|
|
|
|
source: String,
|
|
|
|
},
|
|
|
|
|
2023-10-10 17:29:11 +00:00
|
|
|
UnexpectedSyntaxNode {
|
2023-12-30 07:04:39 +00:00
|
|
|
expected: String,
|
|
|
|
actual: String,
|
|
|
|
#[serde(skip)]
|
2023-11-27 22:53:12 +00:00
|
|
|
location: Point,
|
2023-10-06 11:55:14 +00:00
|
|
|
relevant_source: String,
|
2023-09-28 19:58:01 +00:00
|
|
|
},
|
|
|
|
|
2023-11-28 15:29:42 +00:00
|
|
|
TypeCheck {
|
2023-12-02 07:34:23 +00:00
|
|
|
expected: Type,
|
|
|
|
actual: Type,
|
2023-11-28 15:29:42 +00:00
|
|
|
},
|
|
|
|
|
2023-08-22 16:31:45 +00:00
|
|
|
/// The 'assert' macro did not resolve successfully.
|
|
|
|
AssertEqualFailed {
|
|
|
|
expected: Value,
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// The 'assert' macro did not resolve successfully.
|
|
|
|
AssertFailed,
|
|
|
|
|
2023-08-22 15:40:50 +00:00
|
|
|
/// A row was inserted to a table with the wrong amount of values.
|
|
|
|
WrongColumnAmount {
|
|
|
|
expected: usize,
|
|
|
|
actual: usize,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// An operator was called with the wrong amount of arguments.
|
|
|
|
ExpectedOperatorArgumentAmount {
|
|
|
|
expected: usize,
|
|
|
|
actual: usize,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// A function was called with the wrong amount of arguments.
|
2023-12-22 20:02:22 +00:00
|
|
|
ExpectedBuiltInFunctionArgumentAmount {
|
2023-12-30 07:04:39 +00:00
|
|
|
function_name: String,
|
2023-08-22 15:40:50 +00:00
|
|
|
expected: usize,
|
|
|
|
actual: usize,
|
|
|
|
},
|
|
|
|
|
2023-12-22 20:02:22 +00:00
|
|
|
/// A function was called with the wrong amount of arguments.
|
|
|
|
ExpectedFunctionArgumentAmount {
|
|
|
|
source: String,
|
|
|
|
expected: usize,
|
|
|
|
actual: usize,
|
|
|
|
},
|
|
|
|
|
2023-08-22 15:40:50 +00:00
|
|
|
/// A function was called with the wrong amount of arguments.
|
2023-12-27 00:33:19 +00:00
|
|
|
ExpectedFunctionArgumentMinimum {
|
|
|
|
source: String,
|
|
|
|
minumum_expected: usize,
|
2023-08-22 15:40:50 +00:00
|
|
|
actual: usize,
|
|
|
|
},
|
|
|
|
|
2024-01-04 00:57:06 +00:00
|
|
|
ExpectedFunctionType {
|
|
|
|
actual: Type,
|
|
|
|
},
|
|
|
|
|
2023-08-22 15:40:50 +00:00
|
|
|
ExpectedString {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
2023-11-27 15:27:44 +00:00
|
|
|
ExpectedInteger {
|
2023-08-22 15:40:50 +00:00
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
|
|
|
ExpectedFloat {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// An integer, floating point or value was expected.
|
|
|
|
ExpectedNumber {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// An integer, floating point or string value was expected.
|
|
|
|
ExpectedNumberOrString {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
|
|
|
ExpectedBoolean {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
|
|
|
ExpectedList {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
2023-10-25 18:46:58 +00:00
|
|
|
ExpectedMinLengthList {
|
|
|
|
minimum_len: usize,
|
|
|
|
actual_len: usize,
|
|
|
|
},
|
|
|
|
|
2023-08-22 15:40:50 +00:00
|
|
|
ExpectedFixedLenList {
|
|
|
|
expected_len: usize,
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
2023-12-22 20:02:22 +00:00
|
|
|
ExpectedNone {
|
2023-08-22 15:40:50 +00:00
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
|
|
|
ExpectedMap {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
|
|
|
ExpectedTable {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
|
|
|
ExpectedFunction {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
2023-12-27 00:33:19 +00:00
|
|
|
ExpectedOption {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
2023-08-22 15:40:50 +00:00
|
|
|
/// A string, list, map or table value was expected.
|
|
|
|
ExpectedCollection {
|
|
|
|
actual: Value,
|
|
|
|
},
|
|
|
|
|
|
|
|
/// A `VariableIdentifier` operation did not find its value in the context.
|
|
|
|
VariableIdentifierNotFound(String),
|
|
|
|
|
|
|
|
/// A `FunctionIdentifier` operation did not find its value in the context.
|
2023-12-10 18:47:05 +00:00
|
|
|
FunctionIdentifierNotFound(String),
|
2023-08-22 15:40:50 +00:00
|
|
|
|
|
|
|
/// The function failed due to an external error.
|
2023-12-10 18:47:05 +00:00
|
|
|
External(String),
|
2023-08-22 15:40:50 +00:00
|
|
|
|
|
|
|
/// A custom error explained by its message.
|
|
|
|
CustomMessage(String),
|
2023-11-27 22:53:12 +00:00
|
|
|
|
|
|
|
/// Invalid user input.
|
|
|
|
Syntax {
|
|
|
|
source: String,
|
2023-12-30 07:04:39 +00:00
|
|
|
#[serde(skip)]
|
2023-11-27 22:53:12 +00:00
|
|
|
location: Point,
|
|
|
|
},
|
2023-12-10 18:47:05 +00:00
|
|
|
|
|
|
|
SerdeJson(String),
|
2023-12-29 19:01:54 +00:00
|
|
|
|
|
|
|
ParserCancelled,
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
|
|
|
|
2023-10-14 17:52:16 +00:00
|
|
|
impl Error {
|
2023-12-15 22:27:29 +00:00
|
|
|
pub fn at_node(self, node: Node, source: &str) -> Self {
|
2023-12-09 22:55:47 +00:00
|
|
|
Error::WithContext {
|
|
|
|
error: Box::new(self),
|
2023-12-15 22:27:29 +00:00
|
|
|
location: node.start_position(),
|
|
|
|
source: source[node.byte_range()].to_string(),
|
2023-12-09 22:55:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-30 07:04:39 +00:00
|
|
|
pub fn expect_syntax_node(source: &str, expected: &str, actual: Node) -> Result<()> {
|
2023-11-15 00:31:04 +00:00
|
|
|
if expected == actual.kind() {
|
|
|
|
Ok(())
|
2023-11-27 22:53:12 +00:00
|
|
|
} else if actual.is_error() {
|
|
|
|
Err(Error::Syntax {
|
|
|
|
source: source[actual.byte_range()].to_string(),
|
|
|
|
location: actual.start_position(),
|
|
|
|
})
|
2023-11-15 00:31:04 +00:00
|
|
|
} else {
|
|
|
|
Err(Error::UnexpectedSyntaxNode {
|
2023-12-30 07:04:39 +00:00
|
|
|
expected: expected.to_string(),
|
|
|
|
actual: actual.kind().to_string(),
|
2023-11-15 00:31:04 +00:00
|
|
|
location: actual.start_position(),
|
|
|
|
relevant_source: source[actual.byte_range()].to_string(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-01 09:59:27 +00:00
|
|
|
pub fn expect_argument_amount(
|
2024-01-01 13:52:25 +00:00
|
|
|
function_name: &str,
|
2023-10-14 17:52:16 +00:00
|
|
|
expected: usize,
|
|
|
|
actual: usize,
|
|
|
|
) -> Result<()> {
|
|
|
|
if expected == actual {
|
|
|
|
Ok(())
|
|
|
|
} else {
|
2023-12-22 20:02:22 +00:00
|
|
|
Err(Error::ExpectedBuiltInFunctionArgumentAmount {
|
2024-01-01 13:52:25 +00:00
|
|
|
function_name: function_name.to_string(),
|
2023-10-14 17:52:16 +00:00
|
|
|
expected,
|
|
|
|
actual,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2023-11-30 16:05:09 +00:00
|
|
|
|
2023-12-17 00:47:23 +00:00
|
|
|
pub fn is_type_check_error(&self, other: &Error) -> bool {
|
2023-12-17 00:40:14 +00:00
|
|
|
match self {
|
2024-01-04 00:57:06 +00:00
|
|
|
Error::WithContext { error, .. } => error.as_ref() == other,
|
|
|
|
_ => self == other,
|
2023-12-17 00:40:14 +00:00
|
|
|
}
|
|
|
|
}
|
2023-10-14 17:52:16 +00:00
|
|
|
}
|
|
|
|
|
2023-12-29 19:01:54 +00:00
|
|
|
impl From<LanguageError> for Error {
|
|
|
|
fn from(value: LanguageError) -> Self {
|
|
|
|
Error::External(value.to_string())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-05 18:54:29 +00:00
|
|
|
impl<T> From<PoisonError<T>> for Error {
|
|
|
|
fn from(value: PoisonError<T>) -> Self {
|
2023-12-10 18:47:05 +00:00
|
|
|
Error::External(value.to_string())
|
2023-11-05 18:54:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-21 22:29:46 +00:00
|
|
|
impl From<FromUtf8Error> for Error {
|
|
|
|
fn from(value: FromUtf8Error) -> Self {
|
2023-12-10 18:47:05 +00:00
|
|
|
Error::External(value.to_string())
|
2023-10-21 22:29:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-28 14:28:43 +00:00
|
|
|
impl From<ParseFloatError> for Error {
|
|
|
|
fn from(value: ParseFloatError) -> Self {
|
2023-12-10 18:47:05 +00:00
|
|
|
Error::External(value.to_string())
|
2023-10-28 14:28:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-22 15:40:50 +00:00
|
|
|
impl From<csv::Error> for Error {
|
|
|
|
fn from(value: csv::Error) -> Self {
|
2023-12-10 18:47:05 +00:00
|
|
|
Error::External(value.to_string())
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<io::Error> for Error {
|
|
|
|
fn from(value: std::io::Error) -> Self {
|
2023-12-10 18:47:05 +00:00
|
|
|
Error::External(value.to_string())
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<reqwest::Error> for Error {
|
|
|
|
fn from(value: reqwest::Error) -> Self {
|
2023-12-10 18:47:05 +00:00
|
|
|
Error::External(value.to_string())
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<serde_json::Error> for Error {
|
|
|
|
fn from(value: serde_json::Error) -> Self {
|
2023-12-10 18:47:05 +00:00
|
|
|
Error::SerdeJson(value.to_string())
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-14 00:16:14 +00:00
|
|
|
impl From<time::SystemTimeError> for Error {
|
|
|
|
fn from(value: time::SystemTimeError) -> Self {
|
2023-12-10 18:47:05 +00:00
|
|
|
Error::External(value.to_string())
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-08 09:59:44 +00:00
|
|
|
impl From<toml::de::Error> for Error {
|
|
|
|
fn from(value: toml::de::Error) -> Self {
|
2023-12-10 18:47:05 +00:00
|
|
|
Error::External(value.to_string())
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for Error {}
|
|
|
|
|
2023-10-06 11:55:14 +00:00
|
|
|
impl fmt::Debug for Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
write!(f, "{self}")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-22 15:40:50 +00:00
|
|
|
impl fmt::Display for Error {
|
2023-12-10 18:47:05 +00:00
|
|
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
2023-08-22 15:40:50 +00:00
|
|
|
use Error::*;
|
|
|
|
|
|
|
|
match self {
|
2023-10-19 17:52:26 +00:00
|
|
|
AssertEqualFailed { expected, actual } => {
|
2023-12-10 18:47:05 +00:00
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"Equality assertion failed. {expected} does not equal {actual}."
|
|
|
|
)
|
2023-11-15 00:31:04 +00:00
|
|
|
}
|
2023-10-02 21:15:05 +00:00
|
|
|
AssertFailed => write!(
|
|
|
|
f,
|
|
|
|
"Assertion failed. A false value was passed to \"assert\"."
|
|
|
|
),
|
2023-08-22 15:40:50 +00:00
|
|
|
ExpectedOperatorArgumentAmount { expected, actual } => write!(
|
|
|
|
f,
|
|
|
|
"An operator expected {} arguments, but got {}.",
|
|
|
|
expected, actual
|
|
|
|
),
|
2023-12-22 20:02:22 +00:00
|
|
|
ExpectedBuiltInFunctionArgumentAmount {
|
2023-11-30 16:05:09 +00:00
|
|
|
function_name: tool_name,
|
2023-08-22 15:40:50 +00:00
|
|
|
expected,
|
|
|
|
actual,
|
|
|
|
} => write!(
|
|
|
|
f,
|
2023-10-11 16:07:30 +00:00
|
|
|
"{tool_name} expected {expected} arguments, but got {actual}.",
|
2023-08-22 15:40:50 +00:00
|
|
|
),
|
2023-12-22 20:02:22 +00:00
|
|
|
ExpectedFunctionArgumentAmount {
|
|
|
|
source,
|
|
|
|
expected,
|
|
|
|
actual,
|
|
|
|
} => write!(
|
|
|
|
f,
|
|
|
|
"{source} expected {expected} arguments, but got {actual}.",
|
|
|
|
),
|
2023-12-27 00:33:19 +00:00
|
|
|
ExpectedFunctionArgumentMinimum {
|
|
|
|
source,
|
|
|
|
minumum_expected,
|
2023-08-22 15:40:50 +00:00
|
|
|
actual,
|
2023-12-27 00:33:19 +00:00
|
|
|
} => {
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"{source} expected at least {minumum_expected} arguments, but got {actual}."
|
|
|
|
)
|
|
|
|
}
|
2023-08-22 15:40:50 +00:00
|
|
|
ExpectedString { actual } => {
|
2023-12-10 18:47:05 +00:00
|
|
|
write!(f, "Expected a string but got {actual}.")
|
2023-11-27 15:27:44 +00:00
|
|
|
}
|
2023-12-10 18:47:05 +00:00
|
|
|
ExpectedInteger { actual } => write!(f, "Expected an integer, but got {actual}."),
|
|
|
|
ExpectedFloat { actual } => write!(f, "Expected a float, but got {actual}."),
|
2023-11-27 15:27:44 +00:00
|
|
|
ExpectedNumber { actual } => {
|
2023-12-10 18:47:05 +00:00
|
|
|
write!(f, "Expected a float or integer but got {actual}.",)
|
2023-11-27 15:27:44 +00:00
|
|
|
}
|
|
|
|
ExpectedNumberOrString { actual } => {
|
2023-12-10 18:47:05 +00:00
|
|
|
write!(f, "Expected a number or string, but got {actual}.")
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
|
|
|
ExpectedBoolean { actual } => {
|
2023-12-10 18:47:05 +00:00
|
|
|
write!(f, "Expected a boolean, but got {actual}.")
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
2023-12-10 18:47:05 +00:00
|
|
|
ExpectedList { actual } => write!(f, "Expected a list, but got {actual}."),
|
2023-10-25 18:46:58 +00:00
|
|
|
ExpectedMinLengthList {
|
|
|
|
minimum_len,
|
|
|
|
actual_len,
|
|
|
|
} => write!(
|
|
|
|
f,
|
|
|
|
"Expected a list of at least {minimum_len} values, but got one with {actual_len}.",
|
|
|
|
),
|
2023-08-22 15:40:50 +00:00
|
|
|
ExpectedFixedLenList {
|
|
|
|
expected_len,
|
|
|
|
actual,
|
|
|
|
} => write!(
|
|
|
|
f,
|
2023-11-27 15:27:44 +00:00
|
|
|
"Expected a list of len {}, but got {:?}.",
|
2023-08-22 15:40:50 +00:00
|
|
|
expected_len, actual
|
|
|
|
),
|
2023-12-22 20:02:22 +00:00
|
|
|
ExpectedNone { actual } => write!(f, "Expected an empty value, but got {actual}."),
|
2023-12-10 18:47:05 +00:00
|
|
|
ExpectedMap { actual } => write!(f, "Expected a map, but got {actual}."),
|
|
|
|
ExpectedTable { actual } => write!(f, "Expected a table, but got {actual}."),
|
2023-08-22 15:40:50 +00:00
|
|
|
ExpectedFunction { actual } => {
|
2023-12-10 18:47:05 +00:00
|
|
|
write!(f, "Expected function, but got {actual}.")
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
2023-12-27 00:33:19 +00:00
|
|
|
ExpectedOption { actual } => write!(f, "Expected option, but got {actual}."),
|
2023-08-22 15:40:50 +00:00
|
|
|
ExpectedCollection { actual } => {
|
|
|
|
write!(
|
|
|
|
f,
|
2023-12-10 18:47:05 +00:00
|
|
|
"Expected a string, list, map or table, but got {actual}.",
|
2023-08-22 15:40:50 +00:00
|
|
|
)
|
|
|
|
}
|
2023-12-10 18:47:05 +00:00
|
|
|
VariableIdentifierNotFound(key) => write!(
|
2023-08-22 15:40:50 +00:00
|
|
|
f,
|
2023-12-10 18:47:05 +00:00
|
|
|
"Variable identifier is not bound to anything by context: {key}.",
|
2023-08-22 15:40:50 +00:00
|
|
|
),
|
2023-12-10 18:47:05 +00:00
|
|
|
FunctionIdentifierNotFound(key) => write!(
|
2023-08-22 15:40:50 +00:00
|
|
|
f,
|
2023-12-10 18:47:05 +00:00
|
|
|
"Function identifier is not bound to anything by context: {key}."
|
2023-08-22 15:40:50 +00:00
|
|
|
),
|
2023-10-10 17:29:11 +00:00
|
|
|
UnexpectedSyntaxNode {
|
2023-10-02 21:15:05 +00:00
|
|
|
expected,
|
2023-08-22 15:40:50 +00:00
|
|
|
actual,
|
2023-10-02 21:15:05 +00:00
|
|
|
location,
|
2023-10-13 16:26:44 +00:00
|
|
|
relevant_source,
|
2023-12-31 16:46:56 +00:00
|
|
|
} => {
|
|
|
|
let location = get_position(location);
|
|
|
|
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"Expected {expected}, but got {actual} at {location}. Code: {relevant_source} ",
|
|
|
|
)
|
|
|
|
}
|
2023-11-15 00:31:04 +00:00
|
|
|
WrongColumnAmount { expected, actual } => write!(
|
|
|
|
f,
|
|
|
|
"Wrong column amount. Expected {expected} but got {actual}."
|
2023-10-13 23:56:57 +00:00
|
|
|
),
|
2023-12-10 18:47:05 +00:00
|
|
|
External(message) => write!(f, "External error: {message}"),
|
2023-10-14 00:16:14 +00:00
|
|
|
CustomMessage(message) => write!(f, "{message}"),
|
2023-11-27 22:53:12 +00:00
|
|
|
Syntax { source, location } => {
|
2023-12-31 16:46:56 +00:00
|
|
|
let location = get_position(location);
|
|
|
|
|
|
|
|
write!(f, "Syntax error at {location}: {source}")
|
2023-11-27 22:53:12 +00:00
|
|
|
}
|
2023-12-09 22:55:47 +00:00
|
|
|
TypeCheck { expected, actual } => write!(
|
2023-11-28 15:29:42 +00:00
|
|
|
f,
|
2023-12-09 22:55:47 +00:00
|
|
|
"Type check error. Expected type {expected} but got type {actual}."
|
2023-11-28 15:29:42 +00:00
|
|
|
),
|
2023-12-09 22:55:47 +00:00
|
|
|
WithContext {
|
|
|
|
error,
|
|
|
|
location,
|
|
|
|
source,
|
2023-12-31 16:46:56 +00:00
|
|
|
} => {
|
|
|
|
let location = get_position(location);
|
|
|
|
|
|
|
|
write!(f, "{error} Occured at {location}: \"{source}\"")
|
|
|
|
}
|
2023-12-10 18:47:05 +00:00
|
|
|
SerdeJson(message) => write!(f, "JSON processing error: {message}"),
|
2023-12-29 19:01:54 +00:00
|
|
|
ParserCancelled => write!(
|
|
|
|
f,
|
|
|
|
"Parsing was cancelled either manually or because it took too long."
|
|
|
|
),
|
2024-01-04 00:57:06 +00:00
|
|
|
ExpectedFunctionType { actual } => write!(f, "Expected a function but got {actual}."),
|
2023-08-22 15:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-31 16:46:56 +00:00
|
|
|
|
|
|
|
fn get_position(position: &Point) -> String {
|
|
|
|
format!("column {}, row {}", position.row + 1, position.column)
|
|
|
|
}
|