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

Code before:
    type Error = error_stack::Report<errors::ApiErrorResponse>;

    fn try_from(additional_data: PaymentAdditionalData<'_, F>) -> Result<Self, Self::Error> {
        let payment_data = additional_data.payment_data;
        let connector = api::ConnectorData::get_connector_by_name(
            &additional_data.state.conf.connectors,
            &additional_data.connector_name,
            api::GetToken::Connector,
            payment_data.payment_attempt.merchant_connector_id.clone(),
        )?;
        let total_amount = payment_data
            .incremental_authorization_details
            .clone()
            .map(|details| details.total_amount)
            .ok_or(
                report!(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable("missing incremental_authorization_details in payment_data"),
            )?;
        let additional_amount = payment_data
            .incremental_authorization_details
            .clone()
            .map(|details| details.additional_amount)
            .ok_or(
                report!(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable("missing incremental_authorization_details in payment_data"),
            )?;
        Ok(Self {
            total_amount: total_amount.get_amount_as_i64(),
            additional_amount: additional_amount.get_amount_as_i64(),
            reason: payment_data
                .incremental_authorization_details
                .and_then(|details| details.reason),
            currency: payment_data.currency,
            connector_transaction_id: connector
                .connector
                .connector_transaction_id(payment_data.payment_attempt.clone())?
                .ok_or(errors::ApiErrorResponse::ResourceIdNotFound)?,
            connector_meta: payment_data.payment_attempt.connector_metadata,
        })
    }
}

#[cfg(feature = "v2")]
impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>>
    for types::PaymentsIncrementalAuthorizationData
{
    type Error = error_stack::Report<errors::ApiErrorResponse>;

    fn try_from(additional_data: PaymentAdditionalData<'_, F>) -> Result<Self, Self::Error> {
        let payment_data = additional_data.payment_data;
        let connector = api::ConnectorData::get_connector_by_name(

Review comment (security):
Nit:
instead of cloning `incremental_authorization_details` twice and accessing its fields, you can get `incremental_authorization_details` as reference and clone only required fields

Code after:
    type Error = error_stack::Report<errors::ApiErrorResponse>;

    fn try_from(additional_data: PaymentAdditionalData<'_, F>) -> Result<Self, Self::Error> {
        let payment_data = additional_data.payment_data;
        let payment_attempt = &payment_data.payment_attempt;
        let connector = api::ConnectorData::get_connector_by_name(
            &additional_data.state.conf.connectors,
            &additional_data.connector_name,
            api::GetToken::Connector,
            payment_attempt.merchant_connector_id.clone(),
        )?;
        let incremental_details = payment_data
            .incremental_authorization_details
            .as_ref()
            .ok_or(
                report!(errors::ApiErrorResponse::InternalServerError)
                    .attach_printable("missing incremental_authorization_details in payment_data"),
            )?;
        Ok(Self {
            total_amount: incremental_details.total_amount.get_amount_as_i64(),
            additional_amount: incremental_details.additional_amount.get_amount_as_i64(),
            reason: incremental_details.reason.clone(),
            currency: payment_data.currency,
            connector_transaction_id: connector
                .connector
                .connector_transaction_id(payment_attempt)?
                .ok_or(errors::ApiErrorResponse::ResourceIdNotFound)?,
            connector_meta: payment_attempt.connector_metadata.clone(),
        })
    }
}

#[cfg(feature = "v2")]
impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>>
    for types::PaymentsIncrementalAuthorizationData
{
    type Error = error_stack::Report<errors::ApiErrorResponse>;

    fn try_from(additional_data: PaymentAdditionalData<'_, F>) -> Result<Self, Self::Error> {
        let payment_data = additional_data.payment_data;
        let connector = api::ConnectorData::get_connector_by_name(
            &additional_data.state.conf.connectors,
            &additional_data.connector_name,
            api::GetToken::Connector,
            payment_data.payment_attempt.merchant_connector_id.clone(),
        )?;
        let incremental_details = payment_data
            .incremental_authorization_details
            .as_ref()
            .ok_or(
                report!(errors::ApiErrorResponse::InternalServerError)