@@ -143,12 +143,38 @@ where
143143 }
144144
145145 fn map_range < ' a , I : Iterator < Item = jaq_core:: ValX < ' a , Self > > > (
146- self ,
146+ mut self ,
147147 range : jaq_core:: val:: Range < & Self > ,
148148 opt : jaq_core:: path:: Opt ,
149149 f : impl Fn ( Self ) -> I ,
150150 ) -> jaq_core:: ValX < ' a , Self > {
151- todo ! ( )
151+ if let Some ( arr) = self . 0 . as_array_mut ( ) {
152+ let len = arr. len ( ) ;
153+ let from: Result < Option < isize > , jaq_core:: Error < JsonLikeHelper < A > > > = range. start . as_ref ( ) . as_ref ( ) . map ( |i| i. as_i64 ( ) ) . flatten ( ) . map ( |v| {
154+ v. try_into ( ) . map_err ( |_| jaq_core:: Error :: str ( "From cannot be converted to isize" ) )
155+ } ) . transpose ( ) ;
156+ let upto: Result < Option < isize > , jaq_core:: Error < JsonLikeHelper < A > > > = range. end . as_ref ( ) . as_ref ( ) . map ( |i| i. as_i64 ( ) ) . flatten ( ) . map ( |v| {
157+ v. try_into ( ) . map_err ( |_| jaq_core:: Error :: str ( "From cannot be converted to isize" ) )
158+ } ) . transpose ( ) ;
159+
160+ let ( Ok ( from) , Ok ( upto) ) = ( from, upto) else {
161+ return opt. fail ( self , |_v| jaq_core:: Exn :: from ( jaq_core:: Error :: str ( "Failed to parse range" ) ) )
162+ } ;
163+
164+ let from = abs_bound ( from, len, 0 ) ;
165+ let upto = abs_bound ( upto, len, len) ;
166+
167+ let ( skip, take) = skip_take ( from, upto) ;
168+
169+ let arr_slice = arr. iter_mut ( ) . skip ( skip) . take ( take) . map ( |a| a. clone ( ) ) . collect :: < Vec < _ > > ( ) ;
170+
171+ let new_values = f ( JsonLikeHelper ( JsonLike :: array ( arr_slice) ) ) . collect :: < Result < Vec < _ > , _ > > ( ) ?;
172+
173+ arr. splice ( skip..skip + take, new_values. into_iter ( ) . map ( |a| a. 0 ) ) ;
174+ Ok ( self )
175+ } else {
176+ opt. fail ( self , |_v| jaq_core:: Exn :: from ( jaq_core:: Error :: str ( "Value is not array" ) ) )
177+ }
152178 }
153179
154180 fn as_bool ( & self ) -> bool {
@@ -171,7 +197,7 @@ where
171197 Some ( "false" )
172198 }
173199 } else {
174- // TODO: fill the rest cases
200+ // TODO: fill the rest cases if possible
175201 None
176202 }
177203 }
0 commit comments