jsonpath_plus/
error.rs

1//! Errors returned by fallible methods
2
3use core::fmt;
4use std::error;
5use std::error::Error;
6
7use crate::ast::ParseFail;
8use crate::Idx;
9use serde_json::Value;
10
11/// Error returned by a failure to parse a provided JSON Path
12#[derive(Debug)]
13pub struct ParseError {
14    src: String,
15    errs: Vec<ParseFail<char, ()>>,
16}
17
18impl ParseError {
19    pub(crate) fn new(src: &str, errs: Vec<ParseFail<char, ()>>) -> ParseError {
20        ParseError {
21            src: src.to_string(),
22            errs,
23        }
24    }
25}
26
27impl fmt::Display for ParseError {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        writeln!(f, "Error Parsing JSON Path:")?;
30        writeln!(f, "{}", self.src)?;
31        for _err in &self.errs {
32            todo!();
33            // writeln!(f, "{}", err)?;
34        }
35        Ok(())
36    }
37}
38
39impl error::Error for ParseError {}
40
41/// Enum for an error that might be either a failure to parse a JSON path, or failure to deserialize
42/// JSON data
43#[derive(Debug)]
44pub enum ParseOrJsonError {
45    /// Error was a failure to parse JSON Path
46    Parse(ParseError),
47    /// Error was a failure to deserialize JSON data
48    Json(serde_json::Error),
49}
50
51impl fmt::Display for ParseOrJsonError {
52    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53        match self {
54            ParseOrJsonError::Parse(err) => write!(f, "{}", err),
55            ParseOrJsonError::Json(err) => write!(f, "{}", err),
56        }
57    }
58}
59
60impl error::Error for ParseOrJsonError {
61    fn source(&self) -> Option<&(dyn Error + 'static)> {
62        match self {
63            ParseOrJsonError::Parse(p) => Some(p),
64            ParseOrJsonError::Json(j) => Some(j),
65        }
66    }
67}
68
69impl From<ParseError> for ParseOrJsonError {
70    fn from(err: ParseError) -> Self {
71        ParseOrJsonError::Parse(err)
72    }
73}
74
75impl From<serde_json::Error> for ParseOrJsonError {
76    fn from(err: serde_json::Error) -> Self {
77        ParseOrJsonError::Json(err)
78    }
79}
80
81/// Type of a JSON Value for error info
82#[derive(Copy, Clone, Debug)]
83pub enum JsonTy {
84    /// `null`
85    Null,
86    /// `true` or `false`
87    Bool,
88    /// `1.5` or similar
89    Number,
90    /// `"foo"` or similar
91    String,
92    /// `[1, 2, 3]` or similar
93    Array,
94    /// `{"a": false}` or similar
95    Object,
96}
97
98impl fmt::Display for JsonTy {
99    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100        match self {
101            JsonTy::Null => write!(f, "null"),
102            JsonTy::Bool => write!(f, "bool"),
103            JsonTy::Number => write!(f, "number"),
104            JsonTy::String => write!(f, "string"),
105            JsonTy::Array => write!(f, "array"),
106            JsonTy::Object => write!(f, "object"),
107        }
108    }
109}
110
111impl From<&Value> for JsonTy {
112    fn from(val: &Value) -> Self {
113        match val {
114            Value::Null => JsonTy::Null,
115            Value::Bool(_) => JsonTy::Bool,
116            Value::Number(_) => JsonTy::Number,
117            Value::String(_) => JsonTy::String,
118            Value::Array(_) => JsonTy::Array,
119            Value::Object(_) => JsonTy::Object,
120        }
121    }
122}
123
124/// Error returned by a failure to resolve a path of indices
125#[derive(Debug)]
126pub enum ResolveError {
127    /// Expected next item in the path to be a specific type, but it wasn't
128    MismatchedTy {
129        /// Type that was expected
130        expected: JsonTy,
131        /// Type that was found
132        actual: JsonTy,
133    },
134    /// Expected an index to exist, but it didn't
135    MissingIdx(Idx),
136}
137
138impl ResolveError {
139    pub(crate) fn mismatched(expected: JsonTy, got: &Value) -> ResolveError {
140        ResolveError::MismatchedTy {
141            expected,
142            actual: got.into(),
143        }
144    }
145}
146
147impl fmt::Display for ResolveError {
148    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149        match self {
150            ResolveError::MismatchedTy { expected, actual } => {
151                write!(
152                    f,
153                    "Resolved path expected type {}, instead got type {}",
154                    expected, actual
155                )
156            }
157            ResolveError::MissingIdx(idx) => {
158                let idx = match idx {
159                    Idx::Array(i) => i as &dyn fmt::Debug,
160                    Idx::Object(i) => i as &dyn fmt::Debug,
161                };
162                write!(
163                    f,
164                    "Resolved path expected an index {:?}, but it didn't exist",
165                    idx
166                )
167            }
168        }
169    }
170}