From e1c3de33942f0e997680645941787102ebf61e85 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 16 Jan 2023 20:48:22 -0800 Subject: [PATCH] Adapt SDK to changes to {Try,}{From,Into}Val in env crates. (#824) Adapts the SDK to changes in https://github.com/stellar/rs-soroban-env/pull/628 -- this variant finally worked ok. Very minor warts, lots of code removal. --- Cargo.lock | 10 +- Cargo.toml | 6 +- soroban-auth/src/tests/test_ed25519.rs | 6 +- .../src/tests/test_ed25519_with_nonce.rs | 10 +- soroban-sdk-macros/src/derive_client.rs | 2 +- soroban-sdk-macros/src/derive_enum.rs | 81 +++----- soroban-sdk-macros/src/derive_enum_int.rs | 58 ++---- .../src/derive_error_enum_int.rs | 26 +-- soroban-sdk-macros/src/derive_fn.rs | 4 +- soroban-sdk-macros/src/derive_struct.rs | 66 ++----- soroban-sdk-macros/src/derive_struct_tuple.rs | 66 ++----- soroban-sdk/src/accounts.rs | 80 +++----- soroban-sdk/src/bytes.rs | 183 +++++------------- soroban-sdk/src/deploy.rs | 8 +- soroban-sdk/src/env.rs | 35 +++- soroban-sdk/src/events.rs | 10 +- soroban-sdk/src/lib.rs | 12 +- soroban-sdk/src/logging.rs | 2 +- soroban-sdk/src/map.rs | 84 ++------ soroban-sdk/src/serde.rs | 2 +- soroban-sdk/src/set.rs | 58 ++---- soroban-sdk/src/storage.rs | 20 +- soroban-sdk/src/tests/contract_snapshot.rs | 4 +- soroban-sdk/src/tests/contract_store.rs | 4 +- soroban-sdk/src/tests/contract_udt_enum.rs | 18 +- soroban-sdk/src/tests/contract_udt_struct.rs | 4 +- .../src/tests/contract_udt_struct_tuple.rs | 12 +- soroban-sdk/src/vec.rs | 155 +++++---------- .../src/tests/use_token_contract.rs | 8 +- tests/contract_data/src/lib.rs | 6 +- tests/errors/src/lib.rs | 4 +- tests/udt/src/lib.rs | 2 +- 32 files changed, 335 insertions(+), 711 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a90d487d..7f6dda522 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -841,7 +841,7 @@ dependencies = [ [[package]] name = "soroban-env-common" version = "0.0.12" -source = "git+https://github.com/stellar/rs-soroban-env?rev=65498c8#65498c84ccc30df302c99b50af31752f7aa087e8" +source = "git+https://github.com/stellar/rs-soroban-env?rev=993c527abce72748405d71467498bffd63e061c1#993c527abce72748405d71467498bffd63e061c1" dependencies = [ "crate-git-revision", "serde", @@ -854,7 +854,7 @@ dependencies = [ [[package]] name = "soroban-env-guest" version = "0.0.12" -source = "git+https://github.com/stellar/rs-soroban-env?rev=65498c8#65498c84ccc30df302c99b50af31752f7aa087e8" +source = "git+https://github.com/stellar/rs-soroban-env?rev=993c527abce72748405d71467498bffd63e061c1#993c527abce72748405d71467498bffd63e061c1" dependencies = [ "soroban-env-common", "static_assertions", @@ -863,7 +863,7 @@ dependencies = [ [[package]] name = "soroban-env-host" version = "0.0.12" -source = "git+https://github.com/stellar/rs-soroban-env?rev=65498c8#65498c84ccc30df302c99b50af31752f7aa087e8" +source = "git+https://github.com/stellar/rs-soroban-env?rev=993c527abce72748405d71467498bffd63e061c1#993c527abce72748405d71467498bffd63e061c1" dependencies = [ "backtrace", "curve25519-dalek", @@ -885,7 +885,7 @@ dependencies = [ [[package]] name = "soroban-env-macros" version = "0.0.12" -source = "git+https://github.com/stellar/rs-soroban-env?rev=65498c8#65498c84ccc30df302c99b50af31752f7aa087e8" +source = "git+https://github.com/stellar/rs-soroban-env?rev=993c527abce72748405d71467498bffd63e061c1#993c527abce72748405d71467498bffd63e061c1" dependencies = [ "itertools", "proc-macro2", @@ -911,7 +911,7 @@ dependencies = [ [[package]] name = "soroban-native-sdk-macros" version = "0.0.12" -source = "git+https://github.com/stellar/rs-soroban-env?rev=65498c8#65498c84ccc30df302c99b50af31752f7aa087e8" +source = "git+https://github.com/stellar/rs-soroban-env?rev=993c527abce72748405d71467498bffd63e061c1#993c527abce72748405d71467498bffd63e061c1" dependencies = [ "itertools", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index efd86e9e4..f813bc8ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,17 +37,17 @@ soroban-token-spec = { version = "0.4.3", path = "soroban-token-spec" } [workspace.dependencies.soroban-env-common] version = "0.0.12" git = "https://github.com/stellar/rs-soroban-env" -rev = "65498c8" +rev = "993c527abce72748405d71467498bffd63e061c1" [workspace.dependencies.soroban-env-guest] version = "0.0.12" git = "https://github.com/stellar/rs-soroban-env" -rev = "65498c8" +rev = "993c527abce72748405d71467498bffd63e061c1" [workspace.dependencies.soroban-env-host] version = "0.0.12" git = "https://github.com/stellar/rs-soroban-env" -rev = "65498c8" +rev = "993c527abce72748405d71467498bffd63e061c1" [workspace.dependencies.stellar-strkey] version = "0.0.6" diff --git a/soroban-auth/src/tests/test_ed25519.rs b/soroban-auth/src/tests/test_ed25519.rs index 79fa73fda..7c766f55a 100644 --- a/soroban-auth/src/tests/test_ed25519.rs +++ b/soroban-auth/src/tests/test_ed25519.rs @@ -22,7 +22,7 @@ impl ExampleContract { &env, &sig, symbol!("examplefn"), - (&sig.identifier(&env), arg1, arg2), + (sig.identifier(&env), arg1, arg2), ); } } @@ -54,7 +54,7 @@ fn test() { &signer, &contract_id, symbol!("examplefn"), - (&id, &1, &2), + (id, 1, 2), ); std::println!("signature: {:?}", sig); @@ -92,7 +92,7 @@ fn test_build_keypair() { &signer, &contract_id, symbol!("examplefn"), - (&id, &1, &2), + (id, 1, 2), ); std::println!("signature: {:?}", sig); diff --git a/soroban-auth/src/tests/test_ed25519_with_nonce.rs b/soroban-auth/src/tests/test_ed25519_with_nonce.rs index 244284f68..f6073c162 100644 --- a/soroban-auth/src/tests/test_ed25519_with_nonce.rs +++ b/soroban-auth/src/tests/test_ed25519_with_nonce.rs @@ -9,7 +9,7 @@ pub enum DataKey { fn read_nonce(e: &Env, id: &Identifier) -> i128 { let key = DataKey::Nonce(id.clone()); - e.storage().get(key).unwrap_or(Ok(0)).unwrap() + e.storage().get(&key).unwrap_or(Ok(0)).unwrap() } fn verify_and_consume_nonce(e: &Env, id: &Identifier, expected_nonce: i128) { @@ -29,7 +29,7 @@ fn verify_and_consume_nonce(e: &Env, id: &Identifier, expected_nonce: i128) { if nonce != expected_nonce { panic!("incorrect nonce") } - e.storage().set(key, &nonce + 1); + e.storage().set(&key, &(nonce + 1)); } pub struct TestContract; @@ -41,7 +41,7 @@ impl TestContract { verify_and_consume_nonce(&e, &auth_id, nonce); - verify(&e, &sig, symbol!("verify_sig"), (&auth_id, nonce)); + verify(&e, &sig, symbol!("verify_sig"), (auth_id, nonce)); } pub fn nonce(e: Env, id: Identifier) -> i128 { @@ -54,7 +54,7 @@ pub struct OuterTestContract; #[contractimpl] impl OuterTestContract { pub fn authorize(e: Env, contract_id: BytesN<32>) { - let client = TestContractClient::new(&e, contract_id); + let client = TestContractClient::new(&e, &contract_id); client.verify_sig(&Signature::Invoker, &0); } } @@ -74,7 +74,7 @@ fn test() { &signer, &contract_id, symbol!("verify_sig"), - (&id, &nonce), + (id, nonce), ); client.verify_sig(&sig, &nonce); diff --git a/soroban-sdk-macros/src/derive_client.rs b/soroban-sdk-macros/src/derive_client.rs index 40240b9ea..eea1f4161 100644 --- a/soroban-sdk-macros/src/derive_client.rs +++ b/soroban-sdk-macros/src/derive_client.rs @@ -193,7 +193,7 @@ pub fn derive_client(name: &str, fns: &[ClientFn]) -> TokenStream { } impl #client_ident { - pub fn new(env: &soroban_sdk::Env, contract_id: impl soroban_sdk::IntoVal>) -> Self { + pub fn new(env: &soroban_sdk::Env, contract_id: &impl soroban_sdk::IntoVal>) -> Self { Self { env: env.clone(), contract_id: contract_id.into_val(env), diff --git a/soroban-sdk-macros/src/derive_enum.rs b/soroban-sdk-macros/src/derive_enum.rs index 692085a50..6e4eca6c9 100644 --- a/soroban-sdk-macros/src/derive_enum.rs +++ b/soroban-sdk-macros/src/derive_enum.rs @@ -21,7 +21,7 @@ pub fn derive_type_enum( let mut errors = Vec::::new(); let variants = &data.variants; - let (spec_cases, discriminant_consts, try_froms, intos, try_from_xdrs, into_xdrs): (Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>) = variants + let (spec_cases, discriminant_consts, try_froms, try_intos, try_from_xdrs, into_xdrs): (Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>) = variants .iter() .map(|v| { // TODO: Choose discriminant type based on repr type of enum. @@ -72,7 +72,12 @@ pub fn derive_type_enum( Self::#ident(iter.next().ok_or(#path::ConversionError)??.try_into_val(env)?) } }; - let into = quote! { #enum_ident::#ident(ref value) => (#discriminant_const_sym_ident, value).into_val(env) }; + let try_into = quote! { + #enum_ident::#ident(ref value) => { + let tup: (#path::RawVal, #path::RawVal) = (#discriminant_const_sym_ident.into(), value.try_into_val(env)?); + tup.try_into_val(env) + } + }; let try_from_xdr = quote! { #name => { if iter.len() > 1 { @@ -83,7 +88,7 @@ pub fn derive_type_enum( } }; let into_xdr = quote! { #enum_ident::#ident(value) => (#name, value).try_into().map_err(|_| #path::xdr::Error::Invalid)? }; - (spec_case, discriminant_const, try_from, into, try_from_xdr, into_xdr) + (spec_case, discriminant_const, try_from, try_into, try_from_xdr, into_xdr) } else { let spec_case = ScSpecUdtUnionCaseV0 { name: name.try_into().unwrap_or_else(|_| StringM::default()), @@ -97,7 +102,12 @@ pub fn derive_type_enum( Self::#ident } }; - let into = quote! { #enum_ident::#ident => (#discriminant_const_sym_ident,).into_val(env) }; + let try_into = quote! { + #enum_ident::#ident => { + let tup: (#path::RawVal,) = (#discriminant_const_sym_ident.into(),); + tup.try_into_val(env) + } + }; let try_from_xdr = quote! { #name => { if iter.len() > 0 { @@ -107,7 +117,7 @@ pub fn derive_type_enum( } }; let into_xdr = quote! { #enum_ident::#ident => (#name,).try_into().map_err(|_| #path::xdr::Error::Invalid)? }; - (spec_case, discriminant_const, try_from, into, try_from_xdr, into_xdr) + (spec_case, discriminant_const, try_from, try_into, try_from_xdr, into_xdr) } }) .multiunzip(); @@ -150,7 +160,7 @@ pub fn derive_type_enum( impl #path::TryFromVal<#path::Env, #path::RawVal> for #enum_ident { type Error = #path::ConversionError; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::RawVal) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::RawVal) -> Result { use #path::TryIntoVal; #(#discriminant_consts)* let vec: #path::Vec<#path::RawVal> = val.try_into_val(env)?; @@ -163,30 +173,14 @@ pub fn derive_type_enum( } } - impl #path::TryIntoVal<#path::Env, #enum_ident> for #path::RawVal { + impl #path::TryFromVal<#path::Env, #enum_ident> for #path::RawVal { type Error = #path::ConversionError; #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#enum_ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - - impl #path::IntoVal<#path::Env, #path::RawVal> for #enum_ident { - #[inline(always)] - fn into_val(self, env: &#path::Env) -> #path::RawVal { - #(#discriminant_consts)* - match &self { - #(#intos,)* - } - } - } - - impl #path::IntoVal<#path::Env, #path::RawVal> for &#enum_ident { - #[inline(always)] - fn into_val(self, env: &#path::Env) -> #path::RawVal { + fn try_from_val(env: &#path::Env, val: &#enum_ident) -> Result { + use #path::TryIntoVal; #(#discriminant_consts)* - match self { - #(#intos,)* + match val { + #(#try_intos,)* } } } @@ -195,7 +189,7 @@ pub fn derive_type_enum( impl #path::TryFromVal<#path::Env, #path::xdr::ScVec> for #enum_ident { type Error = #path::xdr::Error; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::xdr::ScVec) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::xdr::ScVec) -> Result { use #path::xdr::Validate; use #path::TryIntoVal; @@ -211,20 +205,11 @@ pub fn derive_type_enum( } } - #[cfg(any(test, feature = "testutils"))] - impl #path::TryIntoVal<#path::Env, #enum_ident> for #path::xdr::ScVec { - type Error = #path::xdr::Error; - #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#enum_ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - #[cfg(any(test, feature = "testutils"))] impl #path::TryFromVal<#path::Env, #path::xdr::ScObject> for #enum_ident { type Error = #path::xdr::Error; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::xdr::ScObject) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::xdr::ScObject) -> Result { if let #path::xdr::ScObject::Vec(vec) = val { <_ as #path::TryFromVal<_, _>>::try_from_val(env, vec) } else { @@ -233,20 +218,11 @@ pub fn derive_type_enum( } } - #[cfg(any(test, feature = "testutils"))] - impl #path::TryIntoVal<#path::Env, #enum_ident> for #path::xdr::ScObject { - type Error = #path::xdr::Error; - #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#enum_ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - #[cfg(any(test, feature = "testutils"))] impl #path::TryFromVal<#path::Env, #path::xdr::ScVal> for #enum_ident { type Error = #path::xdr::Error; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::xdr::ScVal) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::xdr::ScVal) -> Result { if let #path::xdr::ScVal::Object(Some(obj)) = val { <_ as #path::TryFromVal<_, _>>::try_from_val(env, obj) } else { @@ -255,15 +231,6 @@ pub fn derive_type_enum( } } - #[cfg(any(test, feature = "testutils"))] - impl #path::TryIntoVal<#path::Env, #enum_ident> for #path::xdr::ScVal { - type Error = #path::xdr::Error; - #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#enum_ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - #[cfg(any(test, feature = "testutils"))] impl TryInto<#path::xdr::ScVec> for &#enum_ident { type Error = #path::xdr::Error; diff --git a/soroban-sdk-macros/src/derive_enum_int.rs b/soroban-sdk-macros/src/derive_enum_int.rs index ce2977887..10b27bc0f 100644 --- a/soroban-sdk-macros/src/derive_enum_int.rs +++ b/soroban-sdk-macros/src/derive_enum_int.rs @@ -19,7 +19,7 @@ pub fn derive_type_enum_int( let mut errors = Vec::::new(); let variants = &data.variants; - let (spec_cases, try_froms, intos): (Vec<_>, Vec<_>, Vec<_>) = variants + let (spec_cases, try_froms, try_intos): (Vec<_>, Vec<_>, Vec<_>) = variants .iter() .map(|v| { let ident = &v.ident; @@ -48,8 +48,8 @@ pub fn derive_type_enum_int( value: discriminant, }; let try_from = quote! { #discriminant => Self::#ident }; - let into = quote! { #enum_ident::#ident => #discriminant.into_val(env) }; - (spec_case, try_from, into) + let try_into = quote! { #enum_ident::#ident => #discriminant.into() }; + (spec_case, try_from, try_into) }) .multiunzip(); @@ -91,7 +91,7 @@ pub fn derive_type_enum_int( impl #path::TryFromVal<#path::Env, #path::RawVal> for #enum_ident { type Error = #path::ConversionError; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::RawVal) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::RawVal) -> Result { use #path::TryIntoVal; let discriminant: u32 = val.try_into_val(env)?; Ok(match discriminant { @@ -101,51 +101,29 @@ pub fn derive_type_enum_int( } } - impl #path::TryIntoVal<#path::Env, #enum_ident> for #path::RawVal { + impl #path::TryFromVal<#path::Env, #enum_ident> for #path::RawVal { type Error = #path::ConversionError; #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#enum_ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - - impl #path::IntoVal<#path::Env, #path::RawVal> for #enum_ident { - #[inline(always)] - fn into_val(self, env: &#path::Env) -> #path::RawVal { - match &self { - #(#intos,)* - } - } - } - - impl #path::IntoVal<#path::Env, #path::RawVal> for &#enum_ident { - #[inline(always)] - fn into_val(self, env: &#path::Env) -> #path::RawVal { - match self { - #(#intos,)* - } - } - } - - #[cfg(any(test, feature = "testutils"))] - impl #path::TryFromVal<#path::Env, #path::xdr::ScVal> for #enum_ident { - type Error = #path::xdr::Error; - #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::xdr::ScVal) -> Result { - let discriminant: u32 = val.try_into().map_err(|_| #path::xdr::Error::Invalid)?; - Ok(match discriminant { - #(#try_froms,)* - _ => Err(#path::xdr::Error::Invalid)?, + fn try_from_val(env: &#path::Env, val: &#enum_ident) -> Result { + Ok(match val { + #(#try_intos,)* }) } } #[cfg(any(test, feature = "testutils"))] - impl #path::TryIntoVal<#path::Env, #enum_ident> for #path::xdr::ScVal { + impl #path::TryFromVal<#path::Env, #path::xdr::ScVal> for #enum_ident { type Error = #path::xdr::Error; #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#enum_ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) + fn try_from_val(env: &#path::Env, val: &#path::xdr::ScVal) -> Result { + if let #path::xdr::ScVal::U32(discriminant) = val { + Ok(match *discriminant { + #(#try_froms,)* + _ => Err(#path::xdr::Error::Invalid)?, + }) + } else { + Err(#path::xdr::Error::Invalid) + } } } diff --git a/soroban-sdk-macros/src/derive_error_enum_int.rs b/soroban-sdk-macros/src/derive_error_enum_int.rs index 497c636a9..58911d6bd 100644 --- a/soroban-sdk-macros/src/derive_error_enum_int.rs +++ b/soroban-sdk-macros/src/derive_error_enum_int.rs @@ -128,34 +128,18 @@ pub fn derive_type_error_enum_int( impl #path::TryFromVal<#path::Env, #path::RawVal> for #enum_ident { type Error = #path::ConversionError; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::RawVal) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::RawVal) -> Result { use #path::TryIntoVal; let status: #path::Status = val.try_into_val(env)?; status.try_into().map_err(|_| #path::ConversionError) } } - - impl #path::TryIntoVal<#path::Env, #enum_ident> for #path::RawVal { + impl #path::TryFromVal<#path::Env, #enum_ident> for #path::RawVal { type Error = #path::ConversionError; #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#enum_ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - - impl #path::IntoVal<#path::Env, #path::RawVal> for #enum_ident { - #[inline(always)] - fn into_val(self, env: &#path::Env) -> #path::RawVal { - let status: #path::Status = self.into(); - status.into_val(env) - } - } - - impl #path::IntoVal<#path::Env, #path::RawVal> for &#enum_ident { - #[inline(always)] - fn into_val(self, env: &#path::Env) -> #path::RawVal { - let status: #path::Status = self.into(); - status.into_val(env) + fn try_from_val(env: &#path::Env, val: &#enum_ident) -> Result { + let status: #path::Status = val.into(); + Ok(status.into()) } } } diff --git a/soroban-sdk-macros/src/derive_fn.rs b/soroban-sdk-macros/src/derive_fn.rs index 53e14c237..310a0291f 100644 --- a/soroban-sdk-macros/src/derive_fn.rs +++ b/soroban-sdk-macros/src/derive_fn.rs @@ -95,7 +95,7 @@ pub fn derive_fn( <_ as soroban_sdk::unwrap::UnwrapOptimized>::unwrap_optimized( <_ as soroban_sdk::TryFromVal>::try_from_val( &env, - #ident + &#ident ) ) }; @@ -202,7 +202,7 @@ pub fn derive_fn( #use_trait; <_ as soroban_sdk::IntoVal>::into_val( #[allow(deprecated)] - #call( + &#call( #env_call #(#wrap_calls),* ), diff --git a/soroban-sdk-macros/src/derive_struct.rs b/soroban-sdk-macros/src/derive_struct.rs index 7a045c3c8..5b3b97c6a 100644 --- a/soroban-sdk-macros/src/derive_struct.rs +++ b/soroban-sdk-macros/src/derive_struct.rs @@ -33,7 +33,7 @@ pub fn derive_type_struct( )); 0 }); - let (spec_fields, try_froms, intos, try_from_xdrs, into_xdrs): (Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>) = fields + let (spec_fields, try_froms, try_intos, try_from_xdrs, into_xdrs): (Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>) = fields .iter() .enumerate() .map(|(_, f)| { @@ -60,7 +60,7 @@ pub fn derive_type_struct( Err(#path::ConversionError)? } }; - let into = quote! { map.set(#map_key, (&self.#ident).into_val(env)) }; + let try_into = quote! { map.set(#map_key, (&val.#ident).try_into_val(env)?) }; let try_from_xdr = quote! { #ident: { let key = &#name.try_into().map_err(|_| #path::xdr::Error::Invalid)?; @@ -75,7 +75,7 @@ pub fn derive_type_struct( val: (&self.#ident).try_into().map_err(|_| #path::xdr::Error::Invalid)?, } }; - (spec_field, try_from, into, try_from_xdr, into_xdr) + (spec_field, try_from, try_into, try_from_xdr, into_xdr) }) .multiunzip(); @@ -117,7 +117,7 @@ pub fn derive_type_struct( impl #path::TryFromVal<#path::Env, #path::RawVal> for #ident { type Error = #path::ConversionError; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::RawVal) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::RawVal) -> Result { use #path::TryIntoVal; let map: #path::Map<#path::Symbol, #path::RawVal> = val.try_into_val(env)?; if map.len() != #field_count_u32 { @@ -129,29 +129,14 @@ pub fn derive_type_struct( } } - impl #path::TryIntoVal<#path::Env, #ident> for #path::RawVal { + impl #path::TryFromVal<#path::Env, #ident> for #path::RawVal { type Error = #path::ConversionError; #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - - impl #path::IntoVal<#path::Env, #path::RawVal> for #ident { - #[inline(always)] - fn into_val(self, env: &#path::Env) -> #path::RawVal { - let mut map = #path::Map::<#path::Symbol, #path::RawVal>::new(env); - #(#intos;)* - map.into() - } - } - - impl #path::IntoVal<#path::Env, #path::RawVal> for &#ident { - #[inline(always)] - fn into_val(self, env: &#path::Env) -> #path::RawVal { + fn try_from_val(env: &#path::Env, val: &#ident) -> Result { + use #path::TryIntoVal; let mut map = #path::Map::<#path::Symbol, #path::RawVal>::new(env); - #(#intos;)* - map.into() + #(#try_intos;)* + Ok(map.into()) } } @@ -159,7 +144,7 @@ pub fn derive_type_struct( impl #path::TryFromVal<#path::Env, #path::xdr::ScMap> for #ident { type Error = #path::xdr::Error; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::xdr::ScMap) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::xdr::ScMap) -> Result { use #path::xdr::Validate; use #path::TryIntoVal; let map = val; @@ -173,20 +158,11 @@ pub fn derive_type_struct( } } - #[cfg(any(test, feature = "testutils"))] - impl #path::TryIntoVal<#path::Env, #ident> for #path::xdr::ScMap { - type Error = #path::xdr::Error; - #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - #[cfg(any(test, feature = "testutils"))] impl #path::TryFromVal<#path::Env, #path::xdr::ScObject> for #ident { type Error = #path::xdr::Error; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::xdr::ScObject) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::xdr::ScObject) -> Result { if let #path::xdr::ScObject::Map(map) = val { <_ as #path::TryFromVal<_, _>>::try_from_val(env, map) } else { @@ -195,20 +171,11 @@ pub fn derive_type_struct( } } - #[cfg(any(test, feature = "testutils"))] - impl #path::TryIntoVal<#path::Env, #ident> for #path::xdr::ScObject { - type Error = #path::xdr::Error; - #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - #[cfg(any(test, feature = "testutils"))] impl #path::TryFromVal<#path::Env, #path::xdr::ScVal> for #ident { type Error = #path::xdr::Error; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::xdr::ScVal) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::xdr::ScVal) -> Result { if let #path::xdr::ScVal::Object(Some(obj)) = val { <_ as #path::TryFromVal<_, _>>::try_from_val(env, obj) } else { @@ -217,15 +184,6 @@ pub fn derive_type_struct( } } - #[cfg(any(test, feature = "testutils"))] - impl #path::TryIntoVal<#path::Env, #ident> for #path::xdr::ScVal { - type Error = #path::xdr::Error; - #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - #[cfg(any(test, feature = "testutils"))] impl TryInto<#path::xdr::ScMap> for &#ident { type Error = #path::xdr::Error; diff --git a/soroban-sdk-macros/src/derive_struct_tuple.rs b/soroban-sdk-macros/src/derive_struct_tuple.rs index 845d3ee90..87a6d169e 100644 --- a/soroban-sdk-macros/src/derive_struct_tuple.rs +++ b/soroban-sdk-macros/src/derive_struct_tuple.rs @@ -28,7 +28,7 @@ pub fn derive_type_struct_tuple( )); 0 }); - let (spec_fields, try_froms, intos, try_from_xdrs, into_xdrs): (Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>) = fields + let (spec_fields, try_froms, try_intos, try_from_xdrs, into_xdrs): (Vec<_>, Vec<_>, Vec<_>, Vec<_>, Vec<_>) = fields .iter() .enumerate() .map(|(i, f)| { @@ -53,7 +53,7 @@ pub fn derive_type_struct_tuple( Err(#path::ConversionError)? } }; - let into = quote! { vec.push_back((&self.#ident).into_val(env)) }; + let try_into = quote! { vec.push_back((&val.#ident).try_into_val(env)?) }; let try_from_xdr = quote! { #ident: { let rv: #path::RawVal = (&vec[#ident].clone()).try_into_val(env).map_err(|_| #path::xdr::Error::Invalid)?; @@ -63,7 +63,7 @@ pub fn derive_type_struct_tuple( let into_xdr = quote! { (&self.#ident).try_into().map_err(|_| #path::xdr::Error::Invalid)? }; - (spec_field, try_from, into, try_from_xdr, into_xdr) + (spec_field, try_from, try_into, try_from_xdr, into_xdr) }) .multiunzip(); @@ -105,7 +105,7 @@ pub fn derive_type_struct_tuple( impl #path::TryFromVal<#path::Env, #path::RawVal> for #ident { type Error = #path::ConversionError; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::RawVal) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::RawVal) -> Result { use #path::TryIntoVal; let vec: #path::Vec<#path::RawVal> = val.try_into_val(env)?; if vec.len() != #field_count_u32 { @@ -117,29 +117,14 @@ pub fn derive_type_struct_tuple( } } - impl #path::TryIntoVal<#path::Env, #ident> for #path::RawVal { + impl #path::TryFromVal<#path::Env, #ident> for #path::RawVal { type Error = #path::ConversionError; #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - - impl #path::IntoVal<#path::Env, #path::RawVal> for #ident { - #[inline(always)] - fn into_val(self, env: &#path::Env) -> #path::RawVal { - let mut vec = #path::Vec::<#path::RawVal>::new(env); - #(#intos;)* - vec.into() - } - } - - impl #path::IntoVal<#path::Env, #path::RawVal> for &#ident { - #[inline(always)] - fn into_val(self, env: &#path::Env) -> #path::RawVal { + fn try_from_val(env: &#path::Env, val: &#ident) -> Result { + use #path::TryIntoVal; let mut vec = #path::Vec::<#path::RawVal>::new(env); - #(#intos;)* - vec.into() + #(#try_intos;)* + Ok(vec.into()) } } @@ -147,7 +132,7 @@ pub fn derive_type_struct_tuple( impl #path::TryFromVal<#path::Env, #path::xdr::ScVec> for #ident { type Error = #path::xdr::Error; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::xdr::ScVec) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::xdr::ScVec) -> Result { use #path::xdr::Validate; use #path::TryIntoVal; let vec = val; @@ -160,20 +145,11 @@ pub fn derive_type_struct_tuple( } } - #[cfg(any(test, feature = "testutils"))] - impl #path::TryIntoVal<#path::Env, #ident> for #path::xdr::ScVec { - type Error = #path::xdr::Error; - #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - #[cfg(any(test, feature = "testutils"))] impl #path::TryFromVal<#path::Env, #path::xdr::ScObject> for #ident { type Error = #path::xdr::Error; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::xdr::ScObject) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::xdr::ScObject) -> Result { if let #path::xdr::ScObject::Vec(map) = val { <_ as #path::TryFromVal<_, _>>::try_from_val(env, map) } else { @@ -182,20 +158,11 @@ pub fn derive_type_struct_tuple( } } - #[cfg(any(test, feature = "testutils"))] - impl #path::TryIntoVal<#path::Env, #ident> for #path::xdr::ScObject { - type Error = #path::xdr::Error; - #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - #[cfg(any(test, feature = "testutils"))] impl #path::TryFromVal<#path::Env, #path::xdr::ScVal> for #ident { type Error = #path::xdr::Error; #[inline(always)] - fn try_from_val(env: &#path::Env, val: #path::xdr::ScVal) -> Result { + fn try_from_val(env: &#path::Env, val: &#path::xdr::ScVal) -> Result { if let #path::xdr::ScVal::Object(Some(obj)) = val { <_ as #path::TryFromVal<_, _>>::try_from_val(env, obj) } else { @@ -204,15 +171,6 @@ pub fn derive_type_struct_tuple( } } - #[cfg(any(test, feature = "testutils"))] - impl #path::TryIntoVal<#path::Env, #ident> for #path::xdr::ScVal { - type Error = #path::xdr::Error; - #[inline(always)] - fn try_into_val(self, env: &#path::Env) -> Result<#ident, Self::Error> { - <_ as #path::TryFromVal<_, _>>::try_from_val(env, self) - } - } - #[cfg(any(test, feature = "testutils"))] impl TryInto<#path::xdr::ScVec> for &#ident { type Error = #path::xdr::Error; diff --git a/soroban-sdk/src/accounts.rs b/soroban-sdk/src/accounts.rs index 5e341555d..b95b2f118 100644 --- a/soroban-sdk/src/accounts.rs +++ b/soroban-sdk/src/accounts.rs @@ -6,9 +6,15 @@ use core::{cmp::Ordering, fmt::Debug}; use crate::{ env::internal::xdr, env::internal::{Env as _, EnvBase as _, RawVal, RawValConvertible}, - BytesN, ConversionError, Env, IntoVal, Object, TryFromVal, TryIntoVal, + BytesN, ConversionError, Env, Object, TryFromVal, }; +#[cfg(any(test, feature = "testutils"))] +use crate::IntoVal; + +#[cfg(any(test, feature = "testutils", not(target_family = "wasm")))] +use crate::TryIntoVal; + /// Accounts retrieves information about accounts that exist in the current /// ledger. /// @@ -122,11 +128,11 @@ impl Ord for AccountId { impl TryFromVal for AccountId { type Error = ConversionError; - fn try_from_val(env: &Env, obj: Object) -> Result { + fn try_from_val(env: &Env, obj: &Object) -> Result { if obj.is_obj_type(xdr::ScObjectType::AccountId) { Ok(AccountId { env: env.clone(), - obj, + obj: *obj, }) } else { Err(ConversionError {}) @@ -134,51 +140,27 @@ impl TryFromVal for AccountId { } } -impl TryIntoVal for Object { - type Error = >::Error; - - fn try_into_val(self, env: &Env) -> Result { - <_ as TryFromVal<_, Object>>::try_from_val(env, self) - } -} - impl TryFromVal for AccountId { type Error = >::Error; - fn try_from_val(env: &Env, val: RawVal) -> Result { - <_ as TryFromVal<_, Object>>::try_from_val(env, val.try_into()?) + fn try_from_val(env: &Env, val: &RawVal) -> Result { + <_ as TryFromVal<_, Object>>::try_from_val(env, &val.try_into()?) } } -impl TryIntoVal for RawVal { - type Error = >::Error; - - fn try_into_val(self, env: &Env) -> Result { - <_ as TryFromVal<_, RawVal>>::try_from_val(env, self) - } -} - -impl IntoVal for AccountId { - fn into_val(self, _env: &Env) -> Object { - self.to_object() - } -} +impl TryFromVal for Object { + type Error = ConversionError; -impl IntoVal for &AccountId { - fn into_val(self, _env: &Env) -> Object { - self.to_object() + fn try_from_val(_env: &Env, v: &AccountId) -> Result { + Ok(v.to_object()) } } -impl IntoVal for AccountId { - fn into_val(self, _env: &Env) -> RawVal { - self.to_raw() - } -} +impl TryFromVal for RawVal { + type Error = >::Error; -impl IntoVal for &AccountId { - fn into_val(self, _env: &Env) -> RawVal { - self.to_raw() + fn try_from_val(_env: &Env, v: &AccountId) -> Result { + Ok(v.to_raw()) } } @@ -189,7 +171,7 @@ use super::xdr::ScVal; impl TryFrom<&AccountId> for ScVal { type Error = ConversionError; fn try_from(v: &AccountId) -> Result { - ScVal::try_from_val(&v.env, v.obj.to_raw()) + ScVal::try_from_val(&v.env, &v.obj.to_raw()) } } @@ -221,10 +203,10 @@ impl TryFrom for super::xdr::AccountId { #[cfg(not(target_family = "wasm"))] impl TryFromVal for AccountId { type Error = ConversionError; - fn try_from_val(env: &Env, val: ScVal) -> Result { + fn try_from_val(env: &Env, val: &ScVal) -> Result { <_ as TryFromVal<_, Object>>::try_from_val( env, - val.try_into_val(env).map_err(|_| ConversionError)?, + &val.try_into_val(env).map_err(|_| ConversionError)?, ) } } @@ -232,28 +214,12 @@ impl TryFromVal for AccountId { #[cfg(not(target_family = "wasm"))] impl TryFromVal for AccountId { type Error = ConversionError; - fn try_from_val(env: &Env, val: super::xdr::AccountId) -> Result { + fn try_from_val(env: &Env, val: &super::xdr::AccountId) -> Result { let val: ScVal = val.try_into()?; val.try_into_val(env).map_err(|_| ConversionError) } } -#[cfg(not(target_family = "wasm"))] -impl TryIntoVal for ScVal { - type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result { - AccountId::try_from_val(env, self) - } -} - -#[cfg(not(target_family = "wasm"))] -impl TryIntoVal for super::xdr::AccountId { - type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result { - AccountId::try_from_val(env, self) - } -} - impl AccountId { pub(crate) unsafe fn unchecked_new(env: Env, obj: Object) -> Self { Self { env, obj } diff --git a/soroban-sdk/src/bytes.rs b/soroban-sdk/src/bytes.rs index 446dd8bd2..0596a3396 100644 --- a/soroban-sdk/src/bytes.rs +++ b/soroban-sdk/src/bytes.rs @@ -10,7 +10,7 @@ use super::{ env::internal::{Env as _, EnvBase as _, RawValConvertible}, env::IntoVal, xdr::ScObjectType, - ConversionError, Env, Object, RawVal, TryFromVal, TryIntoVal, + ConversionError, Env, Object, RawVal, TryFromVal, }; use crate::unwrap::UnwrapOptimized; @@ -18,7 +18,7 @@ use crate::unwrap::UnwrapOptimized; use crate::{storage::Storage, Map, Vec}; #[cfg(not(target_family = "wasm"))] -use super::xdr::ScVal; +use super::{xdr::ScVal, TryIntoVal}; /// Create a [Bytes] with an array, or an integer or hex literal. /// @@ -163,24 +163,20 @@ impl Ord for Bytes { } } -impl IntoVal for Bytes { - fn into_val(self, _env: &Env) -> Bytes { - self - } -} +impl TryFromVal for Bytes { + type Error = ConversionError; -impl IntoVal for &Bytes { - fn into_val(self, _env: &Env) -> Bytes { - self.clone() + fn try_from_val(_env: &Env, v: &Bytes) -> Result { + Ok(v.clone()) } } impl TryFromVal for Bytes { type Error = ConversionError; - fn try_from_val(env: &Env, val: Object) -> Result { + fn try_from_val(env: &Env, val: &Object) -> Result { if val.is_obj_type(ScObjectType::Bytes) { - Ok(unsafe { Bytes::unchecked_new(env.clone(), val) }) + Ok(unsafe { Bytes::unchecked_new(env.clone(), *val) }) } else { Err(ConversionError {}) } @@ -190,36 +186,16 @@ impl TryFromVal for Bytes { impl TryFromVal for Bytes { type Error = >::Error; - fn try_from_val(env: &Env, val: RawVal) -> Result { - <_ as TryFromVal<_, Object>>::try_from_val(env, val.try_into()?) + fn try_from_val(env: &Env, val: &RawVal) -> Result { + <_ as TryFromVal<_, Object>>::try_from_val(env, &val.try_into()?) } } -impl TryIntoVal for Object { +impl TryFromVal for RawVal { type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result { - <_ as TryFromVal<_, _>>::try_from_val(env, self) - } -} - -impl TryIntoVal for RawVal { - type Error = ConversionError; - - fn try_into_val(self, env: &Env) -> Result { - <_ as TryFromVal<_, _>>::try_from_val(env, self) - } -} - -impl IntoVal for Bytes { - fn into_val(self, _env: &Env) -> RawVal { - self.into() - } -} - -impl IntoVal for &Bytes { - fn into_val(self, _env: &Env) -> RawVal { - self.to_raw() + fn try_from_val(_env: &Env, v: &Bytes) -> Result { + Ok(v.to_raw()) } } @@ -255,7 +231,7 @@ impl From<&Bytes> for Bytes { impl TryFrom<&Bytes> for ScVal { type Error = ConversionError; fn try_from(v: &Bytes) -> Result { - ScVal::try_from_val(&v.env, v.obj.to_raw()) + ScVal::try_from_val(&v.env, &v.obj.to_raw()) } } @@ -270,43 +246,34 @@ impl TryFrom for ScVal { #[cfg(not(target_family = "wasm"))] impl TryFromVal for Bytes { type Error = ConversionError; - fn try_from_val(env: &Env, val: ScVal) -> Result { + fn try_from_val(env: &Env, val: &ScVal) -> Result { <_ as TryFromVal<_, Object>>::try_from_val( env, - val.try_into_val(env).map_err(|_| ConversionError)?, + &val.try_into_val(env).map_err(|_| ConversionError)?, ) } } - -#[cfg(not(target_family = "wasm"))] -impl TryIntoVal for ScVal { +impl TryFromVal for Bytes { type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result { - Bytes::try_from_val(env, self) - } -} -impl IntoVal for &str { - fn into_val(self, env: &Env) -> Bytes { - Bytes::from_slice(env, self.as_bytes()) + fn try_from_val(env: &Env, v: &&str) -> Result { + Ok(Bytes::from_slice(env, v.as_bytes())) } } -impl IntoVal for &[u8] { - fn into_val(self, env: &Env) -> Bytes { - Bytes::from_slice(env, self) - } -} +impl TryFromVal for Bytes { + type Error = ConversionError; -impl IntoVal for [u8; N] { - fn into_val(self, env: &Env) -> Bytes { - Bytes::from_array(env, &self) + fn try_from_val(env: &Env, v: &&[u8]) -> Result { + Ok(Bytes::from_slice(env, *v)) } } -impl IntoVal for &[u8; N] { - fn into_val(self, env: &Env) -> Bytes { - Bytes::from_array(env, self) +impl TryFromVal for Bytes { + type Error = ConversionError; + + fn try_from_val(env: &Env, v: &[u8; N]) -> Result { + Ok(Bytes::from_array(env, v)) } } @@ -755,58 +722,42 @@ impl AsRef for BytesN { } } -impl IntoVal> for BytesN { - fn into_val(self, _env: &Env) -> BytesN { - self - } -} +impl TryFromVal> for BytesN { + type Error = ConversionError; -impl IntoVal> for &BytesN { - fn into_val(self, _env: &Env) -> BytesN { - self.clone() + fn try_from_val(_env: &Env, v: &BytesN) -> Result { + Ok(v.clone()) } } -impl IntoVal for BytesN { - fn into_val(self, _env: &Env) -> Bytes { - self.0 - } -} +impl TryFromVal> for Bytes { + type Error = ConversionError; -impl IntoVal for &BytesN { - fn into_val(self, _env: &Env) -> Bytes { - self.0.clone() + fn try_from_val(_env: &Env, v: &BytesN) -> Result { + Ok(v.0.clone()) } } -impl IntoVal> for [u8; N] { - fn into_val(self, env: &Env) -> BytesN { - BytesN::from_array(env, &self) - } -} +impl TryFromVal for BytesN { + type Error = ConversionError; -impl IntoVal> for &[u8; N] { - fn into_val(self, env: &Env) -> BytesN { - BytesN::from_array(env, self) + fn try_from_val(env: &Env, v: &[u8; N]) -> Result { + Ok(BytesN::from_array(env, v)) } } -impl IntoVal for BytesN { - fn into_val(self, _env: &Env) -> [u8; N] { - self.to_array() - } -} +impl TryFromVal> for [u8; N] { + type Error = ConversionError; -impl IntoVal for &BytesN { - fn into_val(self, _env: &Env) -> [u8; N] { - self.to_array() + fn try_from_val(_env: &Env, v: &BytesN) -> Result { + Ok(v.to_array()) } } impl TryFromVal for BytesN { type Error = ConversionError; - fn try_from_val(env: &Env, val: Object) -> Result { + fn try_from_val(env: &Env, val: &Object) -> Result { Bytes::try_from_val(env, val)?.try_into() } } @@ -814,36 +765,16 @@ impl TryFromVal for BytesN { impl TryFromVal for BytesN { type Error = ConversionError; - fn try_from_val(env: &Env, val: RawVal) -> Result { - <_ as TryFromVal<_, Object>>::try_from_val(env, val.try_into()?) - } -} - -impl TryIntoVal> for Object { - type Error = ConversionError; - - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - <_ as TryFromVal<_, _>>::try_from_val(env, self) + fn try_from_val(env: &Env, val: &RawVal) -> Result { + <_ as TryFromVal<_, Object>>::try_from_val(env, &val.try_into()?) } } -impl TryIntoVal> for RawVal { +impl TryFromVal> for RawVal { type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - <_ as TryFromVal<_, _>>::try_from_val(env, self) - } -} - -impl IntoVal for BytesN { - fn into_val(self, _env: &Env) -> RawVal { - self.into() - } -} - -impl IntoVal for &BytesN { - fn into_val(self, _env: &Env) -> RawVal { - self.to_raw() + fn try_from_val(_env: &Env, v: &BytesN) -> Result { + Ok(v.to_raw()) } } @@ -894,7 +825,7 @@ impl From<&BytesN> for Bytes { impl TryFrom<&BytesN> for ScVal { type Error = ConversionError; fn try_from(v: &BytesN) -> Result { - ScVal::try_from_val(&v.0.env, v.0.obj.to_raw()) + ScVal::try_from_val(&v.0.env, &v.0.obj.to_raw()) } } @@ -909,22 +840,14 @@ impl TryFrom> for ScVal { #[cfg(not(target_family = "wasm"))] impl TryFromVal for BytesN { type Error = ConversionError; - fn try_from_val(env: &Env, val: ScVal) -> Result { + fn try_from_val(env: &Env, val: &ScVal) -> Result { <_ as TryFromVal<_, Object>>::try_from_val( env, - val.try_into_val(env).map_err(|_| ConversionError)?, + &val.try_into_val(env).map_err(|_| ConversionError)?, ) } } -#[cfg(not(target_family = "wasm"))] -impl TryIntoVal> for ScVal { - type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - BytesN::try_from_val(env, self) - } -} - impl BytesN { #[inline(always)] pub(crate) unsafe fn unchecked_new(env: Env, obj: Object) -> Self { diff --git a/soroban-sdk/src/deploy.rs b/soroban-sdk/src/deploy.rs index 090beb047..8fa20a0e3 100644 --- a/soroban-sdk/src/deploy.rs +++ b/soroban-sdk/src/deploy.rs @@ -57,7 +57,7 @@ impl Deployer { /// from the current contract and the provided salt. pub fn with_current_contract( &self, - salt: impl IntoVal, + salt: &impl IntoVal, ) -> DeployerWithCurrentContract { let env = self.env(); DeployerWithCurrentContract { @@ -71,8 +71,8 @@ impl Deployer { /// given contract ID and the provided salt. pub fn with_other_contract( &self, - contract_id: impl IntoVal>, - salt: impl IntoVal, + contract_id: &impl IntoVal>, + salt: &impl IntoVal, ) -> DeployerWithOtherContract { let env = self.env(); DeployerWithOtherContract { @@ -103,7 +103,7 @@ impl DeployerWithCurrentContract { /// will be used to derive a contract ID for the deployed contract. /// /// Returns the deployed contract's ID. - pub fn deploy(&self, wasm_hash: impl IntoVal>) -> BytesN<32> { + pub fn deploy(&self, wasm_hash: &impl IntoVal>) -> BytesN<32> { let env = &self.env; let id = env.create_contract_from_contract( wasm_hash.into_val(env).to_object(), diff --git a/soroban-sdk/src/env.rs b/soroban-sdk/src/env.rs index 3071e0fd3..91667f8d5 100644 --- a/soroban-sdk/src/env.rs +++ b/soroban-sdk/src/env.rs @@ -38,8 +38,6 @@ pub use internal::BitSet; pub use internal::Compare; pub use internal::ConversionError; pub use internal::EnvBase; -pub use internal::FromVal; -pub use internal::IntoVal; use internal::InvokerType; pub use internal::Object; pub use internal::RawVal; @@ -50,6 +48,33 @@ pub use internal::TryFromVal; pub use internal::TryIntoVal; pub use internal::Val; +pub trait IntoVal { + fn into_val(&self, e: &E) -> T; +} + +pub trait FromVal { + fn from_val(e: &E, v: &T) -> Self; +} + +impl FromVal for U +where + U: TryFromVal, +{ + fn from_val(e: &E, v: &T) -> Self { + U::try_from_val(e, v).unwrap_optimized() + } +} + +impl IntoVal for U +where + T: FromVal, +{ + fn into_val(&self, e: &E) -> T { + T::from_val(e, self) + } +} + +use crate::unwrap::UnwrapOptimized; use crate::{ accounts::Accounts, address::Address, crypto::Crypto, deploy::Deployer, events::Events, ledger::Ledger, logging::Logger, storage::Storage, AccountId, Bytes, BytesN, Vec, @@ -241,7 +266,7 @@ impl Env { T: TryFromVal, { let rv = internal::Env::call(self, contract_id.to_object(), *func, args.to_object()); - T::try_from_val(self, rv) + T::try_from_val(self, &rv) .map_err(|_| ConversionError) .unwrap() } @@ -259,9 +284,9 @@ impl Env { E: TryFrom, { let rv = internal::Env::try_call(self, contract_id.to_object(), *func, args.to_object()); - match Status::try_from_val(self, rv) { + match Status::try_from_val(self, &rv) { Ok(status) => Err(E::try_from(status)), - Err(ConversionError) => Ok(T::try_from_val(self, rv)), + Err(ConversionError) => Ok(T::try_from_val(self, &rv)), } } diff --git a/soroban-sdk/src/events.rs b/soroban-sdk/src/events.rs index 7f9831e0c..eeda88aba 100644 --- a/soroban-sdk/src/events.rs +++ b/soroban-sdk/src/events.rs @@ -5,7 +5,7 @@ use core::fmt::Debug; use crate::{contracttype, Bytes, BytesN, Map}; use crate::{ env::internal::{self}, - Env, IntoVal, RawVal, Vec, + ConversionError, Env, IntoVal, RawVal, TryFromVal, Vec, }; // TODO: consolidate with host::events::TOPIC_BYTES_LENGTH_LIMIT @@ -60,9 +60,11 @@ impl Debug for Events { pub trait Topics: IntoVal> {} -impl IntoVal> for () { - fn into_val(self, env: &Env) -> Vec { - Vec::::new(env) +impl TryFromVal for Vec { + type Error = ConversionError; + + fn try_from_val(env: &Env, _v: &()) -> Result { + Ok(Vec::::new(env)) } } diff --git a/soroban-sdk/src/lib.rs b/soroban-sdk/src/lib.rs index 171d41dce..4932b0425 100644 --- a/soroban-sdk/src/lib.rs +++ b/soroban-sdk/src/lib.rs @@ -346,7 +346,7 @@ pub use soroban_sdk_macros::contractimpl; /// state.last_incr = incr; /// /// // Save the count. -/// env.data().set(symbol!("STATE"), &state); +/// env.storage().set(&symbol!("STATE"), &state); /// /// // Return the count to the caller. /// state.count @@ -354,8 +354,8 @@ pub use soroban_sdk_macros::contractimpl; /// /// /// Return the current state. /// pub fn get_state(env: Env) -> State { -/// env.data() -/// .get(symbol!("STATE")) +/// env.storage() +/// .get(&symbol!("STATE")) /// .unwrap_or_else(|| Ok(State::default())) // If no value set, assume 0. /// .unwrap() // Panic if the value of COUNTER is not a State. /// } @@ -424,13 +424,13 @@ pub use soroban_sdk_macros::contractimpl; /// impl Contract { /// /// Set the color. /// pub fn set(env: Env, c: Color) { -/// env.data().set(symbol!("COLOR"), c); +/// env.storage().set(&symbol!("COLOR"), &c); /// } /// /// /// Get the color. /// pub fn get(env: Env) -> Option { -/// env.data() -/// .get(symbol!("COLOR")) +/// env.storage() +/// .get(&symbol!("COLOR")) /// .map(Result::unwrap) // Panic if the value of COLOR is not a Color. /// } /// } diff --git a/soroban-sdk/src/logging.rs b/soroban-sdk/src/logging.rs index 02c8af396..ed63b04ff 100644 --- a/soroban-sdk/src/logging.rs +++ b/soroban-sdk/src/logging.rs @@ -83,7 +83,7 @@ macro_rules! log { if cfg!(debug_assertions) { $env.logger().log($fmt, &[ $( - <_ as $crate::IntoVal>::into_val($args, $env) + <_ as $crate::IntoVal>::into_val(&$args, $env) ),* ]); } diff --git a/soroban-sdk/src/map.rs b/soroban-sdk/src/map.rs index 4d3488ea0..d48232045 100644 --- a/soroban-sdk/src/map.rs +++ b/soroban-sdk/src/map.rs @@ -5,11 +5,11 @@ use crate::iter::{UncheckedEnumerable, UncheckedIter}; use super::{ env::internal::{Env as _, EnvBase as _, RawValConvertible}, xdr::ScObjectType, - ConversionError, Env, IntoVal, Object, RawVal, Status, TryFromVal, TryIntoVal, Vec, + ConversionError, Env, IntoVal, Object, RawVal, Status, TryFromVal, Vec, }; #[cfg(not(target_family = "wasm"))] -use super::xdr::ScVal; +use super::{xdr::ScVal, TryIntoVal}; #[cfg(doc)] use crate::storage::Storage; @@ -159,11 +159,11 @@ where type Error = ConversionError; #[inline(always)] - fn try_from_val(env: &Env, obj: Object) -> Result { + fn try_from_val(env: &Env, obj: &Object) -> Result { if obj.is_obj_type(ScObjectType::Map) { Ok(Map { env: env.clone(), - obj, + obj: *obj, _k: PhantomData, _v: PhantomData, }) @@ -180,52 +180,20 @@ where { type Error = as TryFromVal>::Error; - fn try_from_val(env: &Env, val: RawVal) -> Result { - <_ as TryFromVal<_, Object>>::try_from_val(env, val.try_into()?) + fn try_from_val(env: &Env, val: &RawVal) -> Result { + <_ as TryFromVal<_, Object>>::try_from_val(env, &val.try_into()?) } } -impl TryIntoVal> for Object +impl TryFromVal> for RawVal where K: IntoVal + TryFromVal, V: IntoVal + TryFromVal, { type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - <_ as TryFromVal<_, _>>::try_from_val(env, self) - } -} - -impl TryIntoVal> for RawVal -where - K: IntoVal + TryFromVal, - V: IntoVal + TryFromVal, -{ - type Error = ConversionError; - - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - <_ as TryFromVal<_, _>>::try_from_val(env, self) - } -} - -impl IntoVal for Map -where - K: IntoVal + TryFromVal, - V: IntoVal + TryFromVal, -{ - fn into_val(self, _env: &Env) -> RawVal { - self.into() - } -} - -impl IntoVal for &Map -where - K: IntoVal + TryFromVal, - V: IntoVal + TryFromVal, -{ - fn into_val(self, _env: &Env) -> RawVal { - self.to_raw() + fn try_from_val(_env: &Env, v: &Map) -> Result { + Ok(v.to_raw()) } } @@ -244,7 +212,7 @@ where impl TryFrom<&Map> for ScVal { type Error = ConversionError; fn try_from(v: &Map) -> Result { - ScVal::try_from_val(&v.env, v.obj.to_raw()) + ScVal::try_from_val(&v.env, &v.obj.to_raw()) } } @@ -263,26 +231,14 @@ where V: IntoVal + TryFromVal, { type Error = ConversionError; - fn try_from_val(env: &Env, val: ScVal) -> Result { + fn try_from_val(env: &Env, val: &ScVal) -> Result { <_ as TryFromVal<_, Object>>::try_from_val( env, - val.try_into_val(env).map_err(|_| ConversionError)?, + &val.try_into_val(env).map_err(|_| ConversionError)?, ) } } -#[cfg(not(target_family = "wasm"))] -impl TryIntoVal> for ScVal -where - K: IntoVal + TryFromVal, - V: IntoVal + TryFromVal, -{ - type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - Map::try_from_val(env, self) - } -} - impl Map where K: IntoVal + TryFromVal, @@ -351,7 +307,7 @@ where let has = env.map_has(self.obj, k); if has.is_true() { let v = env.map_get(self.obj, k); - Some(V::try_from_val(env, v)) + Some(V::try_from_val(env, &v)) } else { None } @@ -361,7 +317,7 @@ where pub fn get_unchecked(&self, k: K) -> Result { let env = self.env(); let v = env.map_get(self.obj, k.into_val(env)); - V::try_from_val(env, v) + V::try_from_val(env, &v) } #[inline(always)] @@ -407,14 +363,14 @@ where pub fn keys(&self) -> Vec { let env = self.env(); let vec = env.map_keys(self.obj); - Vec::::try_from_val(env, vec).unwrap() + Vec::::try_from_val(env, &vec).unwrap() } #[inline(always)] pub fn values(&self) -> Vec { let env = self.env(); let vec = env.map_values(self.obj); - Vec::::try_from_val(env, vec).unwrap() + Vec::::try_from_val(env, &vec).unwrap() } pub fn iter(&self) -> MapIter @@ -486,11 +442,11 @@ where let value = env.map_get(self.0.obj, key); self.0.obj = env.map_del(self.0.obj, key); Some(Ok(( - match K::try_from_val(env, key) { + match K::try_from_val(env, &key) { Ok(k) => k, Err(_) => return Some(Err(ConversionError)), }, - match V::try_from_val(env, value) { + match V::try_from_val(env, &value) { Ok(v) => v, Err(_) => return Some(Err(ConversionError)), }, @@ -519,11 +475,11 @@ where let value = env.map_get(self.0.obj, key); self.0.obj = env.map_del(self.0.obj, key); Some(Ok(( - match K::try_from_val(env, key) { + match K::try_from_val(env, &key) { Ok(k) => k, Err(_) => return Some(Err(ConversionError)), }, - match V::try_from_val(env, value) { + match V::try_from_val(env, &value) { Ok(v) => v, Err(_) => return Some(Err(ConversionError)), }, diff --git a/soroban-sdk/src/serde.rs b/soroban-sdk/src/serde.rs index afda58242..49eca8d94 100644 --- a/soroban-sdk/src/serde.rs +++ b/soroban-sdk/src/serde.rs @@ -58,6 +58,6 @@ where fn deserialize(env: &Env, b: &Bytes) -> Result { let t = env.deserialize_from_bytes(b.into()); - T::try_from_val(env, t) + T::try_from_val(env, &t) } } diff --git a/soroban-sdk/src/set.rs b/soroban-sdk/src/set.rs index 69270fb23..920653172 100644 --- a/soroban-sdk/src/set.rs +++ b/soroban-sdk/src/set.rs @@ -2,7 +2,7 @@ use core::{cmp::Ordering, fmt::Debug, iter::FusedIterator}; use super::{ env::internal::Env as _, xdr::ScObjectType, ConversionError, Env, IntoVal, Map, Object, RawVal, - TryFromVal, TryIntoVal, Vec, + TryFromVal, Vec, }; /// Create a [Set] with the given items. @@ -133,7 +133,7 @@ where if self.is_empty() { None } else { - Some(T::try_from_val(env, env.map_min_key(self.to_object()))) + Some(T::try_from_val(env, &env.map_min_key(self.to_object()))) } } @@ -142,7 +142,7 @@ where if self.is_empty() { None } else { - Some(T::try_from_val(env, env.map_max_key(self.to_object()))) + Some(T::try_from_val(env, &env.map_max_key(self.to_object()))) } } @@ -281,9 +281,9 @@ where { type Error = ConversionError; - fn try_from_val(env: &Env, obj: Object) -> Result { + fn try_from_val(env: &Env, obj: &Object) -> Result { if obj.is_obj_type(ScObjectType::Map) { - Ok(unsafe { Set::::unchecked_new(env.clone(), obj) }) + Ok(unsafe { Set::::unchecked_new(env.clone(), obj.clone()) }) } else { Err(ConversionError {}) } @@ -296,48 +296,19 @@ where { type Error = as TryFromVal>::Error; - fn try_from_val(env: &Env, val: RawVal) -> Result { - <_ as TryFromVal<_, Object>>::try_from_val(env, val.try_into()?) + fn try_from_val(env: &Env, val: &RawVal) -> Result { + <_ as TryFromVal<_, Object>>::try_from_val(env, &val.try_into()?) } } -impl IntoVal for Set -where - T: IntoVal + TryFromVal, -{ - fn into_val(self, _env: &Env) -> RawVal { - self.0.into() - } -} - -impl IntoVal for &Set -where - T: IntoVal + TryFromVal, -{ - fn into_val(self, _env: &Env) -> RawVal { - self.to_raw() - } -} - -impl TryIntoVal> for RawVal +impl TryFromVal> for RawVal where T: IntoVal + TryFromVal, { type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - <_ as TryFromVal<_, _>>::try_from_val(env, self) - } -} - -impl TryIntoVal> for Object -where - T: IntoVal + TryFromVal, -{ - type Error = ConversionError; - - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - <_ as TryFromVal<_, _>>::try_from_val(env, self) + fn try_from_val(_env: &Env, v: &Set) -> Result { + Ok(v.to_raw()) } } @@ -350,12 +321,14 @@ where } } -impl IntoVal for Set +impl TryFromVal> for Object where T: IntoVal + TryFromVal, { - fn into_val(self, _env: &Env) -> Object { - self.into() + type Error = ConversionError; + + fn try_from_val(_env: &Env, v: &Set) -> Result { + Ok(v.to_object()) } } @@ -587,6 +560,7 @@ mod test { #[test] fn test_conversions() { + use crate::TryIntoVal; let env = Env::default(); let s1 = set![&env, 1, 2, 3]; let raw = s1.to_raw(); diff --git a/soroban-sdk/src/storage.rs b/soroban-sdk/src/storage.rs index c42c75444..9a8a4481d 100644 --- a/soroban-sdk/src/storage.rs +++ b/soroban-sdk/src/storage.rs @@ -27,9 +27,9 @@ use crate::{ /// # pub fn f(env: Env) { /// let storage = env.storage(); /// let key = symbol!("key"); -/// env.storage().set(key, 1); -/// assert_eq!(storage.has(key), true); -/// assert_eq!(storage.get::<_, i32>(key), Some(Ok(1))); +/// env.storage().set(&key, &1); +/// assert_eq!(storage.has(&key), true); +/// assert_eq!(storage.get::<_, i32>(&key), Some(Ok(1))); /// # } /// # } /// # @@ -68,7 +68,7 @@ impl Storage { /// Returns if there is a value stored for the given key in the currently /// executing contracts data. #[inline(always)] - pub fn has(&self, key: K) -> bool + pub fn has(&self, key: &K) -> bool where K: IntoVal, { @@ -90,7 +90,7 @@ impl Storage { /// /// Add safe checked versions of these functions. #[inline(always)] - pub fn get(&self, key: K) -> Option> + pub fn get(&self, key: &K) -> Option> where V::Error: Debug, K: IntoVal, @@ -101,7 +101,7 @@ impl Storage { let has = internal::Env::has_contract_data(env, key); if has.is_true() { let rv = internal::Env::get_contract_data(env, key); - Some(V::try_from_val(env, rv)) + Some(V::try_from_val(env, &rv)) } else { None } @@ -114,7 +114,7 @@ impl Storage { /// /// When the key does not have a value stored. #[inline(always)] - pub fn get_unchecked(&self, key: K) -> Result + pub fn get_unchecked(&self, key: &K) -> Result where V::Error: Debug, K: IntoVal, @@ -122,7 +122,7 @@ impl Storage { { let env = self.env(); let rv = internal::Env::get_contract_data(env, key.into_val(env)); - V::try_from_val(env, rv) + V::try_from_val(env, &rv) } /// Sets the value for the given key in the currently executing contract's @@ -131,7 +131,7 @@ impl Storage { /// If the key already has a value associated with it, the old value is /// replaced by the new value. #[inline(always)] - pub fn set(&self, key: K, val: V) + pub fn set(&self, key: &K, val: &V) where K: IntoVal, V: IntoVal, @@ -141,7 +141,7 @@ impl Storage { } #[inline(always)] - pub fn remove(&self, key: K) + pub fn remove(&self, key: &K) where K: IntoVal, { diff --git a/soroban-sdk/src/tests/contract_snapshot.rs b/soroban-sdk/src/tests/contract_snapshot.rs index 8ccfa898a..5fe612281 100644 --- a/soroban-sdk/src/tests/contract_snapshot.rs +++ b/soroban-sdk/src/tests/contract_snapshot.rs @@ -6,10 +6,10 @@ pub struct Contract; #[contractimpl] impl Contract { pub fn store(env: Env, k: i32, v: i32) { - env.storage().set(k, v) + env.storage().set(&k, &v) } pub fn get(env: Env, k: i32) -> i32 { - env.storage().get(k).unwrap().unwrap() + env.storage().get(&k).unwrap().unwrap() } } diff --git a/soroban-sdk/src/tests/contract_store.rs b/soroban-sdk/src/tests/contract_store.rs index 86bd6a567..efef1f00b 100644 --- a/soroban-sdk/src/tests/contract_store.rs +++ b/soroban-sdk/src/tests/contract_store.rs @@ -6,7 +6,7 @@ pub struct Contract; #[contractimpl] impl Contract { pub fn store(env: Env, k: i32, v: i32) { - env.storage().set(k, v) + env.storage().set(&k, &v) } } @@ -19,7 +19,7 @@ fn test() { client.store(&2, &4); assert_eq!( - e.as_contract(&contract_id, || e.storage().get::<_, i32>(2)), + e.as_contract(&contract_id, || e.storage().get::<_, i32>(&2)), Some(Ok(4)) ); } diff --git a/soroban-sdk/src/tests/contract_udt_enum.rs b/soroban-sdk/src/tests/contract_udt_enum.rs index c48f59963..66c7da08d 100644 --- a/soroban-sdk/src/tests/contract_udt_enum.rs +++ b/soroban-sdk/src/tests/contract_udt_enum.rs @@ -1,6 +1,6 @@ use crate as soroban_sdk; use soroban_sdk::{ - contractimpl, contracttype, symbol, vec, ConversionError, Env, IntoVal, TryFromVal, + contractimpl, contracttype, symbol, vec, ConversionError, Env, IntoVal, RawVal, TryFromVal, Vec, }; #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -38,21 +38,21 @@ fn test_error_on_partial_decode() { // Success case, a vec will decode to a Udt if the first element is the // variant name as a Symbol, and following elements are tuple-like values // for the variant. - let vec = vec![&env, symbol!("Aaa").into_val(&env)].to_raw(); - let udt = Udt::try_from_val(&env, vec); + let vec: Vec = vec![&env, symbol!("Aaa").into_val(&env)]; + let udt = Udt::try_from_val(&env, &vec.to_raw()); assert_eq!(udt, Ok(Udt::Aaa)); - let vec = vec![&env, symbol!("Bbb").into_val(&env), 8.into()].to_raw(); - let udt = Udt::try_from_val(&env, vec); + let vec: Vec = vec![&env, symbol!("Bbb").into_val(&env), 8.into()]; + let udt = Udt::try_from_val(&env, &vec.to_raw()); assert_eq!(udt, Ok(Udt::Bbb(8))); // If an enum has a tuple like variant with one value, but the vec has // multiple values, it is an error. It is an error because decoding and // encoding will not round trip the data, and therefore partial decoding is // relatively difficult to use safely. - let vec = vec![&env, symbol!("Aaa").into_val(&env), 8.into()].to_raw(); - let udt = Udt::try_from_val(&env, vec); + let vec: Vec = vec![&env, symbol!("Aaa").into_val(&env), 8.into()]; + let udt = Udt::try_from_val(&env, &vec.to_raw()); assert_eq!(udt, Err(ConversionError)); - let vec = vec![&env, symbol!("Bbb").into_val(&env), 8.into(), 9.into()].to_raw(); - let udt = Udt::try_from_val(&env, vec); + let vec: Vec = vec![&env, symbol!("Bbb").into_val(&env), 8.into(), 9.into()]; + let udt = Udt::try_from_val(&env, &vec.to_raw()); assert_eq!(udt, Err(ConversionError)); } diff --git a/soroban-sdk/src/tests/contract_udt_struct.rs b/soroban-sdk/src/tests/contract_udt_struct.rs index b354ccce2..e22f231d3 100644 --- a/soroban-sdk/src/tests/contract_udt_struct.rs +++ b/soroban-sdk/src/tests/contract_udt_struct.rs @@ -39,7 +39,7 @@ fn test_error_on_partial_decode() { // Success case, a map will decode to a Udt if the symbol keys match the // fields. let map = map![&env, (symbol!("a"), 5), (symbol!("b"), 7)].to_raw(); - let udt = Udt::try_from_val(&env, map); + let udt = Udt::try_from_val(&env, &map); assert_eq!(udt, Ok(Udt { a: 5, b: 7 })); // If a struct has fields a, b, and a map is decoded into it where the map @@ -53,7 +53,7 @@ fn test_error_on_partial_decode() { (symbol!("c"), 9) ] .to_raw(); - let udt = Udt::try_from_val(&env, map); + let udt = Udt::try_from_val(&env, &map); assert_eq!(udt, Err(ConversionError)); } diff --git a/soroban-sdk/src/tests/contract_udt_struct_tuple.rs b/soroban-sdk/src/tests/contract_udt_struct_tuple.rs index 5f4de52bd..2dcf68250 100644 --- a/soroban-sdk/src/tests/contract_udt_struct_tuple.rs +++ b/soroban-sdk/src/tests/contract_udt_struct_tuple.rs @@ -46,23 +46,23 @@ fn test_error_on_partial_decode() { let env = Env::default(); // Success case, a vec will decode to a Udt. - let map = vec![&env, 5, 7].to_raw(); - let udt = Udt::try_from_val(&env, map); + let vec = vec![&env, 5, 7].to_raw(); + let udt = Udt::try_from_val(&env, &vec); assert_eq!(udt, Ok(Udt(5, 7))); // If a struct has 2 fields, and a vec is decoded into it where the vec has // 2 elements, it is an error. It is an error because all fields must be // assigned values. - let map = vec![&env, 5, 7, 9].to_raw(); - let udt = Udt::try_from_val(&env, map); + let vec = vec![&env, 5, 7, 9].to_raw(); + let udt = Udt::try_from_val(&env, &vec); assert_eq!(udt, Err(ConversionError)); // If a struct has 2 fields, and a vec is decoded into it where the vec has // 3 elements, it is an error. It is an error because decoding and encoding // will not round trip the data, and therefore partial decoding is // relatively difficult to use safely. - let map = vec![&env, 5, 7, 9].to_raw(); - let udt = Udt::try_from_val(&env, map); + let vec = vec![&env, 5, 7, 9].to_raw(); + let udt = Udt::try_from_val(&env, &vec); assert_eq!(udt, Err(ConversionError)); } diff --git a/soroban-sdk/src/vec.rs b/soroban-sdk/src/vec.rs index 1a8930fa0..6f5f1c2a9 100644 --- a/soroban-sdk/src/vec.rs +++ b/soroban-sdk/src/vec.rs @@ -44,21 +44,13 @@ macro_rules! vec { macro_rules! impl_into_vec_for_tuple { ( $($typ:ident $idx:tt)* ) => { - impl<$($typ),*> IntoVal> for ($($typ,)*) + impl<$($typ),*> TryFromVal for Vec where $($typ: IntoVal),* { - fn into_val(self, env: &Env) -> Vec { - vec![&env, $(self.$idx.into_val(env), )*] - } - } - - impl<$($typ),*> IntoVal> for &($($typ,)*) - where - $(for <'a> &'a $typ: IntoVal),* - { - fn into_val(self, env: &Env) -> Vec { - vec![&env, $((&self.$idx).into_val(env), )*] + type Error = ConversionError; + fn try_from_val(env: &Env, v: &($($typ,)*)) -> Result { + Ok(vec![&env, $(v.$idx.into_val(env), )*]) } } }; @@ -170,15 +162,22 @@ where } } -impl IntoVal> for Vec { - fn into_val(self, _env: &Env) -> Vec { - unsafe { Vec::unchecked_new(self.env, self.obj) } +impl TryFromVal> for Vec { + type Error = ConversionError; + + fn try_from_val(env: &Env, v: &Vec) -> Result { + Ok(unsafe { Vec::unchecked_new(env.clone(), v.obj.clone()) }) } } -impl IntoVal> for &Vec { - fn into_val(self, _env: &Env) -> Vec { - unsafe { Vec::unchecked_new(self.env.clone(), self.obj.clone()) } +// This conflicts with the previous definition unless we add the spurious &, +// which is not .. great. Maybe don't define this particular blanket, or add +// a to_other() method? +impl TryFromVal> for Vec { + type Error = ConversionError; + + fn try_from_val(env: &Env, v: &&Vec) -> Result { + Ok(unsafe { Vec::unchecked_new(env.clone(), v.obj.clone()) }) } } @@ -189,9 +188,9 @@ where type Error = ConversionError; #[inline(always)] - fn try_from_val(env: &Env, obj: Object) -> Result { + fn try_from_val(env: &Env, obj: &Object) -> Result { if obj.is_obj_type(ScObjectType::Vec) { - Ok(unsafe { Vec::::unchecked_new(env.clone(), obj) }) + Ok(unsafe { Vec::::unchecked_new(env.clone(), obj.clone()) }) } else { Err(ConversionError {}) } @@ -205,48 +204,24 @@ where type Error = as TryFromVal>::Error; #[inline(always)] - fn try_from_val(env: &Env, val: RawVal) -> Result { - <_ as TryFromVal<_, Object>>::try_from_val(env, val.try_into()?) + fn try_from_val(env: &Env, val: &RawVal) -> Result { + <_ as TryFromVal<_, Object>>::try_from_val(env, &val.try_into()?) } } -impl TryIntoVal> for Object -where - T: IntoVal + TryFromVal, -{ +impl TryFromVal> for RawVal { type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - <_ as TryFromVal<_, _>>::try_from_val(env, self) + fn try_from_val(_env: &Env, v: &Vec) -> Result { + Ok(v.to_raw()) } } -impl TryIntoVal> for RawVal -where - T: IntoVal + TryFromVal, -{ +impl TryFromVal> for Object { type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - <_ as TryFromVal<_, _>>::try_from_val(env, self) - } -} - -impl IntoVal for Vec -where - T: IntoVal + TryFromVal, -{ - fn into_val(self, _env: &Env) -> RawVal { - self.into() - } -} - -impl IntoVal for &Vec -where - T: IntoVal + TryFromVal, -{ - fn into_val(self, _env: &Env) -> RawVal { - self.to_raw() + fn try_from_val(_env: &Env, v: &Vec) -> Result { + Ok(v.obj.into()) } } @@ -260,15 +235,6 @@ where } } -impl IntoVal for Vec -where - T: IntoVal + TryFromVal, -{ - fn into_val(self, _env: &Env) -> Object { - self.into() - } -} - impl From> for Object where T: IntoVal + TryFromVal, @@ -299,7 +265,7 @@ use super::xdr::{ScObject, ScVal, ScVec}; impl TryFrom<&Vec> for ScVal { type Error = ConversionError; fn try_from(v: &Vec) -> Result { - ScVal::try_from_val(&v.env, v.obj.to_raw()) + ScVal::try_from_val(&v.env, &v.obj.to_raw()) } } @@ -359,10 +325,10 @@ where T: IntoVal + TryFromVal, { type Error = ConversionError; - fn try_from_val(env: &Env, val: ScVal) -> Result { + fn try_from_val(env: &Env, val: &ScVal) -> Result { <_ as TryFromVal<_, Object>>::try_from_val( env, - val.try_into_val(env).map_err(|_| ConversionError)?, + &val.try_into_val(env).map_err(|_| ConversionError)?, ) } } @@ -373,8 +339,8 @@ where T: IntoVal + TryFromVal, { type Error = ConversionError; - fn try_from_val(env: &Env, val: ScObject) -> Result { - <_ as TryFromVal<_, ScVal>>::try_from_val(env, ScVal::Object(Some(val))) + fn try_from_val(env: &Env, val: &ScObject) -> Result { + <_ as TryFromVal<_, ScVal>>::try_from_val(env, &ScVal::Object(Some(val.clone()))) } } @@ -384,41 +350,8 @@ where T: IntoVal + TryFromVal, { type Error = ConversionError; - fn try_from_val(env: &Env, val: ScVec) -> Result { - <_ as TryFromVal<_, ScObject>>::try_from_val(env, ScObject::Vec(val)) - } -} - -#[cfg(not(target_family = "wasm"))] -impl TryIntoVal> for ScVal -where - T: IntoVal + TryFromVal, -{ - type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - Vec::try_from_val(env, self) - } -} - -#[cfg(not(target_family = "wasm"))] -impl TryIntoVal> for ScObject -where - T: IntoVal + TryFromVal, -{ - type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - Vec::try_from_val(env, self) - } -} - -#[cfg(not(target_family = "wasm"))] -impl TryIntoVal> for ScVec -where - T: IntoVal + TryFromVal, -{ - type Error = ConversionError; - fn try_into_val(self, env: &Env) -> Result, Self::Error> { - Vec::try_from_val(env, self) + fn try_from_val(env: &Env, val: &ScVec) -> Result { + <_ as TryFromVal<_, ScObject>>::try_from_val(env, &ScObject::Vec(val.clone())) } } @@ -484,7 +417,7 @@ where if i < self.len() { let env = self.env(); let val = env.vec_get(self.obj, i.into()); - Some(T::try_from_val(env, val)) + Some(T::try_from_val(env, &val)) } else { None } @@ -497,7 +430,7 @@ where { let env = self.env(); let val = env.vec_get(self.obj, i.into()); - T::try_from_val(env, val) + T::try_from_val(env, &val) } #[inline(always)] @@ -605,7 +538,7 @@ where } else { let env = &self.env; let val = env.vec_front(self.obj); - Some(T::try_from_val(env, val)) + Some(T::try_from_val(env, &val)) } } @@ -613,7 +546,7 @@ where pub fn first_unchecked(&self) -> Result { let env = &self.env; let val = env.vec_front(self.obj); - T::try_from_val(env, val) + T::try_from_val(env, &val) } #[inline(always)] @@ -623,7 +556,7 @@ where } else { let env = self.env(); let val = env.vec_back(self.obj); - Some(T::try_from_val(env, val)) + Some(T::try_from_val(env, &val)) } } @@ -631,7 +564,7 @@ where pub fn last_unchecked(&self) -> Result { let env = self.env(); let val = env.vec_back(self.obj); - T::try_from_val(env, val) + T::try_from_val(env, &val) } #[inline(always)] @@ -708,7 +641,7 @@ where impl Vec where - for<'a> &'a T: IntoVal, + T: IntoVal, { /// Returns true if the Vec contains the item. #[inline(always)] @@ -815,7 +748,7 @@ where } else { let val = self.0.env().vec_front(self.0.obj); self.0 = self.0.slice(1..); - Some(T::try_from_val(self.0.env(), val)) + Some(T::try_from_val(self.0.env(), &val)) } } @@ -839,7 +772,7 @@ where } else { let val = self.0.env().vec_back(self.0.obj); self.0 = self.0.slice(..len - 1); - Some(T::try_from_val(self.0.env(), val)) + Some(T::try_from_val(self.0.env(), &val)) } } @@ -1110,7 +1043,7 @@ mod test { let env = Env::default(); let v = vec![&env, 1]; let val: ScVal = v.clone().try_into().unwrap(); - let roundtrip = Vec::::try_from_val(&env, val).unwrap(); + let roundtrip = Vec::::try_from_val(&env, &val).unwrap(); assert_eq!(v, roundtrip); } diff --git a/soroban-token-spec/src/tests/use_token_contract.rs b/soroban-token-spec/src/tests/use_token_contract.rs index adc1bf416..fa857c38b 100644 --- a/soroban-token-spec/src/tests/use_token_contract.rs +++ b/soroban-token-spec/src/tests/use_token_contract.rs @@ -16,7 +16,7 @@ pub enum DataKey { } fn get_token(e: &Env) -> BytesN<32> { - e.storage().get_unchecked(DataKey::Token).unwrap() + e.storage().get_unchecked(&DataKey::Token).unwrap() } pub struct TestContract; @@ -24,7 +24,7 @@ pub struct TestContract; #[contractimpl] impl TestContract { pub fn init(e: Env, contract: BytesN<32>) { - e.storage().set(DataKey::Token, contract); + e.storage().set(&DataKey::Token, &contract); } pub fn get_token(e: Env) -> BytesN<32> { @@ -32,11 +32,11 @@ impl TestContract { } pub fn approve(e: Env, spender: Identifier, amount: i128) { - TokenClient::new(&e, get_token(&e)).incr_allow(&Signature::Invoker, &0, &spender, &amount); + TokenClient::new(&e, &get_token(&e)).incr_allow(&Signature::Invoker, &0, &spender, &amount); } pub fn allowance(e: Env, from: Identifier, spender: Identifier) -> i128 { - TokenClient::new(&e, get_token(&e)).allowance(&from, &spender) + TokenClient::new(&e, &get_token(&e)).allowance(&from, &spender) } } diff --git a/tests/contract_data/src/lib.rs b/tests/contract_data/src/lib.rs index 5c7513dba..eedf69c01 100644 --- a/tests/contract_data/src/lib.rs +++ b/tests/contract_data/src/lib.rs @@ -6,14 +6,14 @@ pub struct Contract; #[contractimpl] impl Contract { pub fn put(e: Env, key: Symbol, val: Symbol) { - e.storage().set(key, val) + e.storage().set(&key, &val) } pub fn get(e: Env, key: Symbol) -> Option { - e.storage().get(key).map(|v| v.unwrap()) + e.storage().get(&key).map(|v| v.unwrap()) } pub fn del(e: Env, key: Symbol) { - e.storage().remove(key) + e.storage().remove(&key) } } diff --git a/tests/errors/src/lib.rs b/tests/errors/src/lib.rs index ba64d7624..26023ddb9 100644 --- a/tests/errors/src/lib.rs +++ b/tests/errors/src/lib.rs @@ -12,7 +12,7 @@ pub enum Error { #[contractimpl] impl Contract { pub fn hello(env: Env, flag: u32) -> Result { - env.storage().set(symbol!("persisted"), true); + env.storage().set(&symbol!("persisted"), &true); if flag == 0 { Ok(symbol!("hello")) } else if flag == 1 { @@ -29,7 +29,7 @@ impl Contract { #[cfg(test)] pub fn persisted(env: Env) -> bool { env.storage() - .get(symbol!("persisted")) + .get(&symbol!("persisted")) .unwrap_or(Ok(false)) .unwrap() } diff --git a/tests/udt/src/lib.rs b/tests/udt/src/lib.rs index aa66cb9d2..cbab000c5 100644 --- a/tests/udt/src/lib.rs +++ b/tests/udt/src/lib.rs @@ -205,7 +205,7 @@ mod test { c: vec![&e, 1], }; let val: ScVal = udt.clone().try_into().unwrap(); - let roundtrip = UdtStruct::try_from_val(&e, val).unwrap(); + let roundtrip = UdtStruct::try_from_val(&e, &val).unwrap(); assert_eq!(udt, roundtrip); } }