3636
3737 fn from_map < I : IntoIterator < Item = ( Self , Self ) > > ( iter : I ) -> ValR < Self > {
3838 iter. into_iter ( ) . fold ( ValR :: Ok ( Self ( JsonLike :: object ( JsonObjectLike :: new ( ) ) ) ) , |acc, ( key, value) | {
39- let key = match JsonLike :: as_str ( & key. 0 ) {
40- Some ( key) => key,
41- None => return ValR :: Err ( jaq_core:: Error :: str ( "Key cannot be converted to String" ) ) ,
39+ let Some ( key) = JsonLike :: as_str ( & key. 0 ) else {
40+ return ValR :: Err ( jaq_core:: Error :: str ( "Key cannot be converted to String" ) )
4241 } ;
4342
4443 match acc {
@@ -58,19 +57,17 @@ where
5857
5958 fn index ( self , index : & Self ) -> ValR < Self > {
6059 if let Some ( obj) = self . 0 . as_object ( ) {
61- let key = match index. 0 . as_str ( ) {
62- Some ( key) => key,
63- None => return ValR :: Err ( jaq_core:: Error :: str ( "Key cannot be converted to String" ) )
60+ let Some ( key) = index. 0 . as_str ( ) else {
61+ return ValR :: Err ( jaq_core:: Error :: str ( "Key cannot be converted to String" ) )
6462 } ;
6563
6664 match obj. get_key ( key) {
6765 Some ( item) => ValR :: Ok ( JsonLikeHelper ( item. clone ( ) ) ) ,
6866 None => ValR :: Ok ( JsonLikeHelper ( JsonLike :: null ( ) ) ) ,
6967 }
7068 } else if let Some ( arr) = self . 0 . as_array ( ) {
71- let index: u64 = match index. 0 . as_u64 ( ) {
72- Some ( item) => item,
73- None => return ValR :: Err ( jaq_core:: Error :: str ( "Index cannot be converted to u64" ) )
69+ let Some ( index) = index. 0 . as_u64 ( ) else {
70+ return ValR :: Err ( jaq_core:: Error :: str ( "Index cannot be converted to u64" ) )
7471 } ;
7572
7673 match arr. get ( index as usize ) {
@@ -134,12 +131,53 @@ where
134131 }
135132
136133 fn map_index < ' a , I : Iterator < Item = jaq_core:: ValX < ' a , Self > > > (
137- self ,
134+ mut self ,
138135 index : & Self ,
139136 opt : jaq_core:: path:: Opt ,
140137 f : impl Fn ( Self ) -> I ,
141138 ) -> jaq_core:: ValX < ' a , Self > {
142- todo ! ( )
139+ if let Some ( obj) = self . 0 . as_object_mut ( ) {
140+ let Some ( key) = index. 0 . as_str ( ) else {
141+ return opt. fail ( self , |_v| jaq_core:: Exn :: from ( jaq_core:: Error :: str ( "Key cannot be converted to String" ) ) )
142+ } ;
143+
144+ match obj. get_key ( key) {
145+ Some ( e) => {
146+ match f ( JsonLikeHelper ( e. clone ( ) ) ) . next ( ) . transpose ( ) ? {
147+ Some ( value) => obj. insert_key ( key, value. 0 ) ,
148+ None => { obj. remove_key ( key) ; } ,
149+ }
150+ } ,
151+ None => {
152+ if let Some ( value) = f ( JsonLikeHelper ( JsonLike :: null ( ) ) ) . next ( ) . transpose ( ) ? {
153+ obj. insert_key ( key, value. 0 ) ;
154+ }
155+ } ,
156+ }
157+ Ok ( self )
158+ } else if let Some ( arr) = self . 0 . as_array_mut ( ) {
159+ let Some ( index) = index. 0 . as_u64 ( ) else {
160+ return opt. fail ( self , |_v| jaq_core:: Exn :: from ( jaq_core:: Error :: str ( "Index cannot be converted to u64" ) ) )
161+ } ;
162+ let abs_or = |i| {
163+ abs_index ( i, arr. len ( ) ) . ok_or ( jaq_core:: Error :: str ( format ! ( "index {i} out of bounds" ) ) )
164+ } ;
165+ // TODO: perform error handling
166+ let index = match abs_or ( index. try_into ( ) . unwrap ( ) ) {
167+ Ok ( index) => index,
168+ Err ( e) => return opt. fail ( self , |_v| jaq_core:: Exn :: from ( e) ) ,
169+ } ;
170+
171+ let item = arr[ index] . clone ( ) ;
172+ if let Some ( value) = f ( JsonLikeHelper ( item) ) . next ( ) . transpose ( ) ? {
173+ arr[ index] = value. 0 ;
174+ } else {
175+ arr. remove ( index) ;
176+ }
177+ Ok ( self )
178+ } else {
179+ return opt. fail ( self , |_v| jaq_core:: Exn :: from ( jaq_core:: Error :: str ( "Value is not object or array" ) ) )
180+ }
143181 }
144182
145183 fn map_range < ' a , I : Iterator < Item = jaq_core:: ValX < ' a , Self > > > (
0 commit comments