1use jql_parser::errors::JqlParserError;
2use serde_json::Value;
3use thiserror::Error;
4
5static SLICE_SEP: &str = " ... ";
6static SLICE_LEN: usize = 7;
7static SEP: &str = ", ";
8
9fn join(values: &[String]) -> String {
11 values.join(SEP)
12}
13
14fn shorten(json: &Value) -> String {
16 let full_json_string = json.to_string();
17
18 if full_json_string.len() < SLICE_LEN * 2 + SLICE_SEP.len() {
19 return full_json_string;
20 }
21
22 let start_slice = &full_json_string[..SLICE_LEN];
23 let end_slice = &full_json_string[full_json_string.len() - SLICE_LEN..];
24
25 [start_slice, end_slice].join(SLICE_SEP)
26}
27
28fn get_json_type(json: &Value) -> &str {
30 match json {
31 Value::Array(_) => "array",
32 Value::Bool(_) => "boolean",
33 Value::Null => "null",
34 Value::Number(_) => "number",
35 Value::Object(_) => "object",
36 Value::String(_) => "string",
37 }
38}
39
40#[derive(Debug, Error, PartialEq)]
45#[non_exhaustive]
46pub enum JqlRunnerError {
47 #[error("Failed to deserialize the JSON data")]
49 DeserializationError,
50
51 #[error("Query is empty")]
53 EmptyQueryError,
54
55 #[error("Value {0} is neither an array nor an object and can't be flattened")]
57 FlattenError(Value),
58
59 #[error("Index {index} in parent {parent} is out of bounds")]
61 IndexOutOfBoundsError {
62 index: usize,
64 parent: Value,
66 },
67
68 #[error("Value {} is not a JSON array ({})", .0, get_json_type(.0))]
70 InvalidArrayError(Value),
71
72 #[error("Value {} is not a JSON object ({})", .0, get_json_type(.0))]
74 InvalidObjectError(Value),
75
76 #[error(r#"Key "{key}" doesn't exist in parent {}"#, shorten(parent))]
78 KeyNotFoundError {
79 key: String,
81 parent: Value,
83 },
84
85 #[error("Keys {} don't exist in parent {}", join(keys), shorten(parent))]
87 MultiKeyNotFoundError {
88 keys: Vec<String>,
90 parent: Value,
92 },
93
94 #[error(transparent)]
96 ParsingError(#[from] JqlParserError),
97
98 #[error("Pipe in operator used on {0} which is not an array")]
100 PipeInError(Value),
101
102 #[error("Pipe out operator used without a preceding pipe in operator")]
104 PipeOutError,
105
106 #[error("Range [{start}:{end}] in parent {parent} is out of bounds")]
108 RangeOutOfBoundsError {
109 start: usize,
111 end: usize,
113 parent: Value,
115 },
116
117 #[error("Unknown error")]
119 UnknownError,
120}
121
122#[cfg(test)]
123mod tests {
124
125 use serde_json::json;
126
127 use super::{
128 get_json_type,
129 join,
130 shorten,
131 };
132
133 #[test]
134 fn check_get_json_type() {
135 assert_eq!(get_json_type(&json!([])), "array");
136 assert_eq!(get_json_type(&json!(true)), "boolean");
137 assert_eq!(get_json_type(&json!(null)), "null");
138 assert_eq!(get_json_type(&json!(1)), "number");
139 assert_eq!(get_json_type(&json!({})), "object");
140 assert_eq!(get_json_type(&json!("a")), "string");
141 }
142
143 #[test]
144 fn check_join() {
145 assert_eq!(
146 join(&["a".to_string(), "b".to_string(), "c".to_string()]),
147 "a, b, c".to_string()
148 );
149 }
150
151 #[test]
152 fn check_shorten() {
153 assert_eq!(shorten(&json!("thismakesnosense")), r#""thismakesnosense""#);
154 assert_eq!(
155 shorten(&json!({ "a": { "b": { "c": [1, 2 ,3, 4, 5, 6, 7, 8, 9] } } })),
156 r#"{"a":{" ... 8,9]}}}"#.to_string()
157 );
158 }
159}