mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
refactor(macros): use syn2.0 (#2890)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com>
This commit is contained in:
48
Cargo.lock
generated
48
Cargo.lock
generated
@ -114,7 +114,7 @@ version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a0a77f836d869f700e5b47ac7c3c8b9c8bc82e4aec861954c6198abee3ebd4d"
|
||||
dependencies = [
|
||||
"darling 0.20.3",
|
||||
"darling",
|
||||
"parse-size",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1858,38 +1858,14 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
|
||||
dependencies = [
|
||||
"darling_core 0.14.4",
|
||||
"darling_macro 0.14.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
|
||||
dependencies = [
|
||||
"darling_core 0.20.3",
|
||||
"darling_macro 0.20.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 1.0.109",
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1906,24 +1882,13 @@ dependencies = [
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
|
||||
dependencies = [
|
||||
"darling_core 0.14.4",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
|
||||
dependencies = [
|
||||
"darling_core 0.20.3",
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
@ -4861,7 +4826,6 @@ dependencies = [
|
||||
name = "router_derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"darling 0.14.4",
|
||||
"diesel",
|
||||
"indexmap 2.0.2",
|
||||
"proc-macro2",
|
||||
@ -4869,7 +4833,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum 0.24.1",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5358,7 +5322,7 @@ version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c"
|
||||
dependencies = [
|
||||
"darling 0.20.3",
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
use std::num::{ParseFloatError, TryFromIntError};
|
||||
|
||||
use router_derive;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
#[doc(hidden)]
|
||||
@ -29,7 +28,7 @@ pub mod diesel_exports {
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum AttemptStatus {
|
||||
@ -107,7 +106,7 @@ impl AttemptStatus {
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum AuthenticationType {
|
||||
@ -132,7 +131,7 @@ pub enum AuthenticationType {
|
||||
ToSchema,
|
||||
Hash,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum CaptureStatus {
|
||||
@ -163,7 +162,7 @@ pub enum CaptureStatus {
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum CaptureMethod {
|
||||
@ -190,7 +189,7 @@ pub enum CaptureMethod {
|
||||
serde::Serialize,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ConnectorType {
|
||||
@ -231,7 +230,7 @@ pub enum ConnectorType {
|
||||
strum::EnumVariantNames,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
pub enum Currency {
|
||||
AED,
|
||||
ALL,
|
||||
@ -789,7 +788,7 @@ impl Currency {
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum EventType {
|
||||
@ -825,7 +824,7 @@ pub enum EventType {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum MerchantStorageScheme {
|
||||
@ -848,7 +847,7 @@ pub enum MerchantStorageScheme {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum IntentStatus {
|
||||
@ -882,7 +881,7 @@ pub enum IntentStatus {
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum FutureUsage {
|
||||
@ -904,7 +903,7 @@ pub enum FutureUsage {
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PaymentMethodIssuerCode {
|
||||
@ -1108,7 +1107,7 @@ pub enum PaymentMethod {
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum PaymentType {
|
||||
@ -1132,7 +1131,7 @@ pub enum PaymentType {
|
||||
serde::Serialize,
|
||||
serde::Deserialize,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum RefundStatus {
|
||||
Failure,
|
||||
@ -1157,7 +1156,7 @@ pub enum RefundStatus {
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum MandateStatus {
|
||||
@ -1211,7 +1210,7 @@ pub enum CardNetwork {
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum DisputeStage {
|
||||
@ -1235,7 +1234,7 @@ pub enum DisputeStage {
|
||||
strum::EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum DisputeStatus {
|
||||
@ -1265,7 +1264,7 @@ pub enum DisputeStatus {
|
||||
utoipa::ToSchema,
|
||||
Copy
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[rustfmt::skip]
|
||||
pub enum CountryAlpha2 {
|
||||
AF, AX, AL, DZ, AS, AD, AO, AI, AQ, AG, AR, AM, AW, AU, AT,
|
||||
@ -1692,7 +1691,7 @@ pub enum CanadaStatesAbbreviation {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum PayoutStatus {
|
||||
@ -1720,7 +1719,7 @@ pub enum PayoutStatus {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum PayoutType {
|
||||
@ -1775,7 +1774,7 @@ pub enum PayoutEntityType {
|
||||
ToSchema,
|
||||
Hash,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum PaymentSource {
|
||||
@ -1842,7 +1841,7 @@ pub enum FrmSuggestion {
|
||||
utoipa::ToSchema,
|
||||
Copy,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum ReconStatus {
|
||||
@ -1871,7 +1870,7 @@ pub enum ApplePayFlow {
|
||||
ToSchema,
|
||||
Default,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[router_derive::diesel_enum(storage_type = "db_enum")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ConnectorStatus {
|
||||
|
||||
@ -21,6 +21,7 @@ pub mod diesel_exports {
|
||||
pub use common_enums::*;
|
||||
use common_utils::pii;
|
||||
use diesel::serialize::{Output, ToSql};
|
||||
use router_derive::diesel_enum;
|
||||
use time::PrimitiveDateTime;
|
||||
|
||||
#[derive(
|
||||
@ -34,7 +35,7 @@ use time::PrimitiveDateTime;
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum RoutingAlgorithmKind {
|
||||
@ -55,7 +56,7 @@ pub enum RoutingAlgorithmKind {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum EventClass {
|
||||
@ -76,7 +77,7 @@ pub enum EventClass {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum EventObjectType {
|
||||
@ -97,7 +98,7 @@ pub enum EventObjectType {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum ProcessTrackerStatus {
|
||||
@ -126,7 +127,7 @@ pub enum ProcessTrackerStatus {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[diesel_enum(storage_type = "db_enum")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum RefundType {
|
||||
@ -149,7 +150,7 @@ pub enum RefundType {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum MandateType {
|
||||
@ -217,7 +218,7 @@ pub struct MandateAmountData {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "text")]
|
||||
#[diesel_enum(storage_type = "text")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum BankNames {
|
||||
@ -348,7 +349,7 @@ pub enum BankNames {
|
||||
strum::Display,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[diesel_enum(storage_type = "db_enum")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum FraudCheckType {
|
||||
@ -369,7 +370,7 @@ pub enum FraudCheckType {
|
||||
strum::EnumString,
|
||||
frunk::LabelledGeneric,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "pg_enum")]
|
||||
#[diesel_enum(storage_type = "db_enum")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum FraudCheckStatus {
|
||||
Fraud,
|
||||
@ -393,7 +394,7 @@ pub enum FraudCheckStatus {
|
||||
strum::EnumString,
|
||||
frunk::LabelledGeneric,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "text")]
|
||||
#[diesel_enum(storage_type = "text")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum FraudCheckLastStep {
|
||||
#[default]
|
||||
@ -416,7 +417,7 @@ pub enum FraudCheckLastStep {
|
||||
strum::EnumString,
|
||||
frunk::LabelledGeneric,
|
||||
)]
|
||||
#[router_derive::diesel_enum(storage_type = "text")]
|
||||
#[diesel_enum(storage_type = "text")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum UserStatus {
|
||||
|
||||
@ -28,7 +28,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "authorize")]
|
||||
#[operation(operations = "all", flow = "authorize")]
|
||||
pub struct PaymentApprove;
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@ -25,7 +25,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, router_derive::PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "cancel")]
|
||||
#[operation(operations = "all", flow = "cancel")]
|
||||
pub struct PaymentCancel;
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@ -24,7 +24,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, router_derive::PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "capture")]
|
||||
#[operation(operations = "all", flow = "capture")]
|
||||
pub struct PaymentCapture;
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@ -27,7 +27,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "authorize")]
|
||||
#[operation(operations = "all", flow = "authorize")]
|
||||
pub struct CompleteAuthorize;
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@ -34,7 +34,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "authorize")]
|
||||
#[operation(operations = "all", flow = "authorize")]
|
||||
pub struct PaymentConfirm;
|
||||
#[async_trait]
|
||||
impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
|
||||
|
||||
@ -34,7 +34,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "authorize")]
|
||||
#[operation(operations = "all", flow = "authorize")]
|
||||
pub struct PaymentCreate;
|
||||
|
||||
/// The `get_trackers` function for `PaymentsCreate` is an entrypoint for new payments
|
||||
|
||||
@ -29,7 +29,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "verify")]
|
||||
#[operation(operations = "all", flow = "verify")]
|
||||
pub struct PaymentMethodValidate;
|
||||
|
||||
impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::VerifyRequest, Ctx>
|
||||
|
||||
@ -24,7 +24,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, router_derive::PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "reject")]
|
||||
#[operation(operations = "all", flow = "reject")]
|
||||
pub struct PaymentReject;
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@ -35,8 +35,8 @@ use crate::{
|
||||
|
||||
#[derive(Debug, Clone, Copy, router_derive::PaymentOperation)]
|
||||
#[operation(
|
||||
ops = "post_tracker",
|
||||
flow = "syncdata,authorizedata,canceldata,capturedata,completeauthorizedata,approvedata,rejectdata,setupmandatedata,sessiondata"
|
||||
operations = "post_update_tracker",
|
||||
flow = "sync_data, authorize_data, cancel_data, capture_data, complete_authorize_data, approve_data, reject_data, setup_mandate_data, session_data"
|
||||
)]
|
||||
pub struct PaymentResponse;
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "session")]
|
||||
#[operation(operations = "all", flow = "session")]
|
||||
pub struct PaymentSession;
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@ -25,7 +25,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "start")]
|
||||
#[operation(operations = "all", flow = "start")]
|
||||
pub struct PaymentStart;
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@ -28,7 +28,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "sync")]
|
||||
#[operation(operations = "all", flow = "sync")]
|
||||
pub struct PaymentStatus;
|
||||
|
||||
impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> Operation<F, api::PaymentsRequest, Ctx>
|
||||
|
||||
@ -27,7 +27,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PaymentOperation)]
|
||||
#[operation(ops = "all", flow = "authorize")]
|
||||
#[operation(operations = "all", flow = "authorize")]
|
||||
pub struct PaymentUpdate;
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@ -12,14 +12,14 @@ proc-macro = true
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
darling = "0.14.4"
|
||||
indexmap = "2.0.0"
|
||||
proc-macro2 = "1.0.56"
|
||||
quote = "1.0.26"
|
||||
syn = { version = "1.0.109", features = ["full", "extra-traits"] } # the full feature does not seem to encompass all the features
|
||||
syn = { version = "2.0.5", features = ["full", "extra-traits"] } # the full feature does not seem to encompass all the features
|
||||
strum = { version = "0.24.1", features = ["derive"] }
|
||||
|
||||
[dev-dependencies]
|
||||
diesel = { version = "2.1.0", features = ["postgres"] }
|
||||
serde = { version = "1.0.163", features = ["derive"] }
|
||||
serde_json = "1.0.96"
|
||||
strum = { version = "0.24.1", features = ["derive"] }
|
||||
|
||||
|
||||
@ -2,6 +2,10 @@
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use syn::parse_macro_input;
|
||||
|
||||
use crate::macros::diesel::DieselEnumMeta;
|
||||
|
||||
mod macros;
|
||||
|
||||
/// Uses the [`Debug`][Debug] implementation of a type to derive its [`Display`][Display]
|
||||
@ -66,7 +70,7 @@ pub fn debug_as_display_derive(input: proc_macro::TokenStream) -> proc_macro::To
|
||||
/// Blue,
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro_derive(DieselEnum)]
|
||||
#[proc_macro_derive(DieselEnum, attributes(storage_type))]
|
||||
pub fn diesel_enum_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let ast = syn::parse_macro_input!(input as syn::DeriveInput);
|
||||
let tokens =
|
||||
@ -104,16 +108,15 @@ pub fn diesel_enum_derive_string(input: proc_macro::TokenStream) -> proc_macro::
|
||||
|
||||
/// Derives the boilerplate code required for using an enum with `diesel` and a PostgreSQL database.
|
||||
///
|
||||
/// Storage Type can either be "text" or "pg_enum"
|
||||
/// Choosing text will store the enum as text in the database, whereas pg_enum will map it to the
|
||||
/// database enum
|
||||
/// Storage Type can either be "text" or "db_enum"
|
||||
/// Choosing text will store the enum as text in the database, whereas db_enum will map it to the
|
||||
/// corresponding database enum
|
||||
///
|
||||
/// Works in tandem with the [`DieselEnum`][DieselEnum] and [`DieselEnumText`][DieselEnumText] derive macro to achieve the desired results.
|
||||
/// Works in tandem with the [`DieselEnum`][DieselEnum] derive macro to achieve the desired results.
|
||||
/// The enum is required to implement (or derive) the [`ToString`][ToString] and the
|
||||
/// [`FromStr`][FromStr] traits for the [`DieselEnum`][DieselEnum] derive macro to be used.
|
||||
///
|
||||
/// [DieselEnum]: crate::DieselEnum
|
||||
/// [DieselEnumText]: crate::DieselEnumText
|
||||
/// [FromStr]: ::core::str::FromStr
|
||||
/// [ToString]: ::std::string::ToString
|
||||
///
|
||||
@ -138,12 +141,12 @@ pub fn diesel_enum(
|
||||
args: proc_macro::TokenStream,
|
||||
item: proc_macro::TokenStream,
|
||||
) -> proc_macro::TokenStream {
|
||||
let args = syn::parse_macro_input!(args as syn::AttributeArgs);
|
||||
let args_parsed = parse_macro_input!(args as DieselEnumMeta);
|
||||
let item = syn::parse_macro_input!(item as syn::ItemEnum);
|
||||
|
||||
let tokens = macros::diesel_enum_attribute_inner(&args, &item)
|
||||
.unwrap_or_else(|error| error.to_compile_error());
|
||||
tokens.into()
|
||||
macros::diesel::diesel_enum_attribute_macro(args_parsed, &item)
|
||||
.unwrap_or_else(|error| error.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
/// A derive macro which generates the setter functions for any struct with fields
|
||||
@ -226,7 +229,7 @@ pub fn setter(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
#[inline]
|
||||
fn check_if_auth_based_attr_is_present(f: &syn::Field, ident: &str) -> bool {
|
||||
for i in f.attrs.iter() {
|
||||
if i.path.is_ident(ident) {
|
||||
if i.path().is_ident(ident) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -460,7 +463,8 @@ pub fn api_error_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStre
|
||||
#[proc_macro_derive(PaymentOperation, attributes(operation))]
|
||||
pub fn operation_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = syn::parse_macro_input!(input as syn::DeriveInput);
|
||||
macros::operation_derive_inner(input).unwrap_or_else(|err| err.to_compile_error().into())
|
||||
macros::operation::operation_derive_inner(input)
|
||||
.unwrap_or_else(|err| err.to_compile_error().into())
|
||||
}
|
||||
|
||||
/// Generates different schemas with the ability to mark few fields as mandatory for certain schema
|
||||
|
||||
@ -13,11 +13,8 @@ use syn::DeriveInput;
|
||||
|
||||
pub(crate) use self::{
|
||||
api_error::api_error_derive_inner,
|
||||
diesel::{
|
||||
diesel_enum_attribute_inner, diesel_enum_derive_inner, diesel_enum_text_derive_inner,
|
||||
},
|
||||
diesel::{diesel_enum_derive_inner, diesel_enum_text_derive_inner},
|
||||
generate_schema::polymorphic_macro_derive_inner,
|
||||
operation::operation_derive_inner,
|
||||
};
|
||||
|
||||
pub(crate) fn debug_as_display_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::ToTokens;
|
||||
use syn::{
|
||||
parse::Parse, spanned::Spanned, DeriveInput, Field, Fields, LitStr, Token, TypePath, Variant,
|
||||
};
|
||||
@ -38,10 +40,10 @@ impl Parse for EnumMeta {
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for EnumMeta {
|
||||
fn span(&self) -> proc_macro2::Span {
|
||||
impl ToTokens for EnumMeta {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
Self::ErrorTypeEnum { keyword, .. } => keyword.span(),
|
||||
Self::ErrorTypeEnum { keyword, .. } => keyword.to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -143,13 +145,13 @@ impl Parse for VariantMeta {
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for VariantMeta {
|
||||
fn span(&self) -> proc_macro2::Span {
|
||||
impl ToTokens for VariantMeta {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
Self::ErrorType { keyword, .. } => keyword.span,
|
||||
Self::Code { keyword, .. } => keyword.span,
|
||||
Self::Message { keyword, .. } => keyword.span,
|
||||
Self::Ignore { keyword, .. } => keyword.span,
|
||||
Self::ErrorType { keyword, .. } => keyword.to_tokens(tokens),
|
||||
Self::Code { keyword, .. } => keyword.to_tokens(tokens),
|
||||
Self::Message { keyword, .. } => keyword.to_tokens(tokens),
|
||||
Self::Ignore { keyword, .. } => keyword.to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
#![allow(clippy::use_self)]
|
||||
use darling::FromMeta;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
use syn::{AttributeArgs, Data, DeriveInput, ItemEnum};
|
||||
use quote::{format_ident, quote, ToTokens};
|
||||
use syn::{parse::Parse, Data, DeriveInput, ItemEnum};
|
||||
|
||||
use crate::macros::helpers::non_enum_error;
|
||||
use crate::macros::helpers;
|
||||
|
||||
pub(crate) fn diesel_enum_text_derive_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
|
||||
let name = &ast.ident;
|
||||
@ -12,10 +10,11 @@ pub(crate) fn diesel_enum_text_derive_inner(ast: &DeriveInput) -> syn::Result<To
|
||||
|
||||
match &ast.data {
|
||||
Data::Enum(_) => (),
|
||||
_ => return Err(non_enum_error()),
|
||||
}
|
||||
_ => return Err(helpers::non_enum_error()),
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
|
||||
#[automatically_derived]
|
||||
impl #impl_generics ::diesel::serialize::ToSql<::diesel::sql_types::Text, ::diesel::pg::Pg> for #name #ty_generics
|
||||
#where_clause
|
||||
@ -42,18 +41,20 @@ pub(crate) fn diesel_enum_text_derive_inner(ast: &DeriveInput) -> syn::Result<To
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn diesel_enum_derive_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
|
||||
pub(crate) fn diesel_enum_db_enum_derive_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
|
||||
let name = &ast.ident;
|
||||
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
|
||||
|
||||
match &ast.data {
|
||||
Data::Enum(_) => (),
|
||||
_ => return Err(non_enum_error()),
|
||||
}
|
||||
_ => return Err(helpers::non_enum_error()),
|
||||
};
|
||||
|
||||
let struct_name = format_ident!("Db{name}");
|
||||
let type_name = format!("{name}");
|
||||
|
||||
Ok(quote! {
|
||||
|
||||
#[derive(::core::clone::Clone, ::core::marker::Copy, ::core::fmt::Debug, ::diesel::QueryId, ::diesel::SqlType)]
|
||||
#[diesel(postgres_type(name = #type_name))]
|
||||
pub struct #struct_name;
|
||||
@ -84,45 +85,138 @@ pub(crate) fn diesel_enum_derive_inner(ast: &DeriveInput) -> syn::Result<TokenSt
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn diesel_enum_attribute_inner(
|
||||
args: &AttributeArgs,
|
||||
mod diesel_keyword {
|
||||
use syn::custom_keyword;
|
||||
|
||||
custom_keyword!(storage_type);
|
||||
custom_keyword!(db_enum);
|
||||
custom_keyword!(text);
|
||||
}
|
||||
|
||||
#[derive(Debug, strum::EnumString, strum::EnumIter, strum::Display)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum StorageType {
|
||||
/// Store the Enum as Text value in the database
|
||||
Text,
|
||||
/// Store the Enum as Enum in the database. This requires a corresponding enum to be created
|
||||
/// in the database with the same name
|
||||
DbEnum,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DieselEnumMeta {
|
||||
StorageTypeEnum {
|
||||
keyword: diesel_keyword::storage_type,
|
||||
value: StorageType,
|
||||
},
|
||||
}
|
||||
|
||||
impl Parse for StorageType {
|
||||
fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
|
||||
let text = input.parse::<syn::LitStr>()?;
|
||||
let value = text.value();
|
||||
|
||||
value.as_str().parse().map_err(|_| {
|
||||
syn::Error::new_spanned(
|
||||
&text,
|
||||
format!(
|
||||
"Unexpected value for storage_type: `{value}`. Possible values are `{}`",
|
||||
helpers::get_possible_values_for_enum::<Self>()
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl DieselEnumMeta {
|
||||
pub fn get_storage_type(&self) -> &StorageType {
|
||||
match self {
|
||||
Self::StorageTypeEnum { value, .. } => value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for DieselEnumMeta {
|
||||
fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
|
||||
let lookahead = input.lookahead1();
|
||||
if lookahead.peek(diesel_keyword::storage_type) {
|
||||
let keyword = input.parse()?;
|
||||
input.parse::<syn::Token![=]>()?;
|
||||
let value = input.parse()?;
|
||||
Ok(Self::StorageTypeEnum { keyword, value })
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for DieselEnumMeta {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
Self::StorageTypeEnum { keyword, .. } => keyword.to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait DieselDeriveInputExt {
|
||||
/// Get all the error metadata associated with an enum.
|
||||
fn get_metadata(&self) -> syn::Result<Vec<DieselEnumMeta>>;
|
||||
}
|
||||
|
||||
impl DieselDeriveInputExt for DeriveInput {
|
||||
fn get_metadata(&self) -> syn::Result<Vec<DieselEnumMeta>> {
|
||||
helpers::get_metadata_inner("storage_type", &self.attrs)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn diesel_enum_derive_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {
|
||||
let storage_type = ast.get_metadata()?;
|
||||
|
||||
match storage_type
|
||||
.first()
|
||||
.ok_or(syn::Error::new(
|
||||
Span::call_site(),
|
||||
"Storage type must be specified",
|
||||
))?
|
||||
.get_storage_type()
|
||||
{
|
||||
StorageType::Text => diesel_enum_text_derive_inner(ast),
|
||||
StorageType::DbEnum => diesel_enum_db_enum_derive_inner(ast),
|
||||
}
|
||||
}
|
||||
|
||||
/// Based on the storage type, derive appropriate diesel traits
|
||||
/// This will add the appropriate #[diesel(sql_type)]
|
||||
/// Since the `FromSql` and `ToSql` have to be derived for all the enums, this will add the
|
||||
/// `DieselEnum` derive trait.
|
||||
pub(crate) fn diesel_enum_attribute_macro(
|
||||
diesel_enum_meta: DieselEnumMeta,
|
||||
item: &ItemEnum,
|
||||
) -> syn::Result<TokenStream> {
|
||||
#[derive(FromMeta, Debug)]
|
||||
enum StorageType {
|
||||
PgEnum,
|
||||
Text,
|
||||
}
|
||||
let diesel_derives =
|
||||
quote!(#[derive(diesel::AsExpression, diesel::FromSqlRow, router_derive::DieselEnum) ]);
|
||||
|
||||
#[derive(FromMeta, Debug)]
|
||||
struct StorageTypeArgs {
|
||||
storage_type: StorageType,
|
||||
}
|
||||
|
||||
let storage_type_args = match StorageTypeArgs::from_list(args) {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
return Err(syn::Error::new(
|
||||
Span::call_site(),
|
||||
"Expected storage_type of text or pg_enum",
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
match storage_type_args.storage_type {
|
||||
StorageType::PgEnum => {
|
||||
match diesel_enum_meta {
|
||||
DieselEnumMeta::StorageTypeEnum {
|
||||
value: storage_type,
|
||||
..
|
||||
} => match storage_type {
|
||||
StorageType::Text => Ok(quote! {
|
||||
#diesel_derives
|
||||
#[diesel(sql_type = ::diesel::sql_types::Text)]
|
||||
#[storage_type(storage_type = "text")]
|
||||
#item
|
||||
}),
|
||||
StorageType::DbEnum => {
|
||||
let name = &item.ident;
|
||||
let type_name = format_ident!("Db{name}");
|
||||
Ok(quote! {
|
||||
#[derive(diesel::AsExpression, diesel::FromSqlRow, router_derive::DieselEnum) ]
|
||||
#diesel_derives
|
||||
#[diesel(sql_type = #type_name)]
|
||||
#[storage_type(storage_type= "db_enum")]
|
||||
#item
|
||||
})
|
||||
}
|
||||
StorageType::Text => Ok(quote! {
|
||||
#[derive(diesel::AsExpression, diesel::FromSqlRow, router_derive::DieselEnumText) ]
|
||||
#[diesel(sql_type = ::diesel::sql_types::Text)]
|
||||
#item
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,12 +42,14 @@ pub fn polymorphic_macro_derive_inner(
|
||||
let (mandatory_attribute, other_attributes) = field
|
||||
.attrs
|
||||
.iter()
|
||||
.partition::<Vec<_>, _>(|attribute| attribute.path.is_ident("mandatory_in"));
|
||||
.partition::<Vec<_>, _>(|attribute| attribute.path().is_ident("mandatory_in"));
|
||||
|
||||
// Other attributes ( schema ) are to be printed as is
|
||||
other_attributes
|
||||
.iter()
|
||||
.filter(|attribute| attribute.path.is_ident("schema") || attribute.path.is_ident("doc"))
|
||||
.filter(|attribute| {
|
||||
attribute.path().is_ident("schema") || attribute.path().is_ident("doc")
|
||||
})
|
||||
.for_each(|attribute| {
|
||||
// Since attributes will be modified, the field should not contain any attributes
|
||||
// So create a field, with previous attributes removed
|
||||
|
||||
@ -23,13 +23,24 @@ pub(super) fn syn_error(span: Span, message: &str) -> syn::Error {
|
||||
syn::Error::new(span, message)
|
||||
}
|
||||
|
||||
/// Get all the variants of a enum in the form of a string
|
||||
pub fn get_possible_values_for_enum<T>() -> String
|
||||
where
|
||||
T: strum::IntoEnumIterator + ToString,
|
||||
{
|
||||
T::iter()
|
||||
.map(|variants| variants.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
}
|
||||
|
||||
pub(super) fn get_metadata_inner<'a, T: Parse + Spanned>(
|
||||
ident: &str,
|
||||
attrs: impl IntoIterator<Item = &'a Attribute>,
|
||||
) -> syn::Result<Vec<T>> {
|
||||
attrs
|
||||
.into_iter()
|
||||
.filter(|attr| attr.path.is_ident(ident))
|
||||
.filter(|attr| attr.path().is_ident(ident))
|
||||
.try_fold(Vec::new(), |mut vec, attr| {
|
||||
vec.extend(attr.parse_args_with(Punctuated::<T, Token![,]>::parse_terminated)?);
|
||||
Ok(vec)
|
||||
|
||||
@ -1,25 +1,27 @@
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{self, spanned::Spanned, DeriveInput, Lit, Meta, MetaNameValue, NestedMeta};
|
||||
use quote::{quote, ToTokens};
|
||||
use strum::IntoEnumIterator;
|
||||
use syn::{self, parse::Parse, DeriveInput};
|
||||
|
||||
use crate::macros::helpers;
|
||||
use crate::macros::helpers::{self};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Derives {
|
||||
#[derive(Debug, Clone, Copy, strum::EnumString, strum::EnumIter, strum::Display)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum Derives {
|
||||
Sync,
|
||||
Cancel,
|
||||
Reject,
|
||||
Capture,
|
||||
Approvedata,
|
||||
ApproveData,
|
||||
Authorize,
|
||||
Authorizedata,
|
||||
Syncdata,
|
||||
Canceldata,
|
||||
Capturedata,
|
||||
AuthorizeData,
|
||||
SyncData,
|
||||
CancelData,
|
||||
CaptureData,
|
||||
CompleteAuthorizeData,
|
||||
Rejectdata,
|
||||
RejectData,
|
||||
SetupMandateData,
|
||||
Start,
|
||||
Verify,
|
||||
@ -27,31 +29,6 @@ enum Derives {
|
||||
SessionData,
|
||||
}
|
||||
|
||||
impl From<String> for Derives {
|
||||
fn from(s: String) -> Self {
|
||||
match s.as_str() {
|
||||
"sync" => Self::Sync,
|
||||
"cancel" => Self::Cancel,
|
||||
"reject" => Self::Reject,
|
||||
"syncdata" => Self::Syncdata,
|
||||
"authorize" => Self::Authorize,
|
||||
"approvedata" => Self::Approvedata,
|
||||
"authorizedata" => Self::Authorizedata,
|
||||
"canceldata" => Self::Canceldata,
|
||||
"capture" => Self::Capture,
|
||||
"capturedata" => Self::Capturedata,
|
||||
"completeauthorizedata" => Self::CompleteAuthorizeData,
|
||||
"rejectdata" => Self::Rejectdata,
|
||||
"start" => Self::Start,
|
||||
"verify" => Self::Verify,
|
||||
"setupmandatedata" => Self::SetupMandateData,
|
||||
"session" => Self::Session,
|
||||
"sessiondata" => Self::SessionData,
|
||||
_ => Self::Authorize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Derives {
|
||||
fn to_operation(
|
||||
self,
|
||||
@ -82,8 +59,9 @@ impl Derives {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
enum Conversion {
|
||||
#[derive(Debug, Clone, strum::EnumString, strum::EnumIter, strum::Display)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum Conversion {
|
||||
ValidateRequest,
|
||||
GetTracker,
|
||||
Domain,
|
||||
@ -93,34 +71,20 @@ enum Conversion {
|
||||
Invalid(String),
|
||||
}
|
||||
|
||||
impl From<String> for Conversion {
|
||||
fn from(s: String) -> Self {
|
||||
match s.as_str() {
|
||||
"validate_request" => Self::ValidateRequest,
|
||||
"get_tracker" => Self::GetTracker,
|
||||
"domain" => Self::Domain,
|
||||
"update_tracker" => Self::UpdateTracker,
|
||||
"post_tracker" => Self::PostUpdateTracker,
|
||||
"all" => Self::All,
|
||||
s => Self::Invalid(s.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Conversion {
|
||||
fn get_req_type(ident: Derives) -> syn::Ident {
|
||||
match ident {
|
||||
Derives::Authorize => syn::Ident::new("PaymentsRequest", Span::call_site()),
|
||||
Derives::Authorizedata => syn::Ident::new("PaymentsAuthorizeData", Span::call_site()),
|
||||
Derives::AuthorizeData => syn::Ident::new("PaymentsAuthorizeData", Span::call_site()),
|
||||
Derives::Sync => syn::Ident::new("PaymentsRetrieveRequest", Span::call_site()),
|
||||
Derives::Syncdata => syn::Ident::new("PaymentsSyncData", Span::call_site()),
|
||||
Derives::SyncData => syn::Ident::new("PaymentsSyncData", Span::call_site()),
|
||||
Derives::Cancel => syn::Ident::new("PaymentsCancelRequest", Span::call_site()),
|
||||
Derives::Canceldata => syn::Ident::new("PaymentsCancelData", Span::call_site()),
|
||||
Derives::Approvedata => syn::Ident::new("PaymentsApproveData", Span::call_site()),
|
||||
Derives::CancelData => syn::Ident::new("PaymentsCancelData", Span::call_site()),
|
||||
Derives::ApproveData => syn::Ident::new("PaymentsApproveData", Span::call_site()),
|
||||
Derives::Reject => syn::Ident::new("PaymentsRejectRequest", Span::call_site()),
|
||||
Derives::Rejectdata => syn::Ident::new("PaymentsRejectData", Span::call_site()),
|
||||
Derives::RejectData => syn::Ident::new("PaymentsRejectData", Span::call_site()),
|
||||
Derives::Capture => syn::Ident::new("PaymentsCaptureRequest", Span::call_site()),
|
||||
Derives::Capturedata => syn::Ident::new("PaymentsCaptureData", Span::call_site()),
|
||||
Derives::CaptureData => syn::Ident::new("PaymentsCaptureData", Span::call_site()),
|
||||
Derives::CompleteAuthorizeData => {
|
||||
syn::Ident::new("CompleteAuthorizeData", Span::call_site())
|
||||
}
|
||||
@ -231,103 +195,206 @@ impl Conversion {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_operation_attr(a: &[syn::Attribute]) -> syn::Result<syn::Attribute> {
|
||||
a.iter()
|
||||
.find(|a| {
|
||||
a.path
|
||||
.get_ident()
|
||||
.map(|ident| *ident == "operation")
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.cloned()
|
||||
.ok_or_else(|| {
|
||||
helpers::syn_error(
|
||||
mod operations_keyword {
|
||||
use syn::custom_keyword;
|
||||
|
||||
custom_keyword!(operations);
|
||||
custom_keyword!(flow);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum OperationsEnumMeta {
|
||||
Operations {
|
||||
keyword: operations_keyword::operations,
|
||||
value: Vec<Conversion>,
|
||||
},
|
||||
Flow {
|
||||
keyword: operations_keyword::flow,
|
||||
value: Vec<Derives>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct OperationProperties {
|
||||
operations: Vec<Conversion>,
|
||||
flows: Vec<Derives>,
|
||||
}
|
||||
|
||||
fn get_operation_properties(
|
||||
operation_enums: Vec<OperationsEnumMeta>,
|
||||
) -> syn::Result<OperationProperties> {
|
||||
let mut operations = vec![];
|
||||
let mut flows = vec![];
|
||||
|
||||
for operation in operation_enums {
|
||||
match operation {
|
||||
OperationsEnumMeta::Operations { value, .. } => {
|
||||
operations = value;
|
||||
}
|
||||
OperationsEnumMeta::Flow { value, .. } => {
|
||||
flows = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if operations.is_empty() {
|
||||
Err(syn::Error::new(
|
||||
Span::call_site(),
|
||||
"Cannot find attribute 'operation' in the macro",
|
||||
"atleast one operation must be specitied",
|
||||
))?;
|
||||
}
|
||||
|
||||
if flows.is_empty() {
|
||||
Err(syn::Error::new(
|
||||
Span::call_site(),
|
||||
"atleast one flow must be specitied",
|
||||
))?;
|
||||
}
|
||||
|
||||
Ok(OperationProperties { operations, flows })
|
||||
}
|
||||
|
||||
impl Parse for Derives {
|
||||
fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
|
||||
let text = input.parse::<syn::LitStr>()?;
|
||||
let value = text.value();
|
||||
|
||||
value.as_str().parse().map_err(|_| {
|
||||
syn::Error::new_spanned(
|
||||
&text,
|
||||
format!(
|
||||
"Unexpected value for flow: `{value}`. Possible values are `{}`",
|
||||
helpers::get_possible_values_for_enum::<Self>()
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn find_value(v: &NestedMeta) -> Option<(String, Vec<String>)> {
|
||||
match v {
|
||||
NestedMeta::Meta(Meta::NameValue(MetaNameValue {
|
||||
ref path,
|
||||
eq_token: _,
|
||||
lit: Lit::Str(ref litstr),
|
||||
})) => {
|
||||
let key = path.get_ident()?.to_string();
|
||||
Some((
|
||||
key,
|
||||
litstr.value().split(',').map(ToString::to_string).collect(),
|
||||
))
|
||||
}
|
||||
_ => None,
|
||||
|
||||
impl Parse for Conversion {
|
||||
fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
|
||||
let text = input.parse::<syn::LitStr>()?;
|
||||
let value = text.value();
|
||||
|
||||
value.as_str().parse().map_err(|_| {
|
||||
syn::Error::new_spanned(
|
||||
&text,
|
||||
format!(
|
||||
"Unexpected value for operation: `{value}`. Possible values are `{}`",
|
||||
helpers::get_possible_values_for_enum::<Self>()
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn find_properties(attr: &syn::Attribute) -> syn::Result<HashMap<String, Vec<String>>> {
|
||||
let meta = attr.parse_meta();
|
||||
match meta {
|
||||
Ok(syn::Meta::List(syn::MetaList {
|
||||
ref path,
|
||||
paren_token: _,
|
||||
nested,
|
||||
})) => {
|
||||
path.get_ident().map(|i| i == "operation").ok_or_else(|| {
|
||||
helpers::syn_error(path.span(), "Attribute 'operation' was not found")
|
||||
})?;
|
||||
Ok(HashMap::from_iter(nested.iter().filter_map(find_value)))
|
||||
fn parse_list_string<T>(list_string: String, keyword: &str) -> syn::Result<Vec<T>>
|
||||
where
|
||||
T: FromStr + IntoEnumIterator + ToString,
|
||||
{
|
||||
list_string
|
||||
.split(',')
|
||||
.map(str::trim)
|
||||
.map(T::from_str)
|
||||
.map(|result| {
|
||||
result.map_err(|_| {
|
||||
syn::Error::new(
|
||||
Span::call_site(),
|
||||
format!(
|
||||
"Unexpected {keyword}, possible values are {}",
|
||||
helpers::get_possible_values_for_enum::<T>()
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_conversions(input: syn::parse::ParseStream<'_>) -> syn::Result<Vec<Conversion>> {
|
||||
let lit_str_list = input.parse::<syn::LitStr>()?;
|
||||
parse_list_string(lit_str_list.value(), "operation")
|
||||
}
|
||||
|
||||
fn get_derives(input: syn::parse::ParseStream<'_>) -> syn::Result<Vec<Derives>> {
|
||||
let lit_str_list = input.parse::<syn::LitStr>()?;
|
||||
parse_list_string(lit_str_list.value(), "flow")
|
||||
}
|
||||
|
||||
impl Parse for OperationsEnumMeta {
|
||||
fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
|
||||
let lookahead = input.lookahead1();
|
||||
if lookahead.peek(operations_keyword::operations) {
|
||||
let keyword = input.parse()?;
|
||||
input.parse::<syn::Token![=]>()?;
|
||||
let value = get_conversions(input)?;
|
||||
Ok(Self::Operations { keyword, value })
|
||||
} else if lookahead.peek(operations_keyword::flow) {
|
||||
let keyword = input.parse()?;
|
||||
input.parse::<syn::Token![=]>()?;
|
||||
let value = get_derives(input)?;
|
||||
Ok(Self::Flow { keyword, value })
|
||||
} else {
|
||||
Err(lookahead.error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait OperationsDeriveInputExt {
|
||||
/// Get all the error metadata associated with an enum.
|
||||
fn get_metadata(&self) -> syn::Result<Vec<OperationsEnumMeta>>;
|
||||
}
|
||||
|
||||
impl OperationsDeriveInputExt for DeriveInput {
|
||||
fn get_metadata(&self) -> syn::Result<Vec<OperationsEnumMeta>> {
|
||||
helpers::get_metadata_inner("operation", &self.attrs)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for OperationsEnumMeta {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
Self::Operations { keyword, .. } => keyword.to_tokens(tokens),
|
||||
Self::Flow { keyword, .. } => keyword.to_tokens(tokens),
|
||||
}
|
||||
_ => Err(helpers::syn_error(
|
||||
attr.span(),
|
||||
"No attributes were found. Expected format is ops=..,flow=..",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn operation_derive_inner(input: DeriveInput) -> syn::Result<proc_macro::TokenStream> {
|
||||
let struct_name = &input.ident;
|
||||
let op = find_operation_attr(&input.attrs)?;
|
||||
let prop = find_properties(&op)?;
|
||||
let ops = prop.get("ops").ok_or_else(|| {
|
||||
helpers::syn_error(
|
||||
op.span(),
|
||||
"Invalid properties. Property 'ops' was not found",
|
||||
)
|
||||
})?;
|
||||
let flow = prop.get("flow").ok_or_else(|| {
|
||||
helpers::syn_error(
|
||||
op.span(),
|
||||
"Invalid properties. Property 'flow' was not found",
|
||||
)
|
||||
})?;
|
||||
let current_crate = syn::Ident::new(
|
||||
&prop
|
||||
.get("crate")
|
||||
.map(|v| v.join(""))
|
||||
.unwrap_or_else(|| String::from("crate")),
|
||||
Span::call_site(),
|
||||
);
|
||||
let operations_meta = input.get_metadata()?;
|
||||
let operation_properties = get_operation_properties(operations_meta)?;
|
||||
|
||||
let trait_derive = flow.iter().map(|derive| {
|
||||
let derive: Derives = derive.to_owned().into();
|
||||
let fns = ops.iter().map(|t| {
|
||||
let con: Conversion = t.to_owned().into();
|
||||
con.to_function(derive)
|
||||
});
|
||||
let current_crate = syn::Ident::new("crate", Span::call_site());
|
||||
|
||||
let trait_derive = operation_properties
|
||||
.clone()
|
||||
.flows
|
||||
.into_iter()
|
||||
.map(|derive| {
|
||||
let fns = operation_properties
|
||||
.operations
|
||||
.iter()
|
||||
.map(|conversion| conversion.to_function(derive));
|
||||
derive.to_operation(fns, struct_name)
|
||||
});
|
||||
let ref_trait_derive = flow.iter().map(|derive| {
|
||||
let derive: Derives = derive.to_owned().into();
|
||||
let fns = ops.iter().map(|t| {
|
||||
let con: Conversion = t.to_owned().into();
|
||||
con.to_ref_function(derive)
|
||||
});
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let ref_trait_derive = operation_properties
|
||||
.flows
|
||||
.into_iter()
|
||||
.map(|derive| {
|
||||
let fns = operation_properties
|
||||
.operations
|
||||
.iter()
|
||||
.map(|conversion| conversion.to_ref_function(derive));
|
||||
derive.to_ref_operation(fns, struct_name)
|
||||
});
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let trait_derive = quote! {
|
||||
#(#ref_trait_derive)* #(#trait_derive)*
|
||||
};
|
||||
|
||||
let output = quote! {
|
||||
const _: () = {
|
||||
use #current_crate::core::errors::RouterResult;
|
||||
|
||||
@ -1,21 +1,62 @@
|
||||
use proc_macro2::Span;
|
||||
use syn::punctuated::Punctuated;
|
||||
use quote::ToTokens;
|
||||
use syn::{parse::Parse, punctuated::Punctuated};
|
||||
|
||||
mod try_get_keyword {
|
||||
use syn::custom_keyword;
|
||||
|
||||
custom_keyword!(error_type);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TryGetEnumMeta {
|
||||
error_type: syn::Ident,
|
||||
variant: syn::Ident,
|
||||
}
|
||||
|
||||
impl Parse for TryGetEnumMeta {
|
||||
fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
|
||||
let error_type = input.parse()?;
|
||||
_ = input.parse::<syn::Token![::]>()?;
|
||||
let variant = input.parse()?;
|
||||
|
||||
Ok(Self {
|
||||
error_type,
|
||||
variant,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
trait TryGetDeriveInputExt {
|
||||
/// Get all the error metadata associated with an enum.
|
||||
fn get_metadata(&self) -> syn::Result<Vec<TryGetEnumMeta>>;
|
||||
}
|
||||
|
||||
impl TryGetDeriveInputExt for syn::DeriveInput {
|
||||
fn get_metadata(&self) -> syn::Result<Vec<TryGetEnumMeta>> {
|
||||
super::helpers::get_metadata_inner("error", &self.attrs)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for TryGetEnumMeta {
|
||||
fn to_tokens(&self, _: &mut proc_macro2::TokenStream) {}
|
||||
}
|
||||
|
||||
/// Try and get the variants for an enum
|
||||
pub fn try_get_enum_variant(
|
||||
input: syn::DeriveInput,
|
||||
) -> Result<proc_macro2::TokenStream, syn::Error> {
|
||||
let name = &input.ident;
|
||||
let parsed_error_type = input.get_metadata()?;
|
||||
|
||||
let (error_type, error_variant) = parsed_error_type
|
||||
.first()
|
||||
.ok_or(syn::Error::new(
|
||||
Span::call_site(),
|
||||
"One error should be specified",
|
||||
))
|
||||
.map(|error_struct| (&error_struct.error_type, &error_struct.variant))?;
|
||||
|
||||
let error_attr = input
|
||||
.attrs
|
||||
.iter()
|
||||
.find(|attr| attr.path.is_ident("error"))
|
||||
.ok_or(super::helpers::syn_error(
|
||||
proc_macro2::Span::call_site(),
|
||||
"Unable to find attribute error. Expected #[error(..)]",
|
||||
))?;
|
||||
let (error_type, error_variant) = get_error_type_and_variant(error_attr)?;
|
||||
let (impl_generics, generics, where_clause) = input.generics.split_for_impl();
|
||||
|
||||
let variants = get_enum_variants(&input.data)?;
|
||||
@ -49,52 +90,6 @@ pub fn try_get_enum_variant(
|
||||
Ok(expanded)
|
||||
}
|
||||
|
||||
/// Parses the attribute #[error(ErrorType(ErrorVariant))]
|
||||
fn get_error_type_and_variant(attr: &syn::Attribute) -> syn::Result<(syn::Ident, syn::Path)> {
|
||||
let meta = attr.parse_meta()?;
|
||||
let metalist = match meta {
|
||||
syn::Meta::List(list) => list,
|
||||
_ => {
|
||||
return Err(super::helpers::syn_error(
|
||||
proc_macro2::Span::call_site(),
|
||||
"Invalid attribute format #[error(ErrorType(ErrorVariant)]",
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
for meta in metalist.nested.iter() {
|
||||
if let syn::NestedMeta::Meta(syn::Meta::List(meta)) = meta {
|
||||
let error_type = meta
|
||||
.path
|
||||
.get_ident()
|
||||
.ok_or(super::helpers::syn_error(
|
||||
proc_macro2::Span::call_site(),
|
||||
"Invalid attribute format #[error(ErrorType(ErrorVariant))]",
|
||||
))
|
||||
.cloned()?;
|
||||
let error_variant = get_error_variant(meta)?;
|
||||
return Ok((error_type, error_variant));
|
||||
};
|
||||
}
|
||||
|
||||
Err(super::helpers::syn_error(
|
||||
proc_macro2::Span::call_site(),
|
||||
"Invalid attribute format #[error(ErrorType(ErrorVariant))]",
|
||||
))
|
||||
}
|
||||
|
||||
fn get_error_variant(meta: &syn::MetaList) -> syn::Result<syn::Path> {
|
||||
for meta in meta.nested.iter() {
|
||||
if let syn::NestedMeta::Meta(syn::Meta::Path(meta)) = meta {
|
||||
return Ok(meta.clone());
|
||||
}
|
||||
}
|
||||
Err(super::helpers::syn_error(
|
||||
proc_macro2::Span::call_site(),
|
||||
"Invalid attribute format expected #[error(ErrorType(ErrorVariant))]",
|
||||
))
|
||||
}
|
||||
|
||||
/// Get variants from Enum
|
||||
fn get_enum_variants(data: &syn::Data) -> syn::Result<Punctuated<syn::Variant, syn::token::Comma>> {
|
||||
if let syn::Data::Enum(syn::DataEnum { variants, .. }) = data {
|
||||
|
||||
@ -60,7 +60,7 @@ pub enum KvOperation<'a, S: serde::Serialize + Debug> {
|
||||
}
|
||||
|
||||
#[derive(TryGetEnumVariant)]
|
||||
#[error(RedisError(UnknownResult))]
|
||||
#[error(RedisError::UnknownResult)]
|
||||
pub enum KvResult<T: de::DeserializeOwned> {
|
||||
HGet(T),
|
||||
Get(T),
|
||||
|
||||
Reference in New Issue
Block a user