use crate::error::display::fmt_parse_error;
use crate::{
num::error::{JsonFloatParseError, JsonIntParseError},
str::{self},
};
use std::fmt::{self, Display};
use thiserror::Error;
mod display;
mod formatter;
mod style;
#[derive(Debug)]
pub(crate) struct ParseErrorBuilder {
syntax_errors: Vec<SyntaxError>,
}
#[derive(Debug, Error)]
pub struct ParseError {
input: String,
inner: InnerParseError,
}
impl Display for ParseError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt_parse_error(self, &display::empty_style(), f)
}
}
impl ParseError {
#[inline]
#[must_use]
pub fn is_nesting_limit_exceeded(&self) -> bool {
matches!(self.inner, InnerParseError::RecursionLimit(_))
}
}
#[derive(Debug)]
enum InnerParseError {
Syntax(Vec<SyntaxError>),
RecursionLimit(usize),
}
impl ParseErrorBuilder {
pub(crate) fn new() -> Self {
Self { syntax_errors: vec![] }
}
pub(crate) fn add(&mut self, syntax_error: SyntaxError) {
self.syntax_errors.push(syntax_error)
}
pub(crate) fn add_many(&mut self, mut syntax_errors: Vec<SyntaxError>) {
self.syntax_errors.append(&mut syntax_errors)
}
pub(crate) fn is_empty(&self) -> bool {
self.syntax_errors.is_empty()
}
pub(crate) fn build(self, str: String) -> ParseError {
ParseError {
input: str,
inner: InnerParseError::Syntax(self.syntax_errors),
}
}
pub(crate) fn recursion_limit_exceeded(str: String, recursion_limit: usize) -> ParseError {
ParseError {
input: str,
inner: InnerParseError::RecursionLimit(recursion_limit),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub(crate) struct SyntaxError {
kind: SyntaxErrorKind,
rev_idx: usize,
len: usize,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub(crate) enum SyntaxErrorKind {
DisallowedLeadingWhitespace,
DisallowedTrailingWhitespace,
MissingRootIdentifier,
InvalidUnescapedCharacter,
InvalidEscapeSequence,
UnpairedHighSurrogate,
UnpairedLowSurrogate,
InvalidHexDigitInUnicodeEscape,
MissingClosingSingleQuote,
MissingClosingDoubleQuote,
InvalidSegmentStart,
InvalidSegmentAfterTwoPeriods,
EmptySelector,
InvalidSelector,
MissingSelectorSeparator,
MissingClosingBracket,
InvalidNameShorthandAfterOnePeriod,
NegativeZeroInteger,
LeadingZeros,
NumberParseError(JsonFloatParseError),
IndexParseError(JsonIntParseError),
SliceStartParseError(JsonIntParseError),
SliceEndParseError(JsonIntParseError),
SliceStepParseError(JsonIntParseError),
MissingClosingParenthesis,
InvalidNegation,
MissingComparisonOperator,
InvalidComparisonOperator,
InvalidComparable,
NonSingularQueryInComparison,
InvalidFilter,
}
impl SyntaxError {
pub(crate) fn new(kind: SyntaxErrorKind, rev_idx: usize, len: usize) -> Self {
Self { kind, rev_idx, len }
}
}
#[derive(Debug)]
pub(crate) enum InternalParseError<'a> {
SyntaxError(SyntaxError, &'a str),
SyntaxErrors(Vec<SyntaxError>, &'a str),
RecursionLimitExceeded,
NomError(nom::error::Error<&'a str>),
}
impl<'a> nom::error::ParseError<&'a str> for InternalParseError<'a> {
fn from_error_kind(input: &'a str, kind: nom::error::ErrorKind) -> Self {
Self::NomError(nom::error::Error::from_error_kind(input, kind))
}
fn append(input: &'a str, kind: nom::error::ErrorKind, other: Self) -> Self {
match other {
Self::NomError(e) => Self::NomError(nom::error::Error::append(input, kind, e)),
_ => other,
}
}
}