use std::{char, error, fmt};
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, PartialEq)]
pub enum Error {
S0101UnterminatedStringLiteral(usize),
S0102LexedNumberOutOfRange(usize, String),
S0103UnsupportedEscape(usize, char),
S0104InvalidUnicodeEscape(usize),
S0105UnterminatedQuoteProp(usize),
S0106UnterminatedComment(usize),
S0201SyntaxError(usize, String),
S0202UnexpectedToken(usize, String, String),
S0204UnknownOperator(usize, String),
S0203ExpectedTokenBeforeEnd(usize, String),
S0208InvalidFunctionParam(usize, String),
S0209InvalidPredicate(usize),
S0210MultipleGroupBy(usize),
S0211InvalidUnary(usize, String),
S0212ExpectedVarLeft(usize),
S0213InvalidStep(usize, String),
S0214ExpectedVarRight(usize, String),
D1001NumberOfOutRange(f64),
D1002NegatingNonNumeric(usize, String),
D1009MultipleKeys(usize, String),
D2014RangeOutOfBounds(usize, isize),
D3001StringNotFinite(usize),
D3030NonNumericCast(usize, String),
D3060SqrtNegative(usize, String),
D3061PowUnrepresentable(usize, String, String),
D3141Assert(String),
D3137Error(String),
T0410ArgumentNotValid(usize, usize, String),
T0412ArgumentMustBeArrayOfType(usize, usize, String, String),
T1003NonStringKey(usize, String),
T1005InvokedNonFunctionSuggest(usize, String),
T1006InvokedNonFunction(usize),
T2001LeftSideNotNumber(usize, String),
T2002RightSideNotNumber(usize, String),
T2003LeftSideNotInteger(usize),
T2004RightSideNotInteger(usize),
T2009BinaryOpMismatch(usize, String, String, String),
T2010BinaryOpTypes(usize, String),
U1001StackOverflow,
U1001Timeout
}
impl error::Error for Error {}
impl Error {
pub fn code(&self) -> &str {
match *self {
Error::S0101UnterminatedStringLiteral(..) => "S0101",
Error::S0102LexedNumberOutOfRange(..) => "S0102",
Error::S0103UnsupportedEscape(..) => "S0103",
Error::S0104InvalidUnicodeEscape(..) => "S0104",
Error::S0105UnterminatedQuoteProp(..) => "S0105",
Error::S0106UnterminatedComment(..) => "S0106",
Error::S0201SyntaxError(..) => "S0201",
Error::S0202UnexpectedToken(..) => "S0202",
Error::S0203ExpectedTokenBeforeEnd(..) => "S0203",
Error::S0204UnknownOperator(..) => "S0204",
Error::S0208InvalidFunctionParam(..) => "S0208",
Error::S0209InvalidPredicate(..) => "S0209",
Error::S0210MultipleGroupBy(..) => "S0210",
Error::S0211InvalidUnary(..) => "S0211",
Error::S0212ExpectedVarLeft(..) => "S0212",
Error::S0213InvalidStep(..) => "S0213",
Error::S0214ExpectedVarRight(..) => "S0214",
Error::D1001NumberOfOutRange(..) => "D1001",
Error::D1002NegatingNonNumeric(..) => "D1002",
Error::D1009MultipleKeys(..) => "D1009",
Error::D2014RangeOutOfBounds(..) => "D2014",
Error::D3001StringNotFinite(..) => "D3001",
Error::D3030NonNumericCast(..) => "D3030",
Error::D3060SqrtNegative(..) => "D3060",
Error::D3061PowUnrepresentable(..) => "D3061",
Error::D3141Assert(..) => "D3141",
Error::D3137Error(..) => "D3137",
Error::T0410ArgumentNotValid(..) => "T0410",
Error::T0412ArgumentMustBeArrayOfType(..) => "T0412",
Error::T1003NonStringKey(..) => "T1003",
Error::T1005InvokedNonFunctionSuggest(..) => "T1005",
Error::T1006InvokedNonFunction(..) => "T1006",
Error::T2001LeftSideNotNumber(..) => "T2001",
Error::T2002RightSideNotNumber(..) => "T2002",
Error::T2003LeftSideNotInteger(..) => "T2003",
Error::T2004RightSideNotInteger(..) => "T2004",
Error::T2009BinaryOpMismatch(..) => "T2009",
Error::T2010BinaryOpTypes(..) => "T2010",
Error::U1001StackOverflow => "U1001",
Error::U1001Timeout => "U1001"
}
}
}
impl fmt::Display for Error {
#[allow(clippy::many_single_char_names)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use Error::*;
write!(f, "{} @ ", self.code())?;
match *self {
S0101UnterminatedStringLiteral(ref p) =>
write!(f, "{}: String literal must be terminated by a matching quote", p),
S0102LexedNumberOutOfRange(ref p, ref n) =>
write!(f, "{}: Number out of range: {}", p, n),
S0103UnsupportedEscape(ref p, ref c) =>
write!(f, "{}: Unsupported escape sequence: \\{}", p, c),
S0104InvalidUnicodeEscape(ref p) =>
write!(f, "{}: The escape sequence \\u must be followed by 4 hex digits", p),
S0105UnterminatedQuoteProp(ref p) =>
write!(f, "{}: Quoted property name must be terminated with a backquote (`)", p),
S0106UnterminatedComment(ref p) =>
write!(f, "{}: Comment has no closing tag", p),
S0201SyntaxError(ref p, ref t) =>
write!(f, "{}: Syntax error `{}`", p, t),
S0202UnexpectedToken(ref p, ref e, ref a) =>
write!(f, "{}: Expected `{}`, got `{}`", p, e, a),
S0203ExpectedTokenBeforeEnd(ref p, ref t) =>
write!(f, "{}: Expected `{}` before end of expression", p, t),
S0204UnknownOperator(ref p, ref t) =>
write!(f, "{}: Unknown operator: `{}`", p, t),
S0208InvalidFunctionParam(ref p, ref k) =>
write!(f, "{}: Parameter `{}` of function definition must be a variable name (start with $)", p, k),
S0209InvalidPredicate(ref p) =>
write!(f, "{}: A predicate cannot follow a grouping expression in a step", p),
S0210MultipleGroupBy(ref p) =>
write!(f, "{}: Each step can only have one grouping expression", p),
S0211InvalidUnary(ref p, ref k) =>
write!(f, "{}: The symbol `{}` cannot be used as a unary operator", p, k),
S0212ExpectedVarLeft(ref p) =>
write!(f, "{}: The left side of `:=` must be a variable name (start with $)", p),
S0213InvalidStep(ref p, ref k) =>
write!(f, "{}: The literal value `{}` cannot be used as a step within a path expression", p, k),
S0214ExpectedVarRight(ref p, ref k) =>
write!(f, "{}: The right side of `{}` must be a variable name (start with $)", p, k),
D1001NumberOfOutRange(ref n) =>
write!(f, "Number out of range: {}", n),
D1002NegatingNonNumeric(ref p, ref v) =>
write!(f, "{}: Cannot negate a non-numeric value `{}`", p, v),
D1009MultipleKeys(ref p, ref k) =>
write!(f, "{}: Multiple key definitions evaluate to same key: {}", p, k),
D2014RangeOutOfBounds(ref p, ref s) =>
write!(f, "{}: The size of the sequence allocated by the range operator (..) must not exceed 1e7. Attempted to allocate {}", p, s),
D3001StringNotFinite(ref p) =>
write!(f, "{}: Attempting to invoke string function on Infinity or NaN", p),
D3030NonNumericCast(ref p, ref n) =>
write!(f, "{}: Unable to cast value to a number: {}", p, n),
D3060SqrtNegative(ref p, ref n) =>
write!(f, "{}: The sqrt function cannot be applied to a negative number: {}", p, n),
D3061PowUnrepresentable(ref p, ref b, ref e) =>
write!(f, "{}: The power function has resulted in a value that cannot be represented as a JSON number: base={}, exponent={}", p, b, e),
D3141Assert(ref m) =>
write!(f, "{}", m),
D3137Error(ref m) =>
write!(f, "{}", m),
T0410ArgumentNotValid(ref p, ref i, ref t) =>
write!(f, "{}: Argument {} of function {} does not match function signature", p, i, t),
T0412ArgumentMustBeArrayOfType(ref p, ref i, ref t, ref ty) =>
write!(f, "{}: Argument {} of function {} must be an array of {}", p, i, t, ty),
T1003NonStringKey(ref p, ref v) =>
write!( f, "{}: Key in object structure must evaluate to a string; got: {}", p, v),
T1005InvokedNonFunctionSuggest(ref p, ref t) =>
write!(f, "{}: Attempted to invoke a non-function. Did you mean ${}?", p, t),
T1006InvokedNonFunction(ref p) =>
write!(f, "{}: Attempted to invoke a non-function", p),
T2001LeftSideNotNumber(ref p, ref o) =>
write!( f, "{}: The left side of the `{}` operator must evaluate to a number", p, o),
T2002RightSideNotNumber(ref p, ref o) =>
write!( f, "{}: The right side of the `{}` operator must evaluate to a number", p, o),
T2003LeftSideNotInteger(ref p) =>
write!(f, "{}: The left side of the range operator (..) must evaluate to an integer", p),
T2004RightSideNotInteger(ref p) =>
write!(f, "{}: The right side of the range operator (..) must evaluate to an integer", p),
T2009BinaryOpMismatch(ref p,ref l ,ref r ,ref o ) =>
write!(f, "{}: The values {} and {} either side of operator {} must be of the same data type", p, l, r, o),
T2010BinaryOpTypes(ref p, ref o) =>
write!(f, "{}: The expressions either side of operator `{}` must evaluate to numeric or string values", p, o),
U1001StackOverflow =>
write!(f, "Stack overflow error: Check for non-terminating recursive function. Consider rewriting as tail-recursive."),
U1001Timeout =>
write!(f, "Expression evaluation timeout: Check for infinite loop")
}
}
}