use serde::{Deserialize, Serialize};
pub const SDK_NAME: &str = "pakasir-sdk";
pub const SDK_VERSION: &str = env!("CARGO_PKG_VERSION");
pub const SDK_REPOSITORY: &str = "https://github.com/H0llyW00dzZ/pakasir-rust-sdk";
pub const PATH_TRANSACTION_CREATE: &str = "/api/transactioncreate";
pub const PATH_TRANSACTION_CANCEL: &str = "/api/transactioncancel";
pub const PATH_TRANSACTION_DETAIL: &str = "/api/transactiondetail";
pub const PATH_PAYMENT_SIMULATION: &str = "/api/paymentsimulation";
pub fn user_agent() -> String {
format!("{SDK_NAME}/{SDK_VERSION} (+{SDK_REPOSITORY})")
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum PaymentMethod {
#[serde(rename = "cimb_niaga_va")]
CimbNiagaVa,
#[serde(rename = "bni_va")]
BniVa,
#[serde(rename = "qris")]
Qris,
#[serde(rename = "sampoerna_va")]
SampoernaVa,
#[serde(rename = "bnc_va")]
BncVa,
#[serde(rename = "maybank_va")]
MaybankVa,
#[serde(rename = "permata_va")]
PermataVa,
#[serde(rename = "atm_bersama_va")]
AtmBersamaVa,
#[serde(rename = "artha_graha_va")]
ArthaGrahaVa,
#[serde(rename = "bri_va")]
BriVa,
#[serde(rename = "paypal")]
Paypal,
}
impl PaymentMethod {
pub fn as_str(self) -> &'static str {
match self {
Self::CimbNiagaVa => "cimb_niaga_va",
Self::BniVa => "bni_va",
Self::Qris => "qris",
Self::SampoernaVa => "sampoerna_va",
Self::BncVa => "bnc_va",
Self::MaybankVa => "maybank_va",
Self::PermataVa => "permata_va",
Self::AtmBersamaVa => "atm_bersama_va",
Self::ArthaGrahaVa => "artha_graha_va",
Self::BriVa => "bri_va",
Self::Paypal => "paypal",
}
}
}
impl core::fmt::Display for PaymentMethod {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum TransactionStatus {
#[serde(rename = "completed")]
Completed,
#[serde(rename = "pending")]
Pending,
#[serde(rename = "expired")]
Expired,
#[serde(rename = "cancelled")]
Cancelled,
#[serde(rename = "canceled")]
Canceled,
}
impl TransactionStatus {
pub fn as_str(self) -> &'static str {
match self {
Self::Completed => "completed",
Self::Pending => "pending",
Self::Expired => "expired",
Self::Cancelled => "cancelled",
Self::Canceled => "canceled",
}
}
}
impl core::fmt::Display for TransactionStatus {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn user_agent_has_expected_shape() {
let ua = user_agent();
assert!(ua.starts_with(&format!("{SDK_NAME}/{SDK_VERSION}")));
assert!(ua.contains(SDK_REPOSITORY));
assert!(ua.ends_with(")"));
}
#[test]
fn payment_method_as_str_covers_every_variant() {
let cases = [
(PaymentMethod::CimbNiagaVa, "cimb_niaga_va"),
(PaymentMethod::BniVa, "bni_va"),
(PaymentMethod::Qris, "qris"),
(PaymentMethod::SampoernaVa, "sampoerna_va"),
(PaymentMethod::BncVa, "bnc_va"),
(PaymentMethod::MaybankVa, "maybank_va"),
(PaymentMethod::PermataVa, "permata_va"),
(PaymentMethod::AtmBersamaVa, "atm_bersama_va"),
(PaymentMethod::ArthaGrahaVa, "artha_graha_va"),
(PaymentMethod::BriVa, "bri_va"),
(PaymentMethod::Paypal, "paypal"),
];
for (variant, wire) in cases {
assert_eq!(variant.as_str(), wire);
assert_eq!(format!("{variant}"), wire);
}
}
#[test]
fn transaction_status_as_str_covers_every_variant() {
let cases = [
(TransactionStatus::Completed, "completed"),
(TransactionStatus::Pending, "pending"),
(TransactionStatus::Expired, "expired"),
(TransactionStatus::Cancelled, "cancelled"),
(TransactionStatus::Canceled, "canceled"),
];
for (variant, wire) in cases {
assert_eq!(variant.as_str(), wire);
assert_eq!(format!("{variant}"), wire);
}
}
}