@@ -157,23 +157,38 @@ impl jaq_all::jaq_std::ValT for RpcValue {
157157 }
158158
159159 fn as_f64 ( & self ) -> Option < f64 > {
160- todo ! ( "{}" , fn_name:: uninstantiated!( ) ) ;
160+ if let Value :: Double ( double) = self . value {
161+ Some ( double)
162+ } else {
163+ None
164+ }
161165 }
162166
163167 fn is_utf8_str ( & self ) -> bool {
164- todo ! ( "{}" , fn_name :: uninstantiated! ( ) ) ;
168+ self . is_string ( )
165169 }
166170
167171 fn as_bytes ( & self ) -> Option < & [ u8 ] > {
168- todo ! ( "{}" , fn_name:: uninstantiated!( ) ) ;
172+ if let Value :: String ( str) = & self . value {
173+ Some ( str. as_bytes ( ) )
174+ } else {
175+ None
176+ }
169177 }
170178
171- fn as_sub_str ( & self , _sub : & [ u8 ] ) -> Self {
172- todo ! ( "{}" , fn_name:: uninstantiated!( ) ) ;
179+ fn as_sub_str ( & self , sub : & [ u8 ] ) -> Self {
180+ if matches ! ( & self . value, Value :: String ( _) ) {
181+ // We do not have any fancy bytes handling, so we will just believe that the sub range
182+ // is a substring of self, and create a string out of it.
183+ String :: from_utf8_lossy ( sub) . to_string ( ) . into ( )
184+ } else {
185+ // jaq-json panics here, but I don't really like that, so if self is not a String, let's just give null.
186+ RpcValue :: null ( )
187+ }
173188 }
174189
175- fn from_utf8_bytes ( _b : impl AsRef < [ u8 ] > + Send + ' static ) -> Self {
176- todo ! ( "{}" , fn_name :: uninstantiated! ( ) ) ;
190+ fn from_utf8_bytes ( b : impl AsRef < [ u8 ] > + Send + ' static ) -> Self {
191+ String :: from_utf8_lossy ( b . as_ref ( ) ) . to_string ( ) . into ( )
177192 }
178193}
179194
@@ -241,16 +256,45 @@ impl jaq_all::jaq_core::ValT for RpcValue {
241256 }
242257 }
243258
244- fn range ( self , _range : jaq_all:: jaq_core:: val:: Range < & Self > ) -> ValR {
245- todo ! ( "{}" , fn_name:: uninstantiated!( ) ) ;
259+ fn range ( self , range : jaq_all:: jaq_core:: val:: Range < & Self > ) -> ValR {
260+ let start = range. start . map_or ( 0 , RpcValue :: as_usize) ;
261+ let end = range. end . map_or ( 0 , RpcValue :: as_usize) ;
262+ match & self . value {
263+ Value :: String ( str) => {
264+ let bytes = str. as_bytes ( ) ;
265+ bytes. get ( start..end) . map ( |bytes| String :: from_utf8_lossy ( bytes) . to_string ( ) . into ( ) ) . ok_or_else ( || Error :: typ ( self , ".." ) )
266+ }
267+ Value :: List ( lst) => {
268+ lst
269+ . get ( start..end)
270+ . map ( |new_range| new_range. to_vec ( ) . into ( ) )
271+ . ok_or_else ( || Error :: typ ( self , ".." ) )
272+ }
273+ _ => Err ( Error :: typ ( self , "" ) ) ,
274+ }
246275 }
247276
248- fn map_values < I : Iterator < Item = ValX > > (
249- self ,
250- _opt : jaq_all:: jaq_core:: path:: Opt ,
251- _f : impl Fn ( Self ) -> I ,
277+ fn map_values < I : Iterator < Item = ValX > > ( self , opt : jaq_all:: jaq_core:: path:: Opt , f : impl Fn ( Self ) -> I ,
252278 ) -> ValX {
253- todo ! ( "{}" , fn_name:: uninstantiated!( ) ) ;
279+ match self . value {
280+ Value :: List ( lst) => {
281+ lst
282+ . into_iter ( )
283+ . flat_map ( f)
284+ . collect :: < Result < Vec < _ > , _ > > ( )
285+ . map ( Into :: into)
286+ }
287+ Value :: Map ( map) => {
288+ map
289+ . into_iter ( )
290+ . filter_map ( |( k, v) | f ( v)
291+ . next ( )
292+ . map ( |v| Ok ( ( k, v?) ) ) )
293+ . collect :: < Result < BTreeMap < _ , _ > , _ > > ( )
294+ . map ( Into :: into)
295+ }
296+ v => opt. fail ( RpcValue { meta : None , value : v } , |v| jaq_all:: jaq_core:: Exn :: from ( Error :: typ ( v, "" ) ) ) ,
297+ }
254298 }
255299
256300 fn map_index < I : Iterator < Item = ValX > > (
0 commit comments