77 * GNU Affero General Public License v3 (AGPLv3).
88 */
99
10+ use crate :: select_value:: { SelectValue , SelectValueType , ValueRef } ;
1011use itertools:: Itertools ;
12+ use log:: trace;
1113use pest:: iterators:: { Pair , Pairs } ;
1214use pest:: Parser ;
1315use pest_derive:: Parser ;
16+ use redis_module:: rediserror:: RedisError ;
17+ use regex:: Regex ;
1418use std:: borrow:: Cow ;
1519use std:: cmp:: Ordering ;
16-
17- use crate :: select_value:: { SelectValue , SelectValueType , ValueRef } ;
18- use log:: trace;
19- use regex:: Regex ;
2020use std:: fmt:: Debug ;
2121
2222// Macro to handle items() iterator for both Borrowed and Owned ValueRef cases
@@ -26,16 +26,16 @@ macro_rules! value_ref_items {
2626 ValueRef :: Borrowed ( borrowed_val) => {
2727 // For borrowed values, convert keys to owned for consistent return type
2828 let iter = borrowed_val. items( ) . unwrap( ) ;
29- let collected: Vec <_> = iter. map( |( k, v) | ( Cow :: Borrowed ( k) , v) ) . collect ( ) ;
29+ let collected = iter. map( |( k, v) | ( Cow :: Borrowed ( k) , v) ) . collect_vec ( ) ;
3030 Box :: new( collected. into_iter( ) )
3131 as Box <dyn Iterator <Item = ( Cow <' _, str >, ValueRef <' _, S >) >>
3232 }
3333 ValueRef :: Owned ( owned_val) => {
3434 // For owned values, collect first to avoid lifetime issues
3535 let iter = owned_val. items( ) . unwrap( ) ;
36- let collected: Vec <_> = iter
36+ let collected = iter
3737 . map( |( k, v) | ( Cow :: Owned ( k. to_string( ) ) , ValueRef :: Owned ( v. inner_cloned( ) ) ) )
38- . collect ( ) ;
38+ . collect_vec ( ) ;
3939 Box :: new( collected. into_iter( ) )
4040 as Box <dyn Iterator <Item = ( Cow <' _, str >, ValueRef <' _, S >) >>
4141 }
@@ -55,7 +55,9 @@ macro_rules! value_ref_values {
5555 ValueRef :: Owned ( owned_val) => {
5656 // For owned values, we need to collect first to avoid lifetime issues
5757 let iter = owned_val. values( ) . unwrap( ) ;
58- let collected: Vec <_> = iter. map( |v| ValueRef :: Owned ( v. inner_cloned( ) ) ) . collect( ) ;
58+ let collected = iter
59+ . map( |v| ValueRef :: Owned ( v. inner_cloned( ) ) )
60+ . collect_vec( ) ;
5961 Box :: new( collected. into_iter( ) ) as Box <dyn Iterator <Item = ValueRef <' _, S >>>
6062 }
6163 }
@@ -105,11 +107,16 @@ pub struct QueryCompilationError {
105107 message : String ,
106108}
107109
110+ impl From < QueryCompilationError > for RedisError {
111+ fn from ( e : QueryCompilationError ) -> Self {
112+ Self :: String ( e. to_string ( ) )
113+ }
114+ }
115+
108116impl < ' i > Query < ' i > {
109117 /// Pop the last element from the compiled json path.
110118 /// For example, if the json path is $.foo.bar then `pop_last`
111- /// will return bar and leave the json path query with foo only
112- /// ($.foo)
119+ /// will return bar and leave the json path query with $.foo
113120 #[ allow( dead_code) ]
114121 pub fn pop_last ( & mut self ) -> Option < ( String , JsonPathToken ) > {
115122 self . root . next_back ( ) . and_then ( |last| match last. as_rule ( ) {
@@ -123,7 +130,7 @@ impl<'i> Query<'i> {
123130 let first_on_list = last. into_inner ( ) . next ( ) ;
124131 first_on_list. map ( |first| ( first. as_str ( ) . to_string ( ) , JsonPathToken :: String ) )
125132 }
126- _ => panic ! ( "pop last was used in a none static path" ) ,
133+ _ => panic ! ( "pop last was used in a non- static path" ) ,
127134 } )
128135 }
129136
@@ -138,11 +145,11 @@ impl<'i> Query<'i> {
138145 self . size ( )
139146 }
140147
141- /// Results whether or not the compiled json path is static
142- /// Static path is a path that is promised to have at most a single result.
148+ /// Returns whether the compiled json path is static
149+ /// A static path is a path that is promised to have at most a single result.
143150 /// Example:
144151 /// static path: $.foo.bar
145- /// none static path: $.*.bar
152+ /// non- static path: $.*.bar
146153 #[ allow( dead_code) ]
147154 pub fn is_static ( & mut self ) -> bool {
148155 if self . is_static . is_some ( ) {
@@ -174,7 +181,7 @@ impl std::fmt::Display for QueryCompilationError {
174181 fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> Result < ( ) , std:: fmt:: Error > {
175182 write ! (
176183 f,
177- "Error occurred on position {}, {}" ,
184+ "Error occurred at position {}, {}" ,
178185 self . location, self . message
179186 )
180187 }
@@ -211,59 +218,31 @@ pub(crate) fn compile(path: &str) -> Result<Query<'_>, QueryCompilationError> {
211218 }
212219 // pest::error::Error
213220 Err ( e) => {
214- let pos = match e. location {
221+ let location = match e. location {
215222 pest:: error:: InputLocation :: Pos ( pos) => pos,
216223 pest:: error:: InputLocation :: Span ( ( pos, _end) ) => pos,
217224 } ;
218- let msg = match e. variant {
225+ let msg = match & e. variant {
219226 pest:: error:: ErrorVariant :: ParsingError {
220- ref positives,
221- ref negatives,
227+ positives,
228+ negatives,
222229 } => {
223- let positives = if positives. is_empty ( ) {
224- None
225- } else {
226- Some (
227- positives
228- . iter ( )
229- . map ( |v| format ! ( "{v}" ) )
230- . collect_vec ( )
231- . join ( ", " ) ,
232- )
233- } ;
234- let negatives = if negatives. is_empty ( ) {
235- None
236- } else {
237- Some (
238- negatives
239- . iter ( )
240- . map ( |v| format ! ( "{v}" ) )
241- . collect_vec ( )
242- . join ( ", " ) ,
243- )
244- } ;
245-
246- match ( positives, negatives) {
247- ( None , None ) => "parsing error" . to_string ( ) ,
248- ( Some ( p) , None ) => format ! ( "expected one of the following: {p}" ) ,
249- ( None , Some ( n) ) => format ! ( "unexpected tokens found: {n}" ) ,
250- ( Some ( p) , Some ( n) ) => format ! (
230+ let p = positives. into_iter ( ) . join ( ", " ) ;
231+ let n = negatives. into_iter ( ) . join ( ", " ) ;
232+ match ( p. len ( ) , n. len ( ) ) {
233+ ( 0 , 0 ) => "parsing error" . to_string ( ) ,
234+ ( _, 0 ) => format ! ( "expected one of the following: {p}" ) ,
235+ ( 0 , _) => format ! ( "unexpected tokens found: {n}" ) ,
236+ ( _, _) => format ! (
251237 "expected one of the following: {p}, unexpected tokens found: {n}"
252238 ) ,
253239 }
254240 }
255- pest:: error:: ErrorVariant :: CustomError { ref message } => message. clone ( ) ,
241+ pest:: error:: ErrorVariant :: CustomError { message } => message. clone ( ) ,
256242 } ;
257243
258- let final_msg = if pos == path. len ( ) {
259- format ! ( "\" {path} <<<<----\" , {msg}." )
260- } else {
261- format ! ( "\" {} ---->>>> {}\" , {}." , & path[ ..pos] , & path[ pos..] , msg)
262- } ;
263- Err ( QueryCompilationError {
264- location : pos,
265- message : final_msg,
266- } )
244+ let message = format ! ( "Error at position {}: {}" , location, msg) ;
245+ Err ( QueryCompilationError { location, message } )
267246 }
268247 }
269248}
0 commit comments