Skip to main content

lance_jsonb/
error.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright The Lance Authors
3// SPDX-FileCopyrightText: Copyright 2023 Datafuse Labs
4// Adapted from databendlabs/jsonb at commit fba895c5ebe77ce2539e187f9c652f51cbf195c3.
5
6use core::fmt::Display;
7
8use serde::de;
9use serde::ser;
10
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub enum ParseErrorCode {
13    InvalidEOF,
14    InvalidNumberValue,
15    InvalidStringValue,
16    ExpectedSomeIdent,
17    ExpectedSomeValue,
18    ExpectedColon,
19    ExpectedArrayCommaOrEnd,
20    ExpectedObjectCommaOrEnd,
21    UnexpectedTrailingCharacters,
22    KeyMustBeAString,
23    ControlCharacterWhileParsingString,
24    InvalidEscaped(u8),
25    InvalidHex(u8),
26    InvalidLoneLeadingSurrogateInHexEscape(u16),
27    InvalidSurrogateInHexEscape(u16),
28    UnexpectedEndOfHexEscape,
29    ObjectDuplicateKey(String),
30    ObjectKeyInvalidNumber,
31    ObjectKeyInvalidCharacter,
32}
33
34pub type Result<T> = std::result::Result<T, Error>;
35
36impl Display for ParseErrorCode {
37    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
38        match self {
39            Self::InvalidEOF => f.write_str("EOF while parsing a value"),
40            Self::InvalidNumberValue => f.write_str("invalid number"),
41            Self::InvalidStringValue => f.write_str("invalid string"),
42            Self::ExpectedSomeIdent => f.write_str("expected ident"),
43            Self::ExpectedSomeValue => f.write_str("expected value"),
44            Self::ExpectedColon => f.write_str("expected `:`"),
45            Self::ExpectedArrayCommaOrEnd => f.write_str("expected `,` or `]`"),
46            Self::ExpectedObjectCommaOrEnd => f.write_str("expected `,` or `}`"),
47            Self::UnexpectedTrailingCharacters => f.write_str("trailing characters"),
48            Self::KeyMustBeAString => f.write_str("key must be a string"),
49            Self::ControlCharacterWhileParsingString => {
50                f.write_str("control character (\\u0000-\\u001F) found while parsing a string")
51            }
52            Self::InvalidEscaped(n) => {
53                write!(f, "invalid escaped '{:X}'", n)
54            }
55            Self::InvalidHex(n) => {
56                write!(f, "invalid hex '{:X}'", n)
57            }
58            Self::InvalidLoneLeadingSurrogateInHexEscape(n) => {
59                write!(f, "lone leading surrogate in hex escape '{:X}'", n)
60            }
61            Self::InvalidSurrogateInHexEscape(n) => {
62                write!(f, "invalid surrogate in hex escape '{:X}'", n)
63            }
64            Self::UnexpectedEndOfHexEscape => f.write_str("unexpected end of hex escape"),
65            Self::ObjectDuplicateKey(key) => {
66                write!(f, "duplicate object attribute \"{}\"", key)
67            }
68            Self::ObjectKeyInvalidNumber => f.write_str("object attribute name cannot be a number"),
69            Self::ObjectKeyInvalidCharacter => {
70                f.write_str("object attribute name cannot be invalid character")
71            }
72        }
73    }
74}
75
76#[derive(Debug, Clone, PartialEq, Eq, Hash)]
77#[non_exhaustive]
78pub enum Error {
79    InvalidUtf8,
80    InvalidEOF,
81    InvalidToken,
82    InvalidCast,
83
84    InvalidJson,
85    InvalidJsonb,
86    InvalidJsonbHeader,
87    InvalidJsonbJEntry,
88    InvalidJsonbNumber,
89    InvalidJsonbExtension,
90
91    InvalidJsonPath,
92    InvalidJsonPathPredicate,
93    InvalidKeyPath,
94
95    InvalidJsonType,
96    InvalidObject,
97    ObjectDuplicateKey,
98    UnexpectedType,
99
100    Message(String),
101    Syntax(ParseErrorCode, usize),
102}
103
104impl ser::Error for Error {
105    fn custom<T: Display>(msg: T) -> Self {
106        Self::Message(msg.to_string())
107    }
108}
109
110impl de::Error for Error {
111    fn custom<T: Display>(msg: T) -> Self {
112        Self::Message(msg.to_string())
113    }
114}
115
116impl Display for Error {
117    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
118        match self {
119            Self::Message(m) => write!(f, "{}", m),
120            Self::Syntax(code, pos) => write!(f, "{}, pos {}", code, pos),
121            _ => write!(f, "{:?}", self),
122        }
123    }
124}
125
126impl std::error::Error for Error {
127    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
128        None
129    }
130}
131
132impl From<std::io::Error> for Error {
133    fn from(_error: std::io::Error) -> Self {
134        Self::InvalidUtf8
135    }
136}
137
138impl From<std::str::Utf8Error> for Error {
139    fn from(_error: std::str::Utf8Error) -> Self {
140        Self::InvalidUtf8
141    }
142}
143
144impl From<nom::Err<nom::error::Error<&[u8]>>> for Error {
145    fn from(_error: nom::Err<nom::error::Error<&[u8]>>) -> Self {
146        Self::InvalidJsonb
147    }
148}