@@ -2,7 +2,7 @@ use crate::{
22 error:: { InternalParseError , ParseErrorBuilder , SyntaxError , SyntaxErrorKind } ,
33 num:: { error:: JsonIntParseError , JsonInt , JsonNonZeroUInt , JsonUInt } ,
44 str:: { JsonString , JsonStringBuilder } ,
5- Index , JsonPathQuery , ParserOptions , Result , Segment , Selector , Selectors , SliceBuilder , Step ,
5+ Index , JsonPathQuery , ParserOptions , Result , Segment , Selector , Selectors , Step ,
66} ;
77use nom:: { branch:: * , bytes:: complete:: * , character:: complete:: * , combinator:: * , multi:: * , sequence:: * , * } ;
88use std:: { iter:: Peekable , str:: FromStr } ;
@@ -254,12 +254,12 @@ fn wildcard_selector(q: &str) -> IResult<&str, Selector, InternalParseError> {
254254fn slice_selector ( q : & str ) -> IResult < & str , Selector , InternalParseError > {
255255 let ( rest, opt_start) = terminated ( opt ( int) , ignore_whitespace ( char ( ':' ) ) ) ( q) ?;
256256 // We have parsed a ':', so this *must* be a slice selector. Any errors after here are fatal.
257- let mut slice = SliceBuilder :: new ( ) ;
257+ let mut slice = crate :: Slice :: default ( ) ;
258258
259259 if let Some ( start_str) = opt_start {
260260 match parse_directional_int ( start_str) {
261- DirectionalInt :: Plus ( int) => slice. with_start ( Index :: FromStart ( int) ) ,
262- DirectionalInt :: Minus ( int) => slice. with_start ( Index :: FromEnd ( int) ) ,
261+ DirectionalInt :: Plus ( int) => slice. start = Index :: FromStart ( int) ,
262+ DirectionalInt :: Minus ( int) => slice. start = Index :: FromEnd ( int) ,
263263 DirectionalInt :: Error ( err) => {
264264 return fail (
265265 SyntaxErrorKind :: SliceStartParseError ( err) ,
@@ -275,8 +275,8 @@ fn slice_selector(q: &str) -> IResult<&str, Selector, InternalParseError> {
275275
276276 if let Some ( end_str) = opt_end {
277277 match parse_directional_int ( end_str) {
278- DirectionalInt :: Plus ( int) => slice. with_end ( Index :: FromStart ( int) ) ,
279- DirectionalInt :: Minus ( int) => slice. with_end ( Index :: FromEnd ( int) ) ,
278+ DirectionalInt :: Plus ( int) => slice. end = Some ( Index :: FromStart ( int) ) ,
279+ DirectionalInt :: Minus ( int) => slice. end = Some ( Index :: FromEnd ( int) ) ,
280280 DirectionalInt :: Error ( err) => {
281281 return fail ( SyntaxErrorKind :: SliceEndParseError ( err) , q. len ( ) , end_str. len ( ) , rest) ;
282282 }
@@ -288,15 +288,15 @@ fn slice_selector(q: &str) -> IResult<&str, Selector, InternalParseError> {
288288
289289 if let Some ( Some ( step_str) ) = opt_step {
290290 match parse_directional_int ( step_str) {
291- DirectionalInt :: Plus ( int) => slice. with_step ( Step :: Forward ( int) ) ,
292- DirectionalInt :: Minus ( int) => slice. with_step ( Step :: Backward ( int) ) ,
291+ DirectionalInt :: Plus ( int) => slice. step = Step :: Forward ( int) ,
292+ DirectionalInt :: Minus ( int) => slice. step = Step :: Backward ( int) ,
293293 DirectionalInt :: Error ( err) => {
294294 return fail ( SyntaxErrorKind :: SliceStepParseError ( err) , q. len ( ) , step_str. len ( ) , rest) ;
295295 }
296296 } ;
297297 }
298298
299- Ok ( ( rest, Selector :: Slice ( slice. into ( ) ) ) )
299+ Ok ( ( rest, Selector :: Slice ( slice) ) )
300300}
301301
302302fn index_selector ( q : & str ) -> IResult < & str , Selector , InternalParseError > {
@@ -655,11 +655,13 @@ mod tests {
655655 #[ derive( Debug , Clone ) ]
656656 enum SelectorTag {
657657 WildcardChild ,
658- Child ( String ) ,
659- WildcardDescendant ,
660- Descendant ( String ) ,
658+ NameChild ( String ) ,
661659 ArrayIndexChild ( JsonUInt ) ,
660+ ArraySliceChild ( JsonUInt , Option < JsonUInt > , JsonUInt ) ,
661+ WildcardDescendant ,
662+ NameDescendant ( String ) ,
662663 ArrayIndexDescendant ( JsonUInt ) ,
664+ ArraySliceDescendant ( JsonUInt , Option < JsonUInt > , JsonUInt ) ,
663665 }
664666
665667 #[ derive( Debug , Clone ) ]
@@ -724,11 +726,13 @@ mod tests {
724726 fn any_selector ( ) -> impl Strategy < Value = Selector > {
725727 prop_oneof ! [
726728 any_wildcard_child( ) ,
727- child_any( ) ,
728- any_wildcard_descendant( ) ,
729- descendant_any( ) ,
729+ any_child_name( ) ,
730730 any_array_index_child( ) ,
731+ any_array_slice_child( ) ,
732+ any_wildcard_descendant( ) ,
733+ any_descendant_name( ) ,
731734 any_array_index_descendant( ) ,
735+ any_array_slice_descendant( ) ,
732736 ]
733737 }
734738
@@ -749,18 +753,18 @@ mod tests {
749753 }
750754
751755 // .label or ['label']
752- fn child_any ( ) -> impl Strategy < Value = Selector > {
756+ fn any_child_name ( ) -> impl Strategy < Value = Selector > {
753757 prop_oneof ! [ any_short_name( ) . prop_map( |x| ( format!( ".{x}" ) , x) ) , any_name( ) , ] . prop_map ( |( s, l) | Selector {
754758 string : s,
755- tag : SelectorTag :: Child ( l) ,
759+ tag : SelectorTag :: NameChild ( l) ,
756760 } )
757761 }
758762
759763 // ..label or ..['label']
760- fn descendant_any ( ) -> impl Strategy < Value = Selector > {
764+ fn any_descendant_name ( ) -> impl Strategy < Value = Selector > {
761765 prop_oneof ! [ any_short_name( ) . prop_map( |x| ( x. clone( ) , x) ) , any_name( ) , ] . prop_map ( |( x, l) | Selector {
762766 string : format ! ( "..{x}" ) ,
763- tag : SelectorTag :: Descendant ( l) ,
767+ tag : SelectorTag :: NameDescendant ( l) ,
764768 } )
765769 }
766770
@@ -771,13 +775,45 @@ mod tests {
771775 } )
772776 }
773777
778+ fn any_array_slice_child ( ) -> impl Strategy < Value = Selector > {
779+ (
780+ any_non_negative_array_index ( ) ,
781+ proptest:: option:: of ( any_non_negative_array_index ( ) ) ,
782+ any_non_negative_array_index ( ) ,
783+ )
784+ . prop_map ( |( start, end, step) | Selector {
785+ string : if let Some ( end) = end {
786+ format ! ( "[{}:{}:{}]" , start. as_u64( ) , end. as_u64( ) , step. as_u64( ) )
787+ } else {
788+ format ! ( "[{}::{}]" , start. as_u64( ) , step. as_u64( ) )
789+ } ,
790+ tag : SelectorTag :: ArraySliceChild ( start, end, step) ,
791+ } )
792+ }
793+
774794 fn any_array_index_descendant ( ) -> impl Strategy < Value = Selector > {
775795 any_non_negative_array_index ( ) . prop_map ( |i| Selector {
776796 string : format ! ( "..[{}]" , i. as_u64( ) ) ,
777797 tag : SelectorTag :: ArrayIndexDescendant ( i) ,
778798 } )
779799 }
780800
801+ fn any_array_slice_descendant ( ) -> impl Strategy < Value = Selector > {
802+ (
803+ any_non_negative_array_index ( ) ,
804+ proptest:: option:: of ( any_non_negative_array_index ( ) ) ,
805+ any_non_negative_array_index ( ) ,
806+ )
807+ . prop_map ( |( start, end, step) | Selector {
808+ string : if let Some ( end) = end {
809+ format ! ( "..[{}:{}:{}]" , start. as_u64( ) , end. as_u64( ) , step. as_u64( ) )
810+ } else {
811+ format ! ( "..[{}::{}]" , start. as_u64( ) , step. as_u64( ) )
812+ } ,
813+ tag : SelectorTag :: ArraySliceDescendant ( start, end, step) ,
814+ } )
815+ }
816+
781817 fn any_short_name ( ) -> impl Strategy < Value = String > {
782818 r"([A-Za-z]|_|[^\u0000-\u007F])([A-Za-z0-9]|_|[^\u0000-\u007F])*"
783819 }
@@ -831,12 +867,20 @@ mod tests {
831867 result += & selector. string;
832868
833869 match selector. tag {
870+ SelectorTag :: NameChild ( name) => query. child_name( JsonString :: new( & name) ) ,
871+ SelectorTag :: ArrayIndexChild ( idx) => query. child_index( idx) ,
872+ SelectorTag :: ArraySliceChild ( start, None , step) =>
873+ query. child_slice( |x| x. with_start( start) . with_step( step) ) ,
874+ SelectorTag :: ArraySliceChild ( start, Some ( end) , step) =>
875+ query. child_slice( |x| x. with_start( start) . with_end( end) . with_step( step) ) ,
834876 SelectorTag :: WildcardChild => query. child_wildcard( ) ,
835- SelectorTag :: Child ( name) => query. child_name( JsonString :: new( & name) ) ,
877+ SelectorTag :: NameDescendant ( name) => query. descendant_name( JsonString :: new( & name) ) ,
878+ SelectorTag :: ArrayIndexDescendant ( idx) => query. descendant_index( idx) ,
879+ SelectorTag :: ArraySliceDescendant ( start, None , step) =>
880+ query. descendant_slice( |x| x. with_start( start) . with_step( step) ) ,
881+ SelectorTag :: ArraySliceDescendant ( start, Some ( end) , step) =>
882+ query. descendant_slice( |x| x. with_start( start) . with_end( end) . with_step( step) ) ,
836883 SelectorTag :: WildcardDescendant => query. descendant_wildcard( ) ,
837- SelectorTag :: Descendant ( name) => query. descendant_name( JsonString :: new( & name) ) ,
838- SelectorTag :: ArrayIndexChild ( idx) => query. child_index( idx) ,
839- SelectorTag :: ArrayIndexDescendant ( idx) => query. descendant_index( idx)
840884 } ;
841885 }
842886
@@ -855,6 +899,14 @@ mod tests {
855899
856900 assert_eq!( expected, result) ;
857901 }
902+
903+ #[ test]
904+ fn round_trip( ( _, query) in any_valid_query( ) ) {
905+ let input = query. to_string( ) ;
906+ let result = crate :: parse( & input) . expect( "expected Ok" ) ;
907+
908+ assert_eq!( query, result) ;
909+ }
858910 }
859911 }
860912 }
0 commit comments