From 3bea493a033097eb6688e66c96fbe06029f4c9f6 Mon Sep 17 00:00:00 2001 From: Fusee Date: Tue, 7 Nov 2023 17:10:48 +0100 Subject: [PATCH] fixed Clone and Debug implementations on BaseTransactionNetworkExecutor --- executor/src/network/transaction.rs | 40 ++++++++++++++++++++++++++++- tester/core/tests/network_call.rs | 24 ++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/executor/src/network/transaction.rs b/executor/src/network/transaction.rs index 8deefb3..e790c5e 100644 --- a/executor/src/network/transaction.rs +++ b/executor/src/network/transaction.rs @@ -1,3 +1,4 @@ +use std::fmt::{Debug, Formatter}; use std::marker::PhantomData; use std::mem; use async_trait::async_trait; @@ -17,7 +18,6 @@ pub type NetworkExecutor = BaseTransactionNetworkExecutor; /// /// This executor is designed to interact with a blockchain network via a specified gateway URL and a wallet /// for signing transactions. It is parameterized by a type `Interactor` that encapsulates the blockchain interaction logic. -#[derive(Clone, Debug)] pub struct BaseTransactionNetworkExecutor { /// The URL of the blockchain network gateway through which transactions will be sent. pub gateway_url: String, @@ -28,6 +28,44 @@ pub struct BaseTransactionNetworkExecutor { _phantom_data: PhantomData, } +/// Custom implementation of `Clone` for `BaseTransactionNetworkExecutor`. +/// +/// This implementation is necessary because the `Interactor` generic parameter might not +/// implement `Clone`. However, since `Interactor` is used only as phantom data (it does not +/// affect the state of `BaseTransactionNetworkExecutor`), we can safely implement `Clone` +/// without the `Interactor` needing to be `Clone`. +impl Clone for BaseTransactionNetworkExecutor +where + Interactor: BlockchainInteractor +{ + fn clone(&self) -> Self { + Self { + gateway_url: self.gateway_url.clone(), + wallet: self.wallet, + _phantom_data: Default::default(), + } + } +} + +/// Custom implementation of `Debug` for `BaseTransactionNetworkExecutor`. +/// +/// This implementation is necessary because the `Interactor` generic parameter might not +/// implement `Debug`. As with `Clone`, since `Interactor` is only used as phantom data, +/// it does not impact the debug representation of `BaseTransactionNetworkExecutor`. This +/// implementation ensures that instances of `BaseTransactionNetworkExecutor` can be +/// formatted using the `Debug` trait regardless of whether `Interactor` implements `Debug`. +impl Debug for BaseTransactionNetworkExecutor + where + Interactor: BlockchainInteractor +{ + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("BaseTransactionNetworkExecutor") + .field("gateway_url", &self.gateway_url) + .field("wallet", &self.wallet) + .finish() + } +} + impl BaseTransactionNetworkExecutor { /// Creates a new instance of `BaseTransactionNetworkExecutor`. /// diff --git a/tester/core/tests/network_call.rs b/tester/core/tests/network_call.rs index d3ca365..3670c91 100644 --- a/tester/core/tests/network_call.rs +++ b/tester/core/tests/network_call.rs @@ -7,7 +7,7 @@ use novax::{Address, Wallet}; use novax::errors::NovaXError; use num_bigint::BigUint; use novax::tester::tester::{CustomEnum, CustomEnumWithFields, CustomEnumWithValues, CustomStruct, CustomStructWithStructAndVec, TesterContract}; -use novax::executor::{BaseTransactionNetworkExecutor, BlockchainInteractor, SendableTransactionConvertible}; +use novax::executor::{BaseTransactionNetworkExecutor, BlockchainInteractor, NetworkExecutor, SendableTransactionConvertible}; use novax_mocking::{ScCallStep, ScDeployStep, TxResponse}; use crate::utils::decode_scr_data::decode_scr_data_or_panic; @@ -128,6 +128,28 @@ fn get_executor() -> Arc>> Arc::new(Mutex::new(executor)) } +// The below test is a success if it compiles +#[tokio::test] +async fn test_clone_network_executor() -> Result<(), NovaXError> { + let wallet = Wallet::from_private_key(CALLER_PRIVATE_KEY).unwrap(); + let executor = NetworkExecutor::new("", &wallet); + #[allow(clippy::redundant_clone)] + let _executor2 = executor.clone(); + + Ok(()) +} + +// The below test is a success if it compiles +#[tokio::test] +async fn test_debug_network_executor() -> Result<(), NovaXError> { + let wallet = Wallet::from_private_key(CALLER_PRIVATE_KEY).unwrap(); + let executor = NetworkExecutor::new("", &wallet); + + println!("{executor:?}"); + + Ok(()) +} + #[tokio::test] async fn test_call_return_caller() -> Result<(), NovaXError> { let executor = get_executor();