diff --git a/api/src/tests/converter_test.rs b/api/src/tests/converter_test.rs index 345f95d66b7f3..cfd042bb9a633 100644 --- a/api/src/tests/converter_test.rs +++ b/api/src/tests/converter_test.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{current_function_name, tests::new_test_context}; -use aptos_api_types::{AsConverter, MoveConverter, MoveType}; +use aptos_api_types::{new_vm_ascii_string, AsConverter, MoveConverter, MoveType}; use aptos_vm::data_cache::AsMoveResolver; use move_core_types::{ account_address::AccountAddress, @@ -27,6 +27,12 @@ async fn test_value_conversion() { assert_value_conversion(&converter, "u128", "1", VmMoveValue::U128(1)); assert_value_conversion(&converter, "bool", true, VmMoveValue::Bool(true)); assert_value_conversion(&converter, "address", "0x1", VmMoveValue::Address(address)); + assert_value_conversion( + &converter, + "0x1::ASCII::String", + "hello", + new_vm_ascii_string("hello"), + ); assert_value_conversion( &converter, "vector", diff --git a/api/types/src/convert.rs b/api/types/src/convert.rs index 308f2c77d5edb..963975c69bb98 100644 --- a/api/types/src/convert.rs +++ b/api/types/src/convert.rs @@ -442,7 +442,7 @@ impl<'a, R: MoveResolver + ?Sized> MoveConverter<'a, R> { type_tag: &TypeTag, val: Value, ) -> Result { - let layout = self.inner.get_type_layout_with_fields(type_tag)?; + let layout = self.inner.get_type_layout_with_types(type_tag)?; self.try_into_vm_value_from_layout(&layout, val) } @@ -496,14 +496,21 @@ impl<'a, R: MoveResolver + ?Sized> MoveConverter<'a, R> { layout: &MoveStructLayout, val: Value, ) -> Result { - let field_layouts = if let MoveStructLayout::WithFields(fields) = layout { - fields - } else { - bail!( - "Expecting `MoveStructLayout::WithFields, getting {:?}", - layout - ); - }; + let (struct_tag, field_layouts) = + if let MoveStructLayout::WithTypes { type_, fields } = layout { + (type_, fields) + } else { + bail!( + "Expecting `MoveStructLayout::WithTypes`, getting {:?}", + layout + ); + }; + if MoveValue::is_ascii_string(struct_tag) { + let string = val + .as_str() + .ok_or_else(|| format_err!("failed to parse ASCII::String."))?; + return Ok(new_vm_ascii_string(string)); + } let mut field_values = if let Value::Object(fields) = val { fields @@ -596,3 +603,17 @@ impl AsConverter for R { MoveConverter::new(self) } } + +pub fn new_vm_ascii_string(string: &str) -> move_core_types::value::MoveValue { + use move_core_types::value::{MoveStruct, MoveValue}; + + let byte_vector = MoveValue::Vector( + string + .as_bytes() + .iter() + .map(|byte| MoveValue::U8(*byte)) + .collect(), + ); + let move_string = MoveStruct::Runtime(vec![byte_vector]); + MoveValue::Struct(move_string) +} diff --git a/api/types/src/lib.rs b/api/types/src/lib.rs index 7b1ed1e968160..20a0e5a69d305 100644 --- a/api/types/src/lib.rs +++ b/api/types/src/lib.rs @@ -17,7 +17,7 @@ mod transaction; pub use account::AccountData; pub use address::Address; pub use bytecode::Bytecode; -pub use convert::{AsConverter, MoveConverter}; +pub use convert::{new_vm_ascii_string, AsConverter, MoveConverter}; pub use error::Error; pub use event_key::EventKey; pub use hash::HashValue;