Repository: juspay/hyperswitch
File: crates/router/src/core/payments/transformers.rs (Rust)

Code before:
            mit_category: pi.mit_category,
            force_3ds_challenge: pi.force_3ds_challenge,
            force_3ds_challenge_trigger: pi.force_3ds_challenge_trigger,
            whole_connector_response: None,
            issuer_error_code: pa.issuer_error_code,
            issuer_error_message: pa.issuer_error_message,
            is_iframe_redirection_enabled:pi.is_iframe_redirection_enabled,
            payment_channel: pi.payment_channel,
            network_transaction_id: None,
            enable_partial_authorization: pi.enable_partial_authorization,
            enable_overcapture: pi.enable_overcapture,
            is_overcapture_enabled: pa.is_overcapture_enabled,
            network_details: pa.network_details.map(NetworkDetails::foreign_from),
            is_stored_credential:pa.is_stored_credential,
            request_extended_authorization: pa.request_extended_authorization,
        }
    }
}

#[cfg(feature = "v2")]
impl ForeignFrom<(storage::PaymentIntent, Option<storage::PaymentAttempt>)>
    for api_models::payments::PaymentsListResponseItem
{
    fn foreign_from((pi, pa): (storage::PaymentIntent, Option<storage::PaymentAttempt>)) -> Self {
        Self {
            id: pi.id.clone(),
            merchant_id: pi.merchant_id.clone(),
            profile_id: pi.profile_id.clone(),
            customer_id: pi.customer_id.clone(),
            payment_method_id: pa.as_ref().and_then(|p| p.payment_method_id.clone()),
            status: pi.status,
            amount: api_models::payments::PaymentAmountDetailsResponse::foreign_from((
                &pi.amount_details,
                pa.as_ref().map(|p| &p.amount_details),
            )),
            created: pi.created_at,
            payment_method_type: pa.as_ref().and_then(|p| p.payment_method_type.into()),
            payment_method_subtype: pa.as_ref().and_then(|p| p.payment_method_subtype.into()),
            connector: pa.as_ref().and_then(|p| p.connector.clone()),
            merchant_connector_id: pa.as_ref().and_then(|p| p.merchant_connector_id.clone()),
            customer: None,
            merchant_reference_id: pi.merchant_reference_id.clone(),
            connector_payment_id: pa.as_ref().and_then(|p| p.connector_payment_id.clone()),
            connector_response_reference_id: pa
                .as_ref()
                .and_then(|p| p.connector_response_reference_id.clone()),
            metadata: pi.metadata.clone(),
            description: pi
                .description
                .as_ref()
                .map(|val| val.get_string_repr().to_string()),

Review comment (suggestion):
These clones are required because `is_split_payment` function borrows PaymentIntent and without these `clone()` calls, there is an error, `Borrow of Partially moved vaule`

Code after:
            shipping_cost: None,
            card_discovery: pa.card_discovery,
            mit_category: pi.mit_category,
            force_3ds_challenge: pi.force_3ds_challenge,
            force_3ds_challenge_trigger: pi.force_3ds_challenge_trigger,
            whole_connector_response: None,
            issuer_error_code: pa.issuer_error_code,
            issuer_error_message: pa.issuer_error_message,
            is_iframe_redirection_enabled:pi.is_iframe_redirection_enabled,
            payment_channel: pi.payment_channel,
            network_transaction_id: None,
            enable_partial_authorization: pi.enable_partial_authorization,
            enable_overcapture: pi.enable_overcapture,
            is_overcapture_enabled: pa.is_overcapture_enabled,
            network_details: pa.network_details.map(NetworkDetails::foreign_from),
            is_stored_credential:pa.is_stored_credential,
            request_extended_authorization: pa.request_extended_authorization,
            billing_descriptor: pi.billing_descriptor,
        }
    }
}

#[cfg(feature = "v2")]
impl ForeignFrom<(storage::PaymentIntent, Option<storage::PaymentAttempt>)>
    for api_models::payments::PaymentsListResponseItem
{
    fn foreign_from((pi, pa): (storage::PaymentIntent, Option<storage::PaymentAttempt>)) -> Self {
        let is_split_payment = pi.is_split_payment();
        Self {
            id: pi.id,
            merchant_id: pi.merchant_id,
            profile_id: pi.profile_id,
            customer_id: pi.customer_id,
            payment_method_id: pa.as_ref().and_then(|p| p.payment_method_id.clone()),
            status: pi.status,
            amount: api_models::payments::PaymentAmountDetailsResponse::foreign_from((
                &pi.amount_details,
                pa.as_ref().map(|p| &p.amount_details),
            )),
            created: pi.created_at,
            payment_method_type: pa.as_ref().and_then(|p| p.payment_method_type.into()),
            payment_method_subtype: pa.as_ref().and_then(|p| p.payment_method_subtype.into()),
            connector: pa.as_ref().and_then(|p| p.connector.clone()),
            merchant_connector_id: pa.as_ref().and_then(|p| p.merchant_connector_id.clone()),
            customer: None,
            merchant_reference_id: pi.merchant_reference_id,
            connector_payment_id: pa.as_ref().and_then(|p| p.connector_payment_id.clone()),
            connector_response_reference_id: pa
                .as_ref()
                .and_then(|p| p.connector_response_reference_id.clone()),
            metadata: pi.metadata,