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

Code before:
        Ok(Self {
            acceptance_type: acceptance_type.into(),
            accepted_at: customer_acceptance
                .accepted_at
                .map(|dt| dt.assume_utc().unix_timestamp())
                .unwrap_or_default(),
            online_mandate_details,
        })
    }
}

impl ForeignTryFrom<Option<u32>> for u16 {
    type Error = error_stack::Report<UnifiedConnectorServiceError>;

    fn foreign_try_from(status_code: Option<u32>) -> Result<Self, Self::Error> {
        let code = status_code.unwrap_or(500);

        Self::try_from(code).map_err(|err| {
            UnifiedConnectorServiceError::RequestEncodingFailedWithReason(format!(
                "Failed to convert status code to u16: {}",
                err
            ))
            .into()
        })
    }
}


Review comment (suggestion):
This implementation looks like a very generic `Option<u32>` -> `u16` conversion implementation at first glance. This does not convey that we are trying to transform a status code stored in a `u32` (I'm guessing this is coming from gRPC) to `u16`. Let's avoid writing such generic-looking implementations which only solve a specific use case of ours (because this trait implementation would be available throughout the `router` crate, even where it's not relevant).

Write this as a function instead. It could be called `convert_connector_service_status_code()` for example.

Code after:
        match future_usage {
            storage_enums::FutureUsage::OnSession => Ok(Self::OnSession),
            storage_enums::FutureUsage::OffSession => Ok(Self::OffSession),
        }
    }
}

impl ForeignTryFrom<common_types::payments::CustomerAcceptance>
    for payments_grpc::CustomerAcceptance
{
    type Error = error_stack::Report<UnifiedConnectorServiceError>;

    fn foreign_try_from(
        customer_acceptance: common_types::payments::CustomerAcceptance,
    ) -> Result<Self, Self::Error> {
        let acceptance_type = match customer_acceptance.acceptance_type {
            common_types::payments::AcceptanceType::Online => payments_grpc::AcceptanceType::Online,
            common_types::payments::AcceptanceType::Offline => {
                payments_grpc::AcceptanceType::Offline
            }
        };

        let online_mandate_details =
            customer_acceptance
                .online
                .map(|online| payments_grpc::OnlineMandate {
                    ip_address: online.ip_address.map(|ip| ip.peek().to_string()),
                    user_agent: online.user_agent,
                });

        Ok(Self {
            acceptance_type: acceptance_type.into(),
            accepted_at: customer_acceptance
                .accepted_at
                .map(|dt| dt.assume_utc().unix_timestamp())
                .unwrap_or_default(),
            online_mandate_details,
        })
    }
}

pub fn convert_connector_service_status_code(
    status_code: u32,
) -> Result<u16, error_stack::Report<UnifiedConnectorServiceError>> {
    u16::try_from(status_code).map_err(|err| {
        UnifiedConnectorServiceError::RequestEncodingFailedWithReason(format!(
            "Failed to convert connector service status code to u16: {err}"
        ))
        .into()
    })
}