@@ -179,7 +179,87 @@ pub fn parse_json_map(input: &RadonString, args: &Option<Vec<Value>>) -> Result<
179179 } ,
180180 _ => Err ( wrong_args ( ) )
181181 }
182+ }
183+
184+ pub fn parse_json_array ( input : & RadonString , args : & Option < Vec < Value > > ) -> Result < RadonArray , RadError > {
185+ let wrong_args = || RadError :: WrongArguments {
186+ input_type : RadonString :: radon_type_name ( ) ,
187+ operator : "ParseJsonArray" . to_string ( ) ,
188+ args : args. to_owned ( ) . unwrap_or_default ( ) ,
189+ } ;
190+
191+ let json_input: JsonValue = serde_json:: from_str ( & input. value ( ) )
192+ . map_err ( |err| RadError :: JsonParse {
193+ description : err. to_string ( ) ,
194+ } ) ?;
195+
196+ match args. to_owned ( ) . unwrap_or_default ( ) . get ( 0 ) {
197+ Some ( Value :: Array ( values) ) => {
198+ let mut items: Vec < RadonTypes > = vec ! [ ] ;
199+ for path in values {
200+ if let Value :: Text ( json_path) = path {
201+ let selector = Selector :: new ( json_path. as_str ( ) )
202+ . map_err ( |err| RadError :: JsonPathParse {
203+ description : err. to_string ( ) ,
204+ } ) ?;
205+ let mut subitems: Vec < RadonTypes > = selector. find ( & json_input)
206+ . map ( |item| into_radon_types ( item) )
207+ . collect ( ) ;
208+ if subitems. len ( ) > 1 {
209+ items. insert ( items. len ( ) , RadonArray :: from ( subitems) . into ( ) ) ;
210+ } else {
211+ items. append ( subitems. as_mut ( ) ) ;
212+ }
213+ } else {
214+ return Err ( wrong_args ( ) ) ;
215+ }
216+ }
217+ Ok ( RadonArray :: from ( items) )
218+ }
219+ Some ( Value :: Text ( json_path) ) => {
220+ let selector = Selector :: new ( json_path. as_str ( ) )
221+ . map_err ( |err| RadError :: JsonPathParse {
222+ description : err. to_string ( ) ,
223+ } ) ?;
224+ let items: Vec < RadonTypes > = selector. find ( & json_input)
225+ . map ( |item| into_radon_types ( item) )
226+ . collect ( ) ;
227+ Ok ( RadonArray :: from ( items) )
228+ }
229+ None => {
230+ RadonTypes :: try_from ( json_input) ?. try_into ( )
231+ }
232+ _ => Err ( wrong_args ( ) )
233+ }
234+ }
182235
236+ fn into_radon_types ( value : & serde_json:: Value ) -> RadonTypes {
237+ match value {
238+ serde_json:: Value :: Number ( value) => {
239+ if value. is_f64 ( ) {
240+ RadonTypes :: from ( RadonFloat :: from ( value. as_f64 ( ) . unwrap_or_default ( ) ) )
241+ } else {
242+ RadonTypes :: from ( RadonInteger :: from ( value. as_i64 ( ) . unwrap_or_default ( ) as i128 ) )
243+ }
244+ } ,
245+ serde_json:: Value :: Bool ( value) => RadonTypes :: from ( RadonBoolean :: from ( * value) ) ,
246+ serde_json:: Value :: String ( value) => RadonTypes :: from ( RadonString :: from ( value. clone ( ) ) ) ,
247+ serde_json:: Value :: Object ( entries) => {
248+ let mut object: BTreeMap < String , RadonTypes > = BTreeMap :: new ( ) ;
249+ for ( key, value) in entries {
250+ object. insert ( key. clone ( ) , into_radon_types ( value) ) ;
251+ }
252+ RadonTypes :: from ( RadonMap :: from ( object) )
253+ }
254+ serde_json:: Value :: Array ( values) => {
255+ let items: Vec < RadonTypes > = values
256+ . iter ( )
257+ . map ( |item| into_radon_types ( item) )
258+ . collect ( ) ;
259+ RadonTypes :: from ( RadonArray :: from ( items) )
260+ }
261+ _ => RadonTypes :: from ( RadonError :: new ( RadError :: JsonParse { description : value. to_string ( ) } ) )
262+ }
183263}
184264
185265fn add_children (
@@ -477,7 +557,7 @@ mod tests {
477557 #[ test]
478558 fn test_parse_json_map ( ) {
479559 let json_map = RadonString :: from ( r#"{ "Hello": "world" }"# ) ;
480- let output = parse_json_map ( & json_map) . unwrap ( ) ;
560+ let output = parse_json_map ( & json_map, & None ) . unwrap ( ) ;
481561
482562 let key = "Hello" ;
483563 let value = RadonTypes :: String ( RadonString :: from ( "world" ) ) ;
@@ -637,7 +717,7 @@ mod tests {
637717 fn test_parse_json_map_with_null_entries ( ) {
638718 // When parsing a JSON map, any keys with value `null` are ignored
639719 let json_map = RadonString :: from ( r#"{ "Hello": "world", "Bye": null }"# ) ;
640- let output = parse_json_map ( & json_map) . unwrap ( ) ;
720+ let output = parse_json_map ( & json_map, & None ) . unwrap ( ) ;
641721
642722 let key = "Hello" ;
643723 let value = RadonTypes :: String ( RadonString :: from ( "world" ) ) ;
@@ -651,15 +731,15 @@ mod tests {
651731 #[ test]
652732 fn test_parse_json_map_fail ( ) {
653733 let invalid_json = RadonString :: from ( r#"{ "Hello": }"# ) ;
654- let output = parse_json_map ( & invalid_json) . unwrap_err ( ) ;
734+ let output = parse_json_map ( & invalid_json, & None ) . unwrap_err ( ) ;
655735
656736 let expected_err = RadError :: JsonParse {
657737 description : "expected value at line 1 column 13" . to_string ( ) ,
658738 } ;
659739 assert_eq ! ( output, expected_err) ;
660740
661741 let json_array = RadonString :: from ( r#"[1,2,3]"# ) ;
662- let output = parse_json_map ( & json_array) . unwrap_err ( ) ;
742+ let output = parse_json_map ( & json_array, & None ) . unwrap_err ( ) ;
663743 let expected_err = RadError :: Decode {
664744 from : "cbor::value::Value" ,
665745 to : RadonMap :: radon_type_name ( ) ,
@@ -670,7 +750,7 @@ mod tests {
670750 #[ test]
671751 fn test_parse_json_array ( ) {
672752 let json_array = RadonString :: from ( r#"[1,2,3]"# ) ;
673- let output = parse_json_array ( & json_array) . unwrap ( ) ;
753+ let output = parse_json_array ( & json_array, & None ) . unwrap ( ) ;
674754
675755 let expected_output = RadonArray :: from ( vec ! [
676756 RadonTypes :: Integer ( RadonInteger :: from( 1 ) ) ,
@@ -685,7 +765,7 @@ mod tests {
685765 fn test_parse_json_array_with_null_entries ( ) {
686766 // When parsing a JSON array, any elements with value `null` are ignored
687767 let json_array = RadonString :: from ( r#"[null, 1, null, null, 2, 3, null]"# ) ;
688- let output = parse_json_array ( & json_array) . unwrap ( ) ;
768+ let output = parse_json_array ( & json_array, & None ) . unwrap ( ) ;
689769
690770 let expected_output = RadonArray :: from ( vec ! [
691771 RadonTypes :: Integer ( RadonInteger :: from( 1 ) ) ,
@@ -699,15 +779,15 @@ mod tests {
699779 #[ test]
700780 fn test_parse_json_array_fail ( ) {
701781 let invalid_json = RadonString :: from ( r#"{ "Hello": }"# ) ;
702- let output = parse_json_array ( & invalid_json) . unwrap_err ( ) ;
782+ let output = parse_json_array ( & invalid_json, & None ) . unwrap_err ( ) ;
703783
704784 let expected_err = RadError :: JsonParse {
705785 description : "expected value at line 1 column 13" . to_string ( ) ,
706786 } ;
707787 assert_eq ! ( output, expected_err) ;
708788
709789 let json_map = RadonString :: from ( r#"{ "Hello": "world" }"# ) ;
710- let output = parse_json_array ( & json_map) . unwrap_err ( ) ;
790+ let output = parse_json_array ( & json_map, & None ) . unwrap_err ( ) ;
711791 let expected_err = RadError :: Decode {
712792 from : "cbor::value::Value" ,
713793 to : RadonArray :: radon_type_name ( ) ,
@@ -1235,7 +1315,7 @@ mod tests {
12351315 let args = vec ! [ Value :: Map ( map) ] ;
12361316
12371317 let result = string_match ( & input_key, & args) ;
1238- assert_eq ! ( result. unwrap_err( ) . to_string( ) , "Wrong `RadonString::String match ()` arguments: `[Map({Text(\" key1\" ): Float(1.0), Text(\" key2\" ): Float(2.0)})]`" ) ;
1318+ assert_eq ! ( result. unwrap_err( ) . to_string( ) , "Wrong `RadonString::StringMatch ()` arguments: `[Map({Text(\" key1\" ): Float(1.0), Text(\" key2\" ): Float(2.0)})]`" ) ;
12391319 }
12401320
12411321 #[ test]
0 commit comments