Repository: juspay/hyperswitch
File: crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs (Rust)

Code before:
                }),
                postal_code: addr.zip.remove_new_line(),
                country: addr.country,
                email,
            })
        })
        .unwrap_or(default_address))
}

fn convert_metadata_to_merchant_defined_info(metadata: Value) -> Vec<MerchantDefinedInformation> {
    let hashmap: std::collections::BTreeMap<String, Value> =
        serde_json::from_str(&metadata.to_string()).unwrap_or(std::collections::BTreeMap::new());
    let mut vector = Vec::new();
    let mut iter = 1;
    for (key, value) in hashmap {
        vector.push(MerchantDefinedInformation {
            key: iter,
            value: format!("{key}={value}"),
        });
        iter += 1;
    }
    vector
}

pub fn map_to_effective_type(
    auth_type: Option<common_enums::DecoupledAuthenticationType>,
) -> Option<EffectiveAuthenticationType> {
    match auth_type {
        Some(common_enums::DecoupledAuthenticationType::Challenge) => {
            Some(EffectiveAuthenticationType::CH)
        }
        Some(common_enums::DecoupledAuthenticationType::Frictionless) => {
            Some(EffectiveAuthenticationType::FR)
        }
        None => None,
    }
}

impl
    TryFrom<(
        &CybersourceRouterData<&PaymentsAuthorizeRouterData>,
        hyperswitch_domain_models::payment_method_data::Card,
    )> for CybersourcePaymentsRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        (item, ccard): (
            &CybersourceRouterData<&PaymentsAuthorizeRouterData>,
            hyperswitch_domain_models::payment_method_data::Card,
        ),
    ) -> Result<Self, Self::Error> {

Review comment (suggestion):
Instead of taking an optional value, you can always take strict type and can handle the option in caller with map. And, use from conversion

Code after:
                }),
                postal_code: addr.zip.remove_new_line(),
                country: addr.country,
                email,
            })
        })
        .unwrap_or(default_address))
}

fn convert_metadata_to_merchant_defined_info(metadata: Value) -> Vec<MerchantDefinedInformation> {
    let hashmap: std::collections::BTreeMap<String, Value> =
        serde_json::from_str(&metadata.to_string()).unwrap_or(std::collections::BTreeMap::new());
    let mut vector = Vec::new();
    let mut iter = 1;
    for (key, value) in hashmap {
        vector.push(MerchantDefinedInformation {
            key: iter,
            value: format!("{key}={value}"),
        });
        iter += 1;
    }
    vector
}

impl From<common_enums::DecoupledAuthenticationType> for EffectiveAuthenticationType {
    fn from(auth_type: common_enums::DecoupledAuthenticationType) -> Self {
        match auth_type {
            common_enums::DecoupledAuthenticationType::Challenge => Self::CH,
            common_enums::DecoupledAuthenticationType::Frictionless => Self::FR,
        }
    }
}

impl
    TryFrom<(
        &CybersourceRouterData<&PaymentsAuthorizeRouterData>,
        hyperswitch_domain_models::payment_method_data::Card,
    )> for CybersourcePaymentsRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        (item, ccard): (
            &CybersourceRouterData<&PaymentsAuthorizeRouterData>,
            hyperswitch_domain_models::payment_method_data::Card,
        ),
    ) -> Result<Self, Self::Error> {
        let email = item
            .router_data
            .get_billing_email()
            .or(item.router_data.request.get_email())?;
        let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?;