@@ -81,7 +81,11 @@ fn convert_move_value_to_json_value(val: &MoveValue, depth: usize) -> VMResult<J
8181 // check the struct type is string
8282 // if yes, then convert move value to json string
8383 // else, execute convert function recursively
84- if is_utf8_string ( type_) {
84+ if is_json_value ( type_) {
85+ convert_json_value_to_json_value ( & fields[ 0 ] . 1 )
86+ } else if is_json_object ( type_) {
87+ convert_json_object_to_json_value ( & fields[ 0 ] . 1 )
88+ } else if is_utf8_string ( type_) {
8589 convert_string_to_json_value ( & fields[ 0 ] . 1 )
8690 } else if is_biguint ( type_) {
8791 convert_biguint_to_json_value ( & fields[ 0 ] . 1 )
@@ -124,6 +128,51 @@ fn convert_move_value_to_json_value(val: &MoveValue, depth: usize) -> VMResult<J
124128 }
125129}
126130
131+ fn bytes_from_move_value ( val : & MoveValue ) -> VMResult < Vec < u8 > > {
132+ match val {
133+ MoveValue :: Vector ( bytes_val) => bytes_val
134+ . iter ( )
135+ . map ( |byte_val| match byte_val {
136+ MoveValue :: U8 ( byte) => Ok ( * byte) ,
137+ _ => Err ( deserialization_error_with_msg ( "Expected U8 in vector" ) ) ,
138+ } )
139+ . collect :: < VMResult < Vec < u8 > > > ( ) ,
140+ _ => Err ( deserialization_error_with_msg ( "Expected vector of U8s" ) ) ,
141+ }
142+ }
143+
144+ fn convert_json_value_to_json_value ( val : & MoveValue ) -> VMResult < JSONValue > {
145+ let bz = bytes_from_move_value ( val) ?;
146+ serde_json:: from_slice ( & bz) . map_err ( deserialization_error_with_msg)
147+ }
148+
149+ fn convert_json_object_to_json_value ( val : & MoveValue ) -> VMResult < JSONValue > {
150+ let elems = match val {
151+ MoveValue :: Vector ( elems) => elems
152+ . iter ( )
153+ . map ( |elem| match elem {
154+ MoveValue :: Struct (
155+ MoveStruct :: WithTypes { type_ : _, fields }
156+ | MoveStruct :: WithFields ( fields)
157+ | MoveStruct :: WithVariantFields ( _, _, fields) ,
158+ ) => {
159+ let key =
160+ std:: str:: from_utf8 ( & bytes_from_move_value ( & fields. first ( ) . unwrap ( ) . 1 ) ?)
161+ . map_err ( deserialization_error_with_msg) ?
162+ . to_string ( ) ;
163+ let val = convert_json_value_to_json_value ( & fields. get ( 1 ) . unwrap ( ) . 1 ) ?;
164+
165+ Ok ( ( key, val) )
166+ }
167+ _ => unreachable ! ( ) ,
168+ } )
169+ . collect :: < VMResult < Map < _ , _ > > > ( ) ?,
170+ _ => unreachable ! ( ) ,
171+ } ;
172+
173+ Ok ( JSONValue :: Object ( elems) )
174+ }
175+
127176fn convert_string_to_json_value ( val : & MoveValue ) -> VMResult < JSONValue > {
128177 let bz: Vec < u8 > = match val {
129178 MoveValue :: Vector ( bytes_val) => bytes_val
@@ -232,6 +281,18 @@ fn convert_object_to_json_value(val: &MoveValue) -> VMResult<JSONValue> {
232281}
233282
234283// check functions
284+ fn is_json_value ( type_ : & StructTag ) -> bool {
285+ type_. address == CORE_CODE_ADDRESS
286+ && type_. module . as_str ( ) == "json"
287+ && type_. name . as_str ( ) == "JSONValue"
288+ }
289+
290+ fn is_json_object ( type_ : & StructTag ) -> bool {
291+ type_. address == CORE_CODE_ADDRESS
292+ && type_. module . as_str ( ) == "json"
293+ && type_. name . as_str ( ) == "JSONObject"
294+ }
295+
235296fn is_utf8_string ( type_ : & StructTag ) -> bool {
236297 type_. address == CORE_CODE_ADDRESS
237298 && type_. module . as_str ( ) == "string"
@@ -453,5 +514,105 @@ mod move_to_json_tests {
453514 } ) ;
454515 let val = convert_move_value_to_json_value ( & mv, 1 ) . unwrap ( ) ;
455516 assert_eq ! ( val, json!( addr. to_hex_literal( ) ) ) ;
517+
518+ // json value
519+ let mv = MoveValue :: Struct ( MoveStruct :: WithTypes {
520+ type_ : StructTag {
521+ address : CORE_CODE_ADDRESS ,
522+ module : ident_str ! ( "json" ) . into ( ) ,
523+ name : ident_str ! ( "JSONValue" ) . into ( ) ,
524+ type_args : vec ! [ ] ,
525+ } ,
526+ fields : vec ! [ (
527+ ident_str!( "val" ) . into( ) ,
528+ MoveValue :: Vector ( vec![
529+ MoveValue :: U8 ( 34 ) ,
530+ MoveValue :: U8 ( 109 ) ,
531+ MoveValue :: U8 ( 111 ) ,
532+ MoveValue :: U8 ( 118 ) ,
533+ MoveValue :: U8 ( 101 ) ,
534+ MoveValue :: U8 ( 34 ) ,
535+ ] ) ,
536+ ) ] ,
537+ } ) ;
538+ let val = convert_move_value_to_json_value ( & mv, 1 ) . unwrap ( ) ;
539+ assert_eq ! ( val, json!( "move" ) ) ;
540+
541+ // json object
542+ let mv = MoveValue :: Struct ( MoveStruct :: WithTypes {
543+ type_ : StructTag {
544+ address : CORE_CODE_ADDRESS ,
545+ module : ident_str ! ( "json" ) . into ( ) ,
546+ name : ident_str ! ( "JSONObject" ) . into ( ) ,
547+ type_args : vec ! [ ] ,
548+ } ,
549+ fields : vec ! [ (
550+ ident_str!( "elems" ) . into( ) ,
551+ MoveValue :: Vector ( vec![
552+ MoveValue :: Struct ( MoveStruct :: WithTypes {
553+ type_: StructTag {
554+ address: CORE_CODE_ADDRESS ,
555+ module: ident_str!( "json" ) . into( ) ,
556+ name: ident_str!( "Element" ) . into( ) ,
557+ type_args: vec![ ] ,
558+ } ,
559+ fields: vec![
560+ (
561+ ident_str!( "key" ) . into( ) ,
562+ MoveValue :: Vector ( vec![
563+ MoveValue :: U8 ( 109 ) ,
564+ MoveValue :: U8 ( 111 ) ,
565+ MoveValue :: U8 ( 118 ) ,
566+ MoveValue :: U8 ( 101 ) ,
567+ ] ) ,
568+ ) ,
569+ (
570+ ident_str!( "value" ) . into( ) ,
571+ MoveValue :: Vector ( vec![
572+ MoveValue :: U8 ( 34 ) ,
573+ MoveValue :: U8 ( 109 ) ,
574+ MoveValue :: U8 ( 111 ) ,
575+ MoveValue :: U8 ( 118 ) ,
576+ MoveValue :: U8 ( 101 ) ,
577+ MoveValue :: U8 ( 34 ) ,
578+ ] ) ,
579+ ) ,
580+ ] ,
581+ } ) ,
582+ MoveValue :: Struct ( MoveStruct :: WithTypes {
583+ type_: StructTag {
584+ address: CORE_CODE_ADDRESS ,
585+ module: ident_str!( "json" ) . into( ) ,
586+ name: ident_str!( "Element" ) . into( ) ,
587+ type_args: vec![ ] ,
588+ } ,
589+ fields: vec![
590+ (
591+ ident_str!( "key" ) . into( ) ,
592+ MoveValue :: Vector ( vec![ MoveValue :: U8 ( 102 ) ] ) ,
593+ ) ,
594+ (
595+ ident_str!( "value" ) . into( ) ,
596+ MoveValue :: Vector ( vec![
597+ MoveValue :: U8 ( 110 ) ,
598+ MoveValue :: U8 ( 117 ) ,
599+ MoveValue :: U8 ( 108 ) ,
600+ MoveValue :: U8 ( 108 ) ,
601+ ] ) ,
602+ ) ,
603+ ] ,
604+ } ) ,
605+ ] ) ,
606+ ) ] ,
607+ } ) ;
608+
609+ let val = convert_move_value_to_json_value ( & mv, 1 ) . unwrap ( ) ;
610+ assert_eq ! (
611+ val,
612+ json!( {
613+ "move" : json!( "move" ) ,
614+ "f" : json!( null) ,
615+ } )
616+ ) ;
456617 }
457618}
0 commit comments