Bug: Use `frunk` deriving mechanisms to reduce boilerplate



https://github.com/juspay/orca/blob/dddc9eaf1430adcd1293933e726c2f4f296c805b/crates/router/src/types/transformers.rs#L5-L14

Why not just use [frunk](https://crates.io/crates/frunk)?

Here's an example:
```rust
use frunk::LabelledGeneric;

#[derive(LabelledGeneric)]
enum ApiRoutingAlgorithm {
    RoundRobin,
    MaxConversion,
    MinCost,
    Custom,
}

#[derive(LabelledGeneric, PartialEq, Debug)]
enum RoutingAlgorithm {
    RoundRobin,
    MaxConversion,
    MinCost,
    Custom,
}

fn main() {
    let api_algorithm = ApiRoutingAlgorithm::MinCost;
    let algorithm: RoutingAlgorithm = frunk::labelled_convert_from(api_algorithm);

    assert_eq!(algorithm, RoutingAlgorithm::MinCost);
}
```
diff --git a/Cargo.lock b/Cargo.lock
index 2d426b834c6..bb6e24c2b93 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -312,6 +312,8 @@ name = "api_models"
 version = "0.1.0"
 dependencies = [
  "common_utils",
+ "frunk",
+ "frunk_core",
  "masking",
  "router_derive",
  "serde",
@@ -1302,6 +1304,70 @@ dependencies = [
  "url",
 ]
 
+[[package]]
+name = "frunk"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a89c703bf50009f383a0873845357cc400a95fc535f836feddfe015d7df6e1e0"
+dependencies = [
+ "frunk_core",
+ "frunk_derives",
+ "frunk_proc_macros",
+]
+
+[[package]]
+name = "frunk_core"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a446d01a558301dca28ef43222864a9fa2bd9a2e71370f769d5d5d5ec9f3537"
+
+[[package]]
+name = "frunk_derives"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b83164912bb4c97cfe0772913c7af7387ee2e00cb6d4636fb65a35b3d0c8f173"
+dependencies = [
+ "frunk_proc_macro_helpers",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "frunk_proc_macro_helpers"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "015425591bbeb0f5b8a75593340f1789af428e9f887a4f1e36c0c471f067ef50"
+dependencies = [
+ "frunk_core",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "frunk_proc_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea01524f285deab48affffb342b97f186e657b119c3f1821ac531780e0fbfae0"
+dependencies = [
+ "frunk_core",
+ "frunk_proc_macros_impl",
+ "proc-macro-hack",
+]
+
+[[package]]
+name = "frunk_proc_macros_impl"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a802d974cc18ee7fe1a7868fc9ce31086294fd96ba62f8da64ecb44e92a2653"
+dependencies = [
+ "frunk_core",
+ "frunk_proc_macro_helpers",
+ "proc-macro-hack",
+ "quote",
+ "syn",
+]
+
 [[package]]
 name = "futures"
 version = "0.3.25"
@@ -2348,6 +2414,12 @@ dependencies = [
  "version_check",
 ]
 
+[[package]]
+name = "proc-macro-hack"
+version = "0.5.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
+
 [[package]]
 name = "proc-macro2"
 version = "1.0.47"
@@ -2631,6 +2703,8 @@ dependencies = [
  "dyn-clone",
  "encoding_rs",
  "error-stack",
+ "frunk",
+ "frunk_core",
  "futures",
  "hex",
  "http",
@@ -3016,6 +3090,8 @@ dependencies = [
  "common_utils",
  "diesel",
  "error-stack",
+ "frunk",
+ "frunk_core",
  "hex",
  "masking",
  "router_derive",
diff --git a/crates/api_models/Cargo.toml b/crates/api_models/Cargo.toml
index adcb63e16b9..4ef5206b8ae 100644
--- a/crates/api_models/Cargo.toml
+++ b/crates/api_models/Cargo.toml
@@ -6,6 +6,8 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+frunk = "0.4.1"
+frunk_core = "0.4.1"
 serde = { version = "1.0.145", features = ["derive"] }
 serde_json = "1.0.85"
 strum = { version = "0.24.1", features = ["derive"] }
diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs
index b7738d8b075..01b79e688e1 100644
--- a/crates/api_models/src/enums.rs
+++ b/crates/api_models/src/enums.rs
@@ -48,6 +48,7 @@ pub enum AttemptStatus {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
@@ -68,6 +69,7 @@ pub enum AuthenticationType {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
@@ -89,6 +91,7 @@ pub enum CaptureMethod {
     strum::EnumString,
     serde::Deserialize,
     serde::Serialize,
+    frunk::LabelledGeneric,
 )]
 #[strum(serialize_all = "snake_case")]
 #[serde(rename_all = "snake_case")]
@@ -122,6 +125,7 @@ pub enum ConnectorType {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 pub enum Currency {
     AED,
@@ -240,6 +244,7 @@ pub enum Currency {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
@@ -258,6 +263,7 @@ pub enum EventType {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
@@ -284,6 +290,7 @@ pub enum IntentStatus {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
@@ -304,6 +311,7 @@ pub enum FutureUsage {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 #[strum(serialize_all = "snake_case")]
 #[serde(rename_all = "snake_case")]
@@ -331,6 +339,7 @@ pub enum PaymentMethodIssuerCode {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
@@ -355,6 +364,7 @@ pub enum PaymentMethodSubType {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
@@ -393,7 +403,17 @@ pub enum WalletIssuer {
     ApplePay,
 }
 
-#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, strum::Display, strum::EnumString)]
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    Default,
+    Eq,
+    PartialEq,
+    strum::Display,
+    strum::EnumString,
+    frunk::LabelledGeneric,
+)]
 #[strum(serialize_all = "snake_case")]
 pub enum RefundStatus {
     Failure,
@@ -414,6 +434,7 @@ pub enum RefundStatus {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
@@ -435,6 +456,7 @@ pub enum RoutingAlgorithm {
     serde::Serialize,
     strum::Display,
     strum::EnumString,
+    frunk::LabelledGeneric,
 )]
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index ffa30426599..fb5f287333d 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -270,7 +270,16 @@ impl Default for PaymentIdType {
 //}
 //}
 
-#[derive(Default, Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
+#[derive(
+    Default,
+    Clone,
+    Debug,
+    Eq,
+    PartialEq,
+    serde::Deserialize,
+    serde::Serialize,
+    frunk::LabelledGeneric,
+)]
 #[serde(deny_unknown_fields)]
 pub struct Address {
     pub address: Option<AddressDetails>,
@@ -278,7 +287,16 @@ pub struct Address {
 }
 
 // used by customers also, could be moved outside
-#[derive(Clone, Default, Debug, Eq, serde::Deserialize, serde::Serialize, PartialEq)]
+#[derive(
+    Clone,
+    Default,
+    Debug,
+    Eq,
+    serde::Deserialize,
+    serde::Serialize,
+    PartialEq,
+    frunk::LabelledGeneric,
+)]
 #[serde(deny_unknown_fields)]
 pub struct AddressDetails {
     pub city: Option<String>,
@@ -292,7 +310,16 @@ pub struct AddressDetails {
     pub last_name: Option<Secret<String>>,
 }
 
-#[derive(Debug, Clone, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
+#[derive(
+    Debug,
+    Clone,
+    Default,
+    Eq,
+    PartialEq,
+    serde::Deserialize,
+    serde::Serialize,
+    frunk::LabelledGeneric,
+)]
 pub struct PhoneDetails {
     pub number: Option<Secret<String>>,
     pub country_code: Option<String>,
diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml
index ce973cd2092..e25e9225490 100644
--- a/crates/router/Cargo.toml
+++ b/crates/router/Cargo.toml
@@ -37,6 +37,8 @@ diesel = { git = "https://github.com/juspay/diesel", features = ["postgres", "se
 dyn-clone = "1.0.9"
 encoding_rs = "0.8.31"
 error-stack = "0.2.4"
+frunk = "0.4.1"
+frunk_core = "0.4.1"
 futures = "0.3.25"
 hex = "0.4.3"
 http = "0.2.8"
diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs
index 9b6bad04baa..5fb459b0282 100644
--- a/crates/router/src/types/transformers.rs
+++ b/crates/router/src/types/transformers.rs
@@ -88,273 +88,73 @@ where
 
 impl From<F<api_enums::RoutingAlgorithm>> for F<storage_enums::RoutingAlgorithm> {
     fn from(algo: F<api_enums::RoutingAlgorithm>) -> Self {
-        match algo.0 {
-            api_enums::RoutingAlgorithm::RoundRobin => storage_enums::RoutingAlgorithm::RoundRobin,
-            api_enums::RoutingAlgorithm::MaxConversion => {
-                storage_enums::RoutingAlgorithm::MaxConversion
-            }
-            api_enums::RoutingAlgorithm::MinCost => storage_enums::RoutingAlgorithm::MinCost,
-            api_enums::RoutingAlgorithm::Custom => storage_enums::RoutingAlgorithm::Custom,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(algo.0))
     }
 }
 
 impl From<F<storage_enums::RoutingAlgorithm>> for F<api_enums::RoutingAlgorithm> {
     fn from(algo: F<storage_enums::RoutingAlgorithm>) -> Self {
-        match algo.0 {
-            storage_enums::RoutingAlgorithm::RoundRobin => api_enums::RoutingAlgorithm::RoundRobin,
-            storage_enums::RoutingAlgorithm::MaxConversion => {
-                api_enums::RoutingAlgorithm::MaxConversion
-            }
-            storage_enums::RoutingAlgorithm::MinCost => api_enums::RoutingAlgorithm::MinCost,
-            storage_enums::RoutingAlgorithm::Custom => api_enums::RoutingAlgorithm::Custom,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(algo.0))
     }
 }
 
 impl From<F<api_enums::ConnectorType>> for F<storage_enums::ConnectorType> {
     fn from(conn: F<api_enums::ConnectorType>) -> Self {
-        match conn.0 {
-            api_enums::ConnectorType::PaymentProcessor => {
-                storage_enums::ConnectorType::PaymentProcessor
-            }
-            api_enums::ConnectorType::PaymentVas => storage_enums::ConnectorType::PaymentVas,
-            api_enums::ConnectorType::FinOperations => storage_enums::ConnectorType::FinOperations,
-            api_enums::ConnectorType::FizOperations => storage_enums::ConnectorType::FizOperations,
-            api_enums::ConnectorType::Networks => storage_enums::ConnectorType::Networks,
-            api_enums::ConnectorType::BankingEntities => {
-                storage_enums::ConnectorType::BankingEntities
-            }
-            api_enums::ConnectorType::NonBankingFinance => {
-                storage_enums::ConnectorType::NonBankingFinance
-            }
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(conn.0))
     }
 }
 
 impl From<F<storage_enums::ConnectorType>> for F<api_enums::ConnectorType> {
     fn from(conn: F<storage_enums::ConnectorType>) -> Self {
-        match conn.0 {
-            storage_enums::ConnectorType::PaymentProcessor => {
-                api_enums::ConnectorType::PaymentProcessor
-            }
-            storage_enums::ConnectorType::PaymentVas => api_enums::ConnectorType::PaymentVas,
-            storage_enums::ConnectorType::FinOperations => api_enums::ConnectorType::FinOperations,
-            storage_enums::ConnectorType::FizOperations => api_enums::ConnectorType::FizOperations,
-            storage_enums::ConnectorType::Networks => api_enums::ConnectorType::Networks,
-            storage_enums::ConnectorType::BankingEntities => {
-                api_enums::ConnectorType::BankingEntities
-            }
-            storage_enums::ConnectorType::NonBankingFinance => {
-                api_enums::ConnectorType::NonBankingFinance
-            }
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(conn.0))
     }
 }
 
 impl From<F<storage_enums::MandateStatus>> for F<api_enums::MandateStatus> {
     fn from(status: F<storage_enums::MandateStatus>) -> Self {
-        match status.0 {
-            storage_enums::MandateStatus::Active => api_enums::MandateStatus::Active,
-            storage_enums::MandateStatus::Inactive => api_enums::MandateStatus::Inactive,
-            storage_enums::MandateStatus::Pending => api_enums::MandateStatus::Pending,
-            storage_enums::MandateStatus::Revoked => api_enums::MandateStatus::Revoked,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(status.0))
     }
 }
 
 impl From<F<api_enums::PaymentMethodType>> for F<storage_enums::PaymentMethodType> {
     fn from(pm_type: F<api_enums::PaymentMethodType>) -> Self {
-        match pm_type.0 {
-            api_enums::PaymentMethodType::Card => storage_enums::PaymentMethodType::Card,
-            api_enums::PaymentMethodType::PaymentContainer => {
-                storage_enums::PaymentMethodType::PaymentContainer
-            }
-            api_enums::PaymentMethodType::BankTransfer => {
-                storage_enums::PaymentMethodType::BankTransfer
-            }
-            api_enums::PaymentMethodType::BankDebit => storage_enums::PaymentMethodType::BankDebit,
-            api_enums::PaymentMethodType::PayLater => storage_enums::PaymentMethodType::PayLater,
-            api_enums::PaymentMethodType::Netbanking => {
-                storage_enums::PaymentMethodType::Netbanking
-            }
-            api_enums::PaymentMethodType::Upi => storage_enums::PaymentMethodType::Upi,
-            api_enums::PaymentMethodType::OpenBanking => {
-                storage_enums::PaymentMethodType::OpenBanking
-            }
-            api_enums::PaymentMethodType::ConsumerFinance => {
-                storage_enums::PaymentMethodType::ConsumerFinance
-            }
-            api_enums::PaymentMethodType::Wallet => storage_enums::PaymentMethodType::Wallet,
-            api_enums::PaymentMethodType::Klarna => storage_enums::PaymentMethodType::Klarna,
-            api_enums::PaymentMethodType::Paypal => storage_enums::PaymentMethodType::Paypal,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(pm_type.0))
     }
 }
 
 impl From<F<storage_enums::PaymentMethodType>> for F<api_enums::PaymentMethodType> {
     fn from(pm_type: F<storage_enums::PaymentMethodType>) -> Self {
-        match pm_type.0 {
-            storage_enums::PaymentMethodType::Card => api_enums::PaymentMethodType::Card,
-            storage_enums::PaymentMethodType::PaymentContainer => {
-                api_enums::PaymentMethodType::PaymentContainer
-            }
-            storage_enums::PaymentMethodType::BankTransfer => {
-                api_enums::PaymentMethodType::BankTransfer
-            }
-            storage_enums::PaymentMethodType::BankDebit => api_enums::PaymentMethodType::BankDebit,
-            storage_enums::PaymentMethodType::PayLater => api_enums::PaymentMethodType::PayLater,
-            storage_enums::PaymentMethodType::Netbanking => {
-                api_enums::PaymentMethodType::Netbanking
-            }
-            storage_enums::PaymentMethodType::Upi => api_enums::PaymentMethodType::Upi,
-            storage_enums::PaymentMethodType::OpenBanking => {
-                api_enums::PaymentMethodType::OpenBanking
-            }
-            storage_enums::PaymentMethodType::ConsumerFinance => {
-                api_enums::PaymentMethodType::ConsumerFinance
-            }
-            storage_enums::PaymentMethodType::Wallet => api_enums::PaymentMethodType::Wallet,
-            storage_enums::PaymentMethodType::Klarna => api_enums::PaymentMethodType::Klarna,
-            storage_enums::PaymentMethodType::Paypal => api_enums::PaymentMethodType::Paypal,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(pm_type.0))
     }
 }
 
 impl From<F<api_enums::PaymentMethodSubType>> for F<storage_enums::PaymentMethodSubType> {
     fn from(pm_subtype: F<api_enums::PaymentMethodSubType>) -> Self {
-        match pm_subtype.0 {
-            api_enums::PaymentMethodSubType::Credit => storage_enums::PaymentMethodSubType::Credit,
-            api_enums::PaymentMethodSubType::Debit => storage_enums::PaymentMethodSubType::Debit,
-            api_enums::PaymentMethodSubType::UpiIntent => {
-                storage_enums::PaymentMethodSubType::UpiIntent
-            }
-            api_enums::PaymentMethodSubType::UpiCollect => {
-                storage_enums::PaymentMethodSubType::UpiCollect
-            }
-            api_enums::PaymentMethodSubType::CreditCardInstallments => {
-                storage_enums::PaymentMethodSubType::CreditCardInstallments
-            }
-            api_enums::PaymentMethodSubType::PayLaterInstallments => {
-                storage_enums::PaymentMethodSubType::PayLaterInstallments
-            }
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(pm_subtype.0))
     }
 }
 
 impl From<F<storage_enums::PaymentMethodSubType>> for F<api_enums::PaymentMethodSubType> {
     fn from(pm_subtype: F<storage_enums::PaymentMethodSubType>) -> Self {
-        match pm_subtype.0 {
-            storage_enums::PaymentMethodSubType::Credit => api_enums::PaymentMethodSubType::Credit,
-            storage_enums::PaymentMethodSubType::Debit => api_enums::PaymentMethodSubType::Debit,
-            storage_enums::PaymentMethodSubType::UpiIntent => {
-                api_enums::PaymentMethodSubType::UpiIntent
-            }
-            storage_enums::PaymentMethodSubType::UpiCollect => {
-                api_enums::PaymentMethodSubType::UpiCollect
-            }
-            storage_enums::PaymentMethodSubType::CreditCardInstallments => {
-                api_enums::PaymentMethodSubType::CreditCardInstallments
-            }
-            storage_enums::PaymentMethodSubType::PayLaterInstallments => {
-                api_enums::PaymentMethodSubType::PayLaterInstallments
-            }
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(pm_subtype.0))
     }
 }
 
 impl From<F<storage_enums::PaymentMethodIssuerCode>> for F<api_enums::PaymentMethodIssuerCode> {
     fn from(issuer_code: F<storage_enums::PaymentMethodIssuerCode>) -> Self {
-        match issuer_code.0 {
-            storage_enums::PaymentMethodIssuerCode::JpHdfc => {
-                api_enums::PaymentMethodIssuerCode::JpHdfc
-            }
-            storage_enums::PaymentMethodIssuerCode::JpIcici => {
-                api_enums::PaymentMethodIssuerCode::JpIcici
-            }
-            storage_enums::PaymentMethodIssuerCode::JpGooglepay => {
-                api_enums::PaymentMethodIssuerCode::JpGooglepay
-            }
-            storage_enums::PaymentMethodIssuerCode::JpApplepay => {
-                api_enums::PaymentMethodIssuerCode::JpApplepay
-            }
-            storage_enums::PaymentMethodIssuerCode::JpPhonepay => {
-                api_enums::PaymentMethodIssuerCode::JpPhonepay
-            }
-            storage_enums::PaymentMethodIssuerCode::JpWechat => {
-                api_enums::PaymentMethodIssuerCode::JpWechat
-            }
-            storage_enums::PaymentMethodIssuerCode::JpSofort => {
-                api_enums::PaymentMethodIssuerCode::JpSofort
-            }
-            storage_enums::PaymentMethodIssuerCode::JpGiropay => {
-                api_enums::PaymentMethodIssuerCode::JpGiropay
-            }
-            storage_enums::PaymentMethodIssuerCode::JpSepa => {
-                api_enums::PaymentMethodIssuerCode::JpSepa
-            }
-            storage_enums::PaymentMethodIssuerCode::JpBacs => {
-                api_enums::PaymentMethodIssuerCode::JpBacs
-            }
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(issuer_code.0))
     }
 }
 
 impl From<F<storage_enums::IntentStatus>> for F<api_enums::IntentStatus> {
     fn from(status: F<storage_enums::IntentStatus>) -> Self {
-        match status.0 {
-            storage_enums::IntentStatus::Succeeded => api_enums::IntentStatus::Succeeded,
-            storage_enums::IntentStatus::Failed => api_enums::IntentStatus::Failed,
-            storage_enums::IntentStatus::Cancelled => api_enums::IntentStatus::Cancelled,
-            storage_enums::IntentStatus::Processing => api_enums::IntentStatus::Processing,
-            storage_enums::IntentStatus::RequiresCustomerAction => {
-                api_enums::IntentStatus::RequiresCustomerAction
-            }
-            storage_enums::IntentStatus::RequiresPaymentMethod => {
-                api_enums::IntentStatus::RequiresPaymentMethod
-            }
-            storage_enums::IntentStatus::RequiresConfirmation => {
-                api_enums::IntentStatus::RequiresConfirmation
-            }
-            storage_enums::IntentStatus::RequiresCapture => {
-                api_enums::IntentStatus::RequiresCapture
-            }
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(status.0))
     }
 }
 
 impl From<F<api_enums::IntentStatus>> for F<storage_enums::IntentStatus> {
     fn from(status: F<api_enums::IntentStatus>) -> Self {
-        match status.0 {
-            api_enums::IntentStatus::Succeeded => storage_enums::IntentStatus::Succeeded,
-            api_enums::IntentStatus::Failed => storage_enums::IntentStatus::Failed,
-            api_enums::IntentStatus::Cancelled => storage_enums::IntentStatus::Cancelled,
-            api_enums::IntentStatus::Processing => storage_enums::IntentStatus::Processing,
-            api_enums::IntentStatus::RequiresCustomerAction => {
-                storage_enums::IntentStatus::RequiresCustomerAction
-            }
-            api_enums::IntentStatus::RequiresPaymentMethod => {
-                storage_enums::IntentStatus::RequiresPaymentMethod
-            }
-            api_enums::IntentStatus::RequiresConfirmation => {
-                storage_enums::IntentStatus::RequiresConfirmation
-            }
-            api_enums::IntentStatus::RequiresCapture => {
-                storage_enums::IntentStatus::RequiresCapture
-            }
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(status.0))
     }
 }
 
@@ -416,208 +216,55 @@ impl TryFrom<F<api_enums::IntentStatus>> for F<storage_enums::EventType> {
 
 impl From<F<storage_enums::EventType>> for F<api_enums::EventType> {
     fn from(event_type: F<storage_enums::EventType>) -> Self {
-        match event_type.0 {
-            storage_enums::EventType::PaymentSucceeded => api_enums::EventType::PaymentSucceeded,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(event_type.0))
     }
 }
 
 impl From<F<api_enums::FutureUsage>> for F<storage_enums::FutureUsage> {
     fn from(future_usage: F<api_enums::FutureUsage>) -> Self {
-        match future_usage.0 {
-            api_enums::FutureUsage::OnSession => storage_enums::FutureUsage::OnSession,
-            api_enums::FutureUsage::OffSession => storage_enums::FutureUsage::OffSession,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(future_usage.0))
     }
 }
 
 impl From<F<storage_enums::FutureUsage>> for F<api_enums::FutureUsage> {
     fn from(future_usage: F<storage_enums::FutureUsage>) -> Self {
-        match future_usage.0 {
-            storage_enums::FutureUsage::OnSession => api_enums::FutureUsage::OnSession,
-            storage_enums::FutureUsage::OffSession => api_enums::FutureUsage::OffSession,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(future_usage.0))
     }
 }
 
 impl From<F<storage_enums::RefundStatus>> for F<api_enums::RefundStatus> {
     fn from(status: F<storage_enums::RefundStatus>) -> Self {
-        match status.0 {
-            storage_enums::RefundStatus::Failure => api_enums::RefundStatus::Failure,
-            storage_enums::RefundStatus::ManualReview => api_enums::RefundStatus::ManualReview,
-            storage_enums::RefundStatus::Pending => api_enums::RefundStatus::Pending,
-            storage_enums::RefundStatus::Success => api_enums::RefundStatus::Success,
-            storage_enums::RefundStatus::TransactionFailure => {
-                api_enums::RefundStatus::TransactionFailure
-            }
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(status.0))
     }
 }
 
 impl From<F<api_enums::CaptureMethod>> for F<storage_enums::CaptureMethod> {
     fn from(capture_method: F<api_enums::CaptureMethod>) -> Self {
-        match capture_method.0 {
-            api_enums::CaptureMethod::Automatic => storage_enums::CaptureMethod::Automatic,
-            api_enums::CaptureMethod::Manual => storage_enums::CaptureMethod::Manual,
-            api_enums::CaptureMethod::ManualMultiple => {
-                storage_enums::CaptureMethod::ManualMultiple
-            }
-            api_enums::CaptureMethod::Scheduled => storage_enums::CaptureMethod::Scheduled,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(capture_method.0))
     }
 }
 
 impl From<F<storage_enums::CaptureMethod>> for F<api_enums::CaptureMethod> {
     fn from(capture_method: F<storage_enums::CaptureMethod>) -> Self {
-        match capture_method.0 {
-            storage_enums::CaptureMethod::Automatic => api_enums::CaptureMethod::Automatic,
-            storage_enums::CaptureMethod::Manual => api_enums::CaptureMethod::Manual,
-            storage_enums::CaptureMethod::ManualMultiple => {
-                api_enums::CaptureMethod::ManualMultiple
-            }
-            storage_enums::CaptureMethod::Scheduled => api_enums::CaptureMethod::Scheduled,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(capture_method.0))
     }
 }
 
 impl From<F<api_enums::AuthenticationType>> for F<storage_enums::AuthenticationType> {
     fn from(auth_type: F<api_enums::AuthenticationType>) -> Self {
-        match auth_type.0 {
-            api_enums::AuthenticationType::ThreeDs => storage_enums::AuthenticationType::ThreeDs,
-            api_enums::AuthenticationType::NoThreeDs => {
-                storage_enums::AuthenticationType::NoThreeDs
-            }
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(auth_type.0))
     }
 }
 
 impl From<F<storage_enums::AuthenticationType>> for F<api_enums::AuthenticationType> {
     fn from(auth_type: F<storage_enums::AuthenticationType>) -> Self {
-        match auth_type.0 {
-            storage_enums::AuthenticationType::ThreeDs => api_enums::AuthenticationType::ThreeDs,
-            storage_enums::AuthenticationType::NoThreeDs => {
-                api_enums::AuthenticationType::NoThreeDs
-            }
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(auth_type.0))
     }
 }
 
 impl From<F<api_enums::Currency>> for F<storage_enums::Currency> {
     fn from(currency: F<api_enums::Currency>) -> Self {
-        match currency.0 {
-            api_enums::Currency::AED => storage_enums::Currency::AED,
-            api_enums::Currency::ALL => storage_enums::Currency::ALL,
-            api_enums::Currency::AMD => storage_enums::Currency::AMD,
-            api_enums::Currency::ARS => storage_enums::Currency::ARS,
-            api_enums::Currency::AUD => storage_enums::Currency::AUD,
-            api_enums::Currency::AWG => storage_enums::Currency::AWG,
-            api_enums::Currency::AZN => storage_enums::Currency::AZN,
-            api_enums::Currency::BBD => storage_enums::Currency::BBD,
-            api_enums::Currency::BDT => storage_enums::Currency::BDT,
-            api_enums::Currency::BHD => storage_enums::Currency::BHD,
-            api_enums::Currency::BMD => storage_enums::Currency::BMD,
-            api_enums::Currency::BND => storage_enums::Currency::BND,
-            api_enums::Currency::BOB => storage_enums::Currency::BOB,
-            api_enums::Currency::BRL => storage_enums::Currency::BRL,
-            api_enums::Currency::BSD => storage_enums::Currency::BSD,
-            api_enums::Currency::BWP => storage_enums::Currency::BWP,
-            api_enums::Currency::BZD => storage_enums::Currency::BZD,
-            api_enums::Currency::CAD => storage_enums::Currency::CAD,
-            api_enums::Currency::CHF => storage_enums::Currency::CHF,
-            api_enums::Currency::CNY => storage_enums::Currency::CNY,
-            api_enums::Currency::COP => storage_enums::Currency::COP,
-            api_enums::Currency::CRC => storage_enums::Currency::CRC,
-            api_enums::Currency::CUP => storage_enums::Currency::CUP,
-            api_enums::Currency::CZK => storage_enums::Currency::CZK,
-            api_enums::Currency::DKK => storage_enums::Currency::DKK,
-            api_enums::Currency::DOP => storage_enums::Currency::DOP,
-            api_enums::Currency::DZD => storage_enums::Currency::DZD,
-            api_enums::Currency::EGP => storage_enums::Currency::EGP,
-            api_enums::Currency::ETB => storage_enums::Currency::ETB,
-            api_enums::Currency::EUR => storage_enums::Currency::EUR,
-            api_enums::Currency::FJD => storage_enums::Currency::FJD,
-            api_enums::Currency::GBP => storage_enums::Currency::GBP,
-            api_enums::Currency::GHS => storage_enums::Currency::GHS,
-            api_enums::Currency::GIP => storage_enums::Currency::GIP,
-            api_enums::Currency::GMD => storage_enums::Currency::GMD,
-            api_enums::Currency::GTQ => storage_enums::Currency::GTQ,
-            api_enums::Currency::GYD => storage_enums::Currency::GYD,
-            api_enums::Currency::HKD => storage_enums::Currency::HKD,
-            api_enums::Currency::HNL => storage_enums::Currency::HNL,
-            api_enums::Currency::HRK => storage_enums::Currency::HRK,
-            api_enums::Currency::HTG => storage_enums::Currency::HTG,
-            api_enums::Currency::HUF => storage_enums::Currency::HUF,
-            api_enums::Currency::IDR => storage_enums::Currency::IDR,
-            api_enums::Currency::ILS => storage_enums::Currency::ILS,
-            api_enums::Currency::INR => storage_enums::Currency::INR,
-            api_enums::Currency::JMD => storage_enums::Currency::JMD,
-            api_enums::Currency::JOD => storage_enums::Currency::JOD,
-            api_enums::Currency::JPY => storage_enums::Currency::JPY,
-            api_enums::Currency::KES => storage_enums::Currency::KES,
-            api_enums::Currency::KGS => storage_enums::Currency::KGS,
-            api_enums::Currency::KHR => storage_enums::Currency::KHR,
-            api_enums::Currency::KRW => storage_enums::Currency::KRW,
-            api_enums::Currency::KWD => storage_enums::Currency::KWD,
-            api_enums::Currency::KYD => storage_enums::Currency::KYD,
-            api_enums::Currency::KZT => storage_enums::Currency::KZT,
-            api_enums::Currency::LAK => storage_enums::Currency::LAK,
-            api_enums::Currency::LBP => storage_enums::Currency::LBP,
-            api_enums::Currency::LKR => storage_enums::Currency::LKR,
-            api_enums::Currency::LRD => storage_enums::Currency::LRD,
-            api_enums::Currency::LSL => storage_enums::Currency::LSL,
-            api_enums::Currency::MAD => storage_enums::Currency::MAD,
-            api_enums::Currency::MDL => storage_enums::Currency::MDL,
-            api_enums::Currency::MKD => storage_enums::Currency::MKD,
-            api_enums::Currency::MMK => storage_enums::Currency::MMK,
-            api_enums::Currency::MNT => storage_enums::Currency::MNT,
-            api_enums::Currency::MOP => storage_enums::Currency::MOP,
-            api_enums::Currency::MUR => storage_enums::Currency::MUR,
-            api_enums::Currency::MVR => storage_enums::Currency::MVR,
-            api_enums::Currency::MWK => storage_enums::Currency::MWK,
-            api_enums::Currency::MXN => storage_enums::Currency::MXN,
-            api_enums::Currency::MYR => storage_enums::Currency::MYR,
-            api_enums::Currency::NAD => storage_enums::Currency::NAD,
-            api_enums::Currency::NGN => storage_enums::Currency::NGN,
-            api_enums::Currency::NIO => storage_enums::Currency::NIO,
-            api_enums::Currency::NOK => storage_enums::Currency::NOK,
-            api_enums::Currency::NPR => storage_enums::Currency::NPR,
-            api_enums::Currency::NZD => storage_enums::Currency::NZD,
-            api_enums::Currency::OMR => storage_enums::Currency::OMR,
-            api_enums::Currency::PEN => storage_enums::Currency::PEN,
-            api_enums::Currency::PGK => storage_enums::Currency::PGK,
-            api_enums::Currency::PHP => storage_enums::Currency::PHP,
-            api_enums::Currency::PKR => storage_enums::Currency::PKR,
-            api_enums::Currency::PLN => storage_enums::Currency::PLN,
-            api_enums::Currency::QAR => storage_enums::Currency::QAR,
-            api_enums::Currency::RUB => storage_enums::Currency::RUB,
-            api_enums::Currency::SAR => storage_enums::Currency::SAR,
-            api_enums::Currency::SCR => storage_enums::Currency::SCR,
-            api_enums::Currency::SEK => storage_enums::Currency::SEK,
-            api_enums::Currency::SGD => storage_enums::Currency::SGD,
-            api_enums::Currency::SLL => storage_enums::Currency::SLL,
-            api_enums::Currency::SOS => storage_enums::Currency::SOS,
-            api_enums::Currency::SSP => storage_enums::Currency::SSP,
-            api_enums::Currency::SVC => storage_enums::Currency::SVC,
-            api_enums::Currency::SZL => storage_enums::Currency::SZL,
-            api_enums::Currency::THB => storage_enums::Currency::THB,
-            api_enums::Currency::TTD => storage_enums::Currency::TTD,
-            api_enums::Currency::TWD => storage_enums::Currency::TWD,
-            api_enums::Currency::TZS => storage_enums::Currency::TZS,
-            api_enums::Currency::USD => storage_enums::Currency::USD,
-            api_enums::Currency::UYU => storage_enums::Currency::UYU,
-            api_enums::Currency::UZS => storage_enums::Currency::UZS,
-            api_enums::Currency::YER => storage_enums::Currency::YER,
-            api_enums::Currency::ZAR => storage_enums::Currency::ZAR,
-        }
-        .into()
+        Foreign(frunk::labelled_convert_from(currency.0))
     }
 }
 
diff --git a/crates/storage_models/Cargo.toml b/crates/storage_models/Cargo.toml
index 620b084f689..2d0d2309ead 100644
--- a/crates/storage_models/Cargo.toml
+++ b/crates/storage_models/Cargo.toml
@@ -10,6 +10,8 @@ async-bb8-diesel = { git = "https://github.com/juspay/async-bb8-diesel", rev = "
 async-trait = "0.1.57"
 diesel = { git = "https://github.com/juspay/diesel", features = ["postgres", "serde_json", "time"], rev = "22f3f59f1db8a3f61623e4d6b375d64cd7bd3d02" }
 error-stack = "0.2.1"
+frunk = "0.4.1"
+frunk_core = "0.4.1"
 hex = "0.4.3"
 serde = { version = "1.0.145", features = ["derive"] }
 serde_json = "1.0.85"
diff --git a/crates/storage_models/src/address.rs b/crates/storage_models/src/address.rs
index af0a5f186b3..d45e74fa3d4 100644
--- a/crates/storage_models/src/address.rs
+++ b/crates/storage_models/src/address.rs
@@ -26,7 +26,7 @@ pub struct AddressNew {
     pub merchant_id: String,
 }
 
-#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)]
+#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable, frunk::LabelledGeneric)]
 #[diesel(table_name = address)]
 pub struct Address {
     #[serde(skip_serializing)]
@@ -54,7 +54,7 @@ pub struct Address {
     pub merchant_id: String,
 }
 
-#[derive(Debug)]
+#[derive(Debug, frunk::LabelledGeneric)]
 pub enum AddressUpdate {
     Update {
         city: Option<String>,
diff --git a/crates/storage_models/src/enums.rs b/crates/storage_models/src/enums.rs
index a44577fe06d..b49055f2683 100644
--- a/crates/storage_models/src/enums.rs
+++ b/crates/storage_models/src/enums.rs
@@ -67,6 +67,7 @@ pub enum AttemptStatus {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[serde(rename_all = "snake_case")]
@@ -89,6 +90,7 @@ pub enum AuthenticationType {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[serde(rename_all = "snake_case")]
@@ -112,6 +114,7 @@ pub enum CaptureMethod {
     serde::Deserialize,
     serde::Serialize,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[strum(serialize_all = "snake_case")]
@@ -147,6 +150,7 @@ pub enum ConnectorType {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 pub enum Currency {
@@ -305,6 +309,7 @@ pub enum EventObjectType {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[serde(rename_all = "snake_case")]
@@ -325,6 +330,7 @@ pub enum EventType {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[serde(rename_all = "snake_case")]
@@ -353,6 +359,7 @@ pub enum IntentStatus {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[serde(rename_all = "snake_case")]
@@ -421,6 +428,7 @@ pub enum PaymentFlow {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[strum(serialize_all = "snake_case")]
@@ -450,6 +458,7 @@ pub enum PaymentMethodIssuerCode {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[serde(rename_all = "snake_case")]
@@ -476,6 +485,7 @@ pub enum PaymentMethodSubType {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[serde(rename_all = "snake_case")]
@@ -555,6 +565,7 @@ pub enum ProcessTrackerStatus {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[strum(serialize_all = "snake_case")]
@@ -598,6 +609,7 @@ pub enum RefundType {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[serde(rename_all = "snake_case")]
 #[strum(serialize_all = "snake_case")]
@@ -644,6 +656,7 @@ pub enum MandateType {
     strum::Display,
     strum::EnumString,
     router_derive::DieselEnum,
+    frunk::LabelledGeneric,
 )]
 #[router_derive::diesel_enum]
 #[serde(rename_all = "snake_case")]

## Type of Change
- [x] Refactoring

## Motivation and Context
Closes #122 

## How did you test it?
Manual, compiler-guided.

## Checklist
- [x] I formatted the code `cargo +nightly fmt`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed submitted code
