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)]
42pub enum JqlRunnerError {
43 #[error("Query is empty")]
45 EmptyQueryError,
46
47 #[error("Value {0} is neither an array nor an object and can't be flattened")]
49 FlattenError(Value),
50
51 #[error("Index {index} in parent {parent} is out of bounds")]
53 IndexOutOfBoundsError {
54 index: usize,
56 parent: Value,
58 },
59
60 #[error("Value {} is not a JSON array ({})", .0, get_json_type(.0))]
62 InvalidArrayError(Value),
63
64 #[error("Value {} is not a JSON object ({})", .0, get_json_type(.0))]
66 InvalidObjectError(Value),
67
68 #[error(r#"Key "{key}" doesn't exist in parent {}"#, shorten(parent))]
70 KeyNotFoundError {
71 key: String,
73 parent: Value,
75 },
76
77 #[error("Keys {} don't exist in parent {}", join(keys), shorten(parent))]
79 MultiKeyNotFoundError {
80 keys: Vec<String>,
82 parent: Value,
84 },
85
86 #[error(transparent)]
88 ParsingError(#[from] JqlParserError),
89
90 #[error("Pipe in operator used on {0} which is not an array")]
92 PipeInError(Value),
93
94 #[error("Pipe out operator used without a preceding pipe in operator")]
96 PipeOutError,
97
98 #[error("Range [{start}:{end}] in parent {parent} is out of bounds")]
100 RangeOutOfBoundsError {
101 start: usize,
103 end: usize,
105 parent: Value,
107 },
108
109 #[error("Unknown error")]
111 UnknownError,
112}
113
114#[cfg(test)]
115mod tests {
116
117 use serde_json::json;
118
119 use super::{
120 get_json_type,
121 join,
122 shorten,
123 };
124
125 #[test]
126 fn check_get_json_type() {
127 assert_eq!(get_json_type(&json!([])), "array");
128 assert_eq!(get_json_type(&json!(true)), "boolean");
129 assert_eq!(get_json_type(&json!(null)), "null");
130 assert_eq!(get_json_type(&json!(1)), "number");
131 assert_eq!(get_json_type(&json!({})), "object");
132 assert_eq!(get_json_type(&json!("a")), "string");
133 }
134
135 #[test]
136 fn check_join() {
137 assert_eq!(
138 join(&["a".to_string(), "b".to_string(), "c".to_string()]),
139 "a, b, c".to_string()
140 );
141 }
142
143 #[test]
144 fn check_shorten() {
145 assert_eq!(shorten(&json!("thismakesnosense")), r#""thismakesnosense""#);
146 assert_eq!(
147 shorten(&json!({ "a": { "b": { "c": [1, 2 ,3, 4, 5, 6, 7, 8, 9] } } })),
148 r#"{"a":{" ... 8,9]}}}"#.to_string()
149 );
150 }
151}