refactor: fix unit and documentation tests (#4754)

This commit is contained in:
Sanchith Hegde
2024-07-05 23:37:39 +05:30
committed by GitHub
parent ae2a34e02c
commit 648cecb204
17 changed files with 179 additions and 155 deletions

11
.github/nextest.toml vendored Normal file
View File

@ -0,0 +1,11 @@
[profile.default]
status-level = "slow"
final-status-level = "leak"
failure-output = "final"
fail-fast = false
[profile.ci]
retries = 2
status-level = "all"
failure-output = "final"
fail-fast = false

View File

@ -33,8 +33,8 @@ env:
RUSTUP_MAX_RETRIES: 10 RUSTUP_MAX_RETRIES: 10
# Don't emit giant backtraces in the CI logs. # Don't emit giant backtraces in the CI logs.
RUST_BACKTRACE: short RUST_BACKTRACE: short
# Use cargo's sparse index protocol # Use `sccache` for caching compilation artifacts
CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse RUSTC_WRAPPER: sccache
jobs: jobs:
formatting: formatting:
@ -88,14 +88,7 @@ jobs:
check-msrv: check-msrv:
name: Check compilation on MSRV toolchain name: Check compilation on MSRV toolchain
runs-on: ${{ matrix.os }} runs-on: hyperswitch-runners
strategy:
fail-fast: true
matrix:
os:
- ubuntu-latest
# - macos-latest
# - windows-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
@ -122,14 +115,17 @@ jobs:
with: with:
toolchain: "${{ env.rust_version }}" toolchain: "${{ env.rust_version }}"
- uses: Swatinem/rust-cache@v2.7.0 - name: Install sccache
uses: taiki-e/install-action@v2.33.28
with: with:
save-if: false tool: sccache
checksum: true
- name: Install cargo-hack - name: Install cargo-hack
uses: baptiste0928/cargo-install@v2.2.0 uses: taiki-e/install-action@v2.33.28
with: with:
crate: cargo-hack tool: cargo-hack
checksum: true
- name: Deny warnings - name: Deny warnings
shell: bash shell: bash
@ -210,14 +206,7 @@ jobs:
test: test:
name: Run tests on stable toolchain name: Run tests on stable toolchain
runs-on: ${{ matrix.os }} runs-on: hyperswitch-runners
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
# - macos-latest
# - windows-latest
steps: steps:
- name: Generate a token - name: Generate a token
@ -256,19 +245,23 @@ jobs:
toolchain: stable 2 weeks ago toolchain: stable 2 weeks ago
components: clippy components: clippy
- name: Install cargo-hack - name: Install sccache
uses: baptiste0928/cargo-install@v2.2.0 uses: taiki-e/install-action@v2.33.28
with: with:
crate: cargo-hack tool: sccache
checksum: true
- name: Install cargo-hack
uses: taiki-e/install-action@v2.33.28
with:
tool: cargo-hack
checksum: true
# - name: Install cargo-nextest # - name: Install cargo-nextest
# uses: baptiste0928/cargo-install@v2.2.0 # uses: taiki-e/install-action@v2.33.28
# with: # with:
# crate: cargo-nextest # tool: cargo-nextest
# checksum: true
- uses: Swatinem/rust-cache@v2.7.0
with:
save-if: false
# - name: Setup Embark Studios lint rules # - name: Setup Embark Studios lint rules
# shell: bash # shell: bash

View File

@ -39,14 +39,7 @@ jobs:
check-msrv: check-msrv:
name: Check compilation on MSRV toolchain name: Check compilation on MSRV toolchain
runs-on: ${{ matrix.os }} runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
os:
- ubuntu-latest
# - macos-latest
# - windows-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
@ -115,14 +108,7 @@ jobs:
test: test:
name: Run tests on stable toolchain name: Run tests on stable toolchain
runs-on: ${{ matrix.os }} runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
# - macos-latest
# - windows-latest
steps: steps:
- name: Checkout repository - name: Checkout repository

3
Cargo.lock generated
View File

@ -6030,7 +6030,9 @@ dependencies = [
name = "router_derive" name = "router_derive"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"common_utils",
"diesel", "diesel",
"error-stack",
"indexmap 2.2.6", "indexmap 2.2.6",
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -6038,6 +6040,7 @@ dependencies = [
"serde_json", "serde_json",
"strum 0.26.2", "strum 0.26.2",
"syn 2.0.57", "syn 2.0.57",
"utoipa",
] ]
[[package]] [[package]]

View File

@ -314,6 +314,7 @@ mod tests {
& payment_method /= voucher & payment_method /= voucher
& payment_method /= gift_card & payment_method /= gift_card
& payment_method /= card_redirect & payment_method /= card_redirect
& payment_method /= real_time_payment
} }
} }
} }

View File

@ -163,7 +163,8 @@ pub trait FromEncoded: Sized {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # use your_module::{FromEncoded, masking::Secret, Vec}; /// use external_services::hashicorp_vault::core::FromEncoded;
/// use masking::Secret;
/// let secret_instance = Secret::<String>::from_encoded("encoded_secret_string".to_string()); /// let secret_instance = Secret::<String>::from_encoded("encoded_secret_string".to_string());
/// let vec_instance = Vec::<u8>::from_encoded("68656c6c6f".to_string()); /// let vec_instance = Vec::<u8>::from_encoded("68656c6c6f".to_string());
/// ``` /// ```

View File

@ -22,7 +22,7 @@ pub struct PaymentsAuthorizeData {
pub payment_method_data: PaymentMethodData, pub payment_method_data: PaymentMethodData,
/// total amount (original_amount + surcharge_amount + tax_on_surcharge_amount) /// total amount (original_amount + surcharge_amount + tax_on_surcharge_amount)
/// If connector supports separate field for surcharge amount, consider using below functions defined on `PaymentsAuthorizeData` to fetch original amount and surcharge amount separately /// If connector supports separate field for surcharge amount, consider using below functions defined on `PaymentsAuthorizeData` to fetch original amount and surcharge amount separately
/// ``` /// ```text
/// get_original_amount() /// get_original_amount()
/// get_surcharge_amount() /// get_surcharge_amount()
/// get_tax_on_surcharge_amount() /// get_tax_on_surcharge_amount()

View File

@ -15,26 +15,43 @@ This solution has such advantages over alternatives:
## How to use ## How to use
To convert non-secret variable into secret use `new()`. Sample: To convert a non-secret variable into a secret, use `Secret::new()`:
```rust ```rust
expiry_year: ccard.map(|x| Secret::new(x.card_exp_year.to_string())), use masking::Secret;
// output: "expiry_year: *** alloc::string::String ***"
let card_number: Secret<String> = Secret::new(String::from("1234 5678 9012 3456"));
assert_eq!(format!("{:?}", card_number), "*** alloc::string::String ***");
``` ```
To get value from secret use `expose()`. Sample: To get a reference to the inner value from the secret, use `peek()`:
```rust ```rust
last4_digits: Some(card_number.expose()) use masking::{PeekInterface, Secret};
let card_number: Secret<String> = Secret::new(String::from("1234 5678 9012 3456"));
let last4_digits: &str = card_number.peek();
``` ```
Most fields are under `Option`. To simplify dealing with `Option`, use `expose_option()`. Sample: To get the owned inner value from the secret, use `expose()`:
```rust ```rust
card_info.push_str( use masking::{ExposeInterface, Secret};
&card_detail
.card_holder_name let card_number: Secret<String> = Secret::new(String::from("1234 5678 9012 3456"));
.expose_option() let last4_digits: String = card_number.expose();
.unwrap_or_default(), ```
);
For fields that are `Option<T>`, you can use `expose_option()`:
```rust
use masking::{ExposeOptionInterface, Secret};
let card_number: Option<Secret<String>> = Some(Secret::new(String::from("1234 5678 9012 3456")));
let card_number_str: String = card_number.expose_option().unwrap_or_default();
assert_eq!(format!("{}", card_number_str), "1234 5678 9012 3456");
let card_number: Option<Secret<String>> = None;
let card_number_str: String = card_number.expose_option().unwrap_or_default();
assert_eq!(format!("{}", card_number_str), "");
``` ```

View File

@ -1001,15 +1001,10 @@ mod hashmap_deserialization_test {
fn test_payment_method_and_payment_method_types() { fn test_payment_method_and_payment_method_types() {
use diesel_models::enums::{PaymentMethod, PaymentMethodType}; use diesel_models::enums::{PaymentMethod, PaymentMethodType};
let input_map: HashMap<String, String> = serde_json::json!({ let input_map: HashMap<String, String> = HashMap::from([
"bank_transfer": "ach,bacs", ("bank_transfer".to_string(), "ach,bacs".to_string()),
"wallet": "paypal,venmo", ("wallet".to_string(), "paypal,venmo".to_string()),
}) ]);
.as_object()
.unwrap()
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect();
let deserializer: MapDeserializer< let deserializer: MapDeserializer<
'_, '_,
std::collections::hash_map::IntoIter<String, String>, std::collections::hash_map::IntoIter<String, String>,
@ -1035,15 +1030,10 @@ mod hashmap_deserialization_test {
fn test_payment_method_and_payment_method_types_with_spaces() { fn test_payment_method_and_payment_method_types_with_spaces() {
use diesel_models::enums::{PaymentMethod, PaymentMethodType}; use diesel_models::enums::{PaymentMethod, PaymentMethodType};
let input_map: HashMap<String, String> = serde_json::json!({ let input_map: HashMap<String, String> = HashMap::from([
" bank_transfer ": " ach , bacs ", (" bank_transfer ".to_string(), " ach , bacs ".to_string()),
"wallet ": " paypal , pix , venmo ", ("wallet ".to_string(), " paypal , pix , venmo ".to_string()),
}) ]);
.as_object()
.unwrap()
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect();
let deserializer: MapDeserializer< let deserializer: MapDeserializer<
'_, '_,
std::collections::hash_map::IntoIter<String, String>, std::collections::hash_map::IntoIter<String, String>,
@ -1073,15 +1063,10 @@ mod hashmap_deserialization_test {
fn test_payment_method_deserializer_error() { fn test_payment_method_deserializer_error() {
use diesel_models::enums::{PaymentMethod, PaymentMethodType}; use diesel_models::enums::{PaymentMethod, PaymentMethodType};
let input_map: HashMap<String, String> = serde_json::json!({ let input_map: HashMap<String, String> = HashMap::from([
"unknown": "ach,bacs", ("unknown".to_string(), "ach,bacs".to_string()),
"wallet": "paypal,unknown", ("wallet".to_string(), "paypal,unknown".to_string()),
}) ]);
.as_object()
.unwrap()
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect();
let deserializer: MapDeserializer< let deserializer: MapDeserializer<
'_, '_,
std::collections::hash_map::IntoIter<String, String>, std::collections::hash_map::IntoIter<String, String>,

View File

@ -118,8 +118,8 @@ pub struct ThreeDSRequestor {
/// External IP address (i.e., the device public IP address) used by the 3DS Requestor App when it connects to the /// External IP address (i.e., the device public IP address) used by the 3DS Requestor App when it connects to the
/// 3DS Requestor environment. The value length is maximum 45 characters. Accepted values are: /// 3DS Requestor environment. The value length is maximum 45 characters. Accepted values are:
/// ///
/// IPv4 address is represented in the dotted decimal f. Refer to RFC 791. /// - IPv4 address is represented in the dotted decimal f. Refer to RFC 791.
/// IPv6 address. Refer to RFC 4291. /// - IPv6 address. Refer to RFC 4291.
/// ///
/// This field is required when deviceChannel = 01 (APP) and unless market or regional mandate restricts sending /// This field is required when deviceChannel = 01 (APP) and unless market or regional mandate restricts sending
/// this information. /// this information.
@ -1454,17 +1454,17 @@ pub struct Sdk {
/// The Split-SDK Server: /// The Split-SDK Server:
/// Creates a JSON object of the following data as the JWS payload to be signed: /// Creates a JSON object of the following data as the JWS payload to be signed:
/// ///
/// SDK Reference Number -> Identifies the vendor and version of the 3DS SDK that is utilised for a specific /// - SDK Reference Number -> Identifies the vendor and version of the 3DS SDK that is utilised for a specific
/// transaction. The value is assigned by EMVCo when the Letter of Approval of the /// transaction. The value is assigned by EMVCo when the Letter of Approval of the
/// specific 3DS SDK is issued. The field is limited to 32 characters. /// specific 3DS SDK is issued. The field is limited to 32 characters.
/// SDK Signature Timestamp -> Date and time indicating when the 3DS SDK generated the Split-SDK Server Signed /// - SDK Signature Timestamp -> Date and time indicating when the 3DS SDK generated the Split-SDK Server Signed
/// Content converted into UTC. The value is limited to 14 characters. Accepted /// Content converted into UTC. The value is limited to 14 characters. Accepted
/// format: YYYYMMDDHHMMSS. /// format: YYYYMMDDHHMMSS.
/// SDK Transaction ID -> Universally unique transaction identifier assigned by the 3DS SDK to identify a /// - SDK Transaction ID -> Universally unique transaction identifier assigned by the 3DS SDK to identify a
/// single transaction. The field is limited to 36 characters and it shall be in a /// single transaction. The field is limited to 36 characters and it shall be in a
/// canonical format as defined in IETF RFC 4122. This may utilize any of the specified /// canonical format as defined in IETF RFC 4122. This may utilize any of the specified
/// versions as long as the output meets specific requirements. /// versions as long as the output meets specific requirements.
/// Split-SDK Server ID -> DS assigned Split-SDK Server identifier. Each DS can provide a unique ID to each /// - Split-SDK Server ID -> DS assigned Split-SDK Server identifier. Each DS can provide a unique ID to each
/// Split-SDK Server on an individual basis. The field is limited to 32 characters. /// Split-SDK Server on an individual basis. The field is limited to 32 characters.
/// Any individual DS may impose specific formatting and character requirements on the /// Any individual DS may impose specific formatting and character requirements on the
/// contents of this field. /// contents of this field.
@ -1473,8 +1473,8 @@ pub struct Sdk {
/// Serialization. The parameter values for this version of the specification and to be included in the JWS /// Serialization. The parameter values for this version of the specification and to be included in the JWS
/// header are: /// header are:
/// ///
/// "alg": PS2567 or ES256 /// - `alg`: PS2567 or ES256
/// "x5c": X.5C v3: Cert (PbSDK) and chaining certificates if present /// - `x5c`: X.5C v3: Cert (PbSDK) and chaining certificates if present
/// ///
/// All other parameters: optional /// All other parameters: optional
/// ///

View File

@ -3098,7 +3098,7 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn test_authenticate_client_secret_fulfillment_time_not_expired() { fn test_authenticate_client_secret_session_not_expired() {
let payment_intent = PaymentIntent { let payment_intent = PaymentIntent {
payment_id: "23".to_string(), payment_id: "23".to_string(),
merchant_id: "22".to_string(), merchant_id: "22".to_string(),
@ -3160,7 +3160,9 @@ mod tests {
} }
#[test] #[test]
fn test_authenticate_client_secret_fulfillment_time_expired() { fn test_authenticate_client_secret_session_expired() {
let created_at =
common_utils::date_time::now().saturating_sub(time::Duration::seconds(20 * 60));
let payment_intent = PaymentIntent { let payment_intent = PaymentIntent {
payment_id: "23".to_string(), payment_id: "23".to_string(),
merchant_id: "22".to_string(), merchant_id: "22".to_string(),
@ -3177,7 +3179,7 @@ mod tests {
billing_address_id: None, billing_address_id: None,
statement_descriptor_name: None, statement_descriptor_name: None,
statement_descriptor_suffix: None, statement_descriptor_suffix: None,
created_at: common_utils::date_time::now().saturating_sub(time::Duration::seconds(20)), created_at,
modified_at: common_utils::date_time::now(), modified_at: common_utils::date_time::now(),
fingerprint_id: None, fingerprint_id: None,
last_synced: None, last_synced: None,
@ -3206,8 +3208,7 @@ mod tests {
incremental_authorization_allowed: None, incremental_authorization_allowed: None,
authorization_count: None, authorization_count: None,
session_expiry: Some( session_expiry: Some(
common_utils::date_time::now() created_at.saturating_add(time::Duration::seconds(consts::DEFAULT_SESSION_EXPIRY)),
.saturating_add(time::Duration::seconds(consts::DEFAULT_SESSION_EXPIRY)),
), ),
request_external_three_ds_authentication: None, request_external_three_ds_authentication: None,
charges: None, charges: None,

View File

@ -754,7 +754,7 @@ mod tests {
.unwrap(); .unwrap();
assert!(updated_event.is_webhook_notified); assert!(updated_event.is_webhook_notified);
assert_eq!(updated_event.primary_object_id, "primary_object_tet"); assert_eq!(updated_event.primary_object_id, payment_id);
assert_eq!(updated_event.event_id, event_id); assert_eq!(updated_event.event_id, event_id);
} }
} }

View File

@ -99,20 +99,28 @@ mod tests {
types::{self, storage::enums}, types::{self, storage::enums},
}; };
#[actix_rt::test] async fn create_single_connection_test_transaction_pool() -> routes::AppState {
#[ignore] // Set pool size to 1 and minimum idle connection size to 0
async fn test_payment_attempt_insert() { std::env::set_var("ROUTER__MASTER_DATABASE__POOL_SIZE", "1");
std::env::set_var("ROUTER__MASTER_DATABASE__MIN_IDLE", "0");
std::env::set_var("ROUTER__REPLICA_DATABASE__POOL_SIZE", "1");
std::env::set_var("ROUTER__REPLICA_DATABASE__MIN_IDLE", "0");
let conf = Settings::new().expect("invalid settings"); let conf = Settings::new().expect("invalid settings");
let tx: oneshot::Sender<()> = oneshot::channel().0; let tx: oneshot::Sender<()> = oneshot::channel().0;
let api_client = Box::new(services::MockApiClient); let api_client = Box::new(services::MockApiClient);
let state = Box::pin(routes::AppState::with_storage( Box::pin(routes::AppState::with_storage(
conf, conf,
StorageImpl::PostgresqlTest, StorageImpl::PostgresqlTest,
tx, tx,
api_client, api_client,
)) ))
.await; .await
}
#[tokio::test]
async fn test_payment_attempt_insert() {
let state = create_single_connection_test_transaction_pool().await;
let payment_id = Uuid::new_v4().to_string(); let payment_id = Uuid::new_v4().to_string();
let current_time = common_utils::date_time::now(); let current_time = common_utils::date_time::now();
let connector = types::Connector::DummyConnector1.to_string(); let connector = types::Connector::DummyConnector1.to_string();
@ -137,22 +145,11 @@ mod tests {
assert_eq!(response.payment_id, payment_id.clone()); assert_eq!(response.payment_id, payment_id.clone());
} }
#[actix_rt::test] #[tokio::test]
/// Example of unit test /// Example of unit test
/// Kind of test: state-based testing /// Kind of test: state-based testing
async fn test_find_payment_attempt() { async fn test_find_payment_attempt() {
use crate::configs::settings::Settings; let state = create_single_connection_test_transaction_pool().await;
let conf = Settings::new().expect("invalid settings");
let tx: oneshot::Sender<()> = oneshot::channel().0;
let api_client = Box::new(services::MockApiClient);
let state = Box::pin(routes::AppState::with_storage(
conf,
StorageImpl::PostgresqlTest,
tx,
api_client,
))
.await;
let current_time = common_utils::date_time::now(); let current_time = common_utils::date_time::now();
let payment_id = Uuid::new_v4().to_string(); let payment_id = Uuid::new_v4().to_string();
let attempt_id = Uuid::new_v4().to_string(); let attempt_id = Uuid::new_v4().to_string();
@ -192,23 +189,12 @@ mod tests {
assert_eq!(response.payment_id, payment_id); assert_eq!(response.payment_id, payment_id);
} }
#[actix_rt::test] #[tokio::test]
/// Example of unit test /// Example of unit test
/// Kind of test: state-based testing /// Kind of test: state-based testing
async fn test_payment_attempt_mandate_field() { async fn test_payment_attempt_mandate_field() {
use crate::configs::settings::Settings; let state = create_single_connection_test_transaction_pool().await;
let conf = Settings::new().expect("invalid settings");
let uuid = Uuid::new_v4().to_string(); let uuid = Uuid::new_v4().to_string();
let tx: oneshot::Sender<()> = oneshot::channel().0;
let api_client = Box::new(services::MockApiClient);
let state = Box::pin(routes::AppState::with_storage(
conf,
StorageImpl::PostgresqlTest,
tx,
api_client,
))
.await;
let current_time = common_utils::date_time::now(); let current_time = common_utils::date_time::now();
let connector = types::Connector::DummyConnector1.to_string(); let connector = types::Connector::DummyConnector1.to_string();

View File

@ -20,5 +20,9 @@ strum = { version = "0.26.2", features = ["derive"] }
[dev-dependencies] [dev-dependencies]
diesel = { version = "2.1.5", features = ["postgres"] } diesel = { version = "2.1.5", features = ["postgres"] }
error-stack = "0.4.1"
serde = { version = "1.0.197", features = ["derive"] } serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.115" serde_json = "1.0.115"
utoipa = "4.2.0"
common_utils = { version = "0.1.0", path = "../common_utils" }

View File

@ -63,7 +63,7 @@ pub fn debug_as_display_derive(input: proc_macro::TokenStream) -> proc_macro::To
/// // yourself if required. /// // yourself if required.
/// #[derive(strum::Display, strum::EnumString)] /// #[derive(strum::Display, strum::EnumString)]
/// #[derive(Debug)] /// #[derive(Debug)]
/// #[diesel_enum(storage_type = "pg_enum")] /// #[diesel_enum(storage_type = "db_enum")]
/// enum Color { /// enum Color {
/// Red, /// Red,
/// Green, /// Green,
@ -153,12 +153,14 @@ pub fn diesel_enum(
/// # Example /// # Example
/// ``` /// ```
/// use router_derive::Setter; /// use router_derive::Setter;
///
/// #[derive(Setter)]
/// struct Test { /// struct Test {
/// test:u32 /// test:u32
/// } /// }
/// ``` /// ```
/// The above Example will expand to /// The above Example will expand to
/// ``` /// ```rust, ignore
/// impl Test { /// impl Test {
/// fn set_test(&mut self, val: u32) -> &mut Self { /// fn set_test(&mut self, val: u32) -> &mut Self {
/// self.test = val; /// self.test = val;
@ -381,7 +383,7 @@ pub fn api_error_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStre
/// - update_tracker /// - update_tracker
/// ///
/// ## Example /// ## Example
/// ``` /// ```rust, ignore
/// use router_derive::Operation; /// use router_derive::Operation;
/// ///
/// #[derive(Operation)] /// #[derive(Operation)]
@ -470,12 +472,14 @@ pub fn operation_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStre
/// Generates different schemas with the ability to mark few fields as mandatory for certain schema /// Generates different schemas with the ability to mark few fields as mandatory for certain schema
/// Usage /// Usage
/// ``` /// ```
/// use router_derive::PolymorphicSchema;
///
/// #[derive(PolymorphicSchema)] /// #[derive(PolymorphicSchema)]
/// #[generate_schemas(PaymentsCreateRequest, PaymentsConfirmRequest)] /// #[generate_schemas(PaymentsCreateRequest, PaymentsConfirmRequest)]
/// struct PaymentsRequest { /// struct PaymentsRequest {
/// #[mandatory_in(PaymentsCreateRequest)] /// #[mandatory_in(PaymentsCreateRequest = u64)]
/// amount: Option<u64>, /// amount: Option<u64>,
/// #[mandatory_in(PaymentsCreateRequest)] /// #[mandatory_in(PaymentsCreateRequest = String)]
/// currency: Option<String>, /// currency: Option<String>,
/// payment_method: String, /// payment_method: String,
/// } /// }
@ -520,6 +524,17 @@ pub fn polymorphic_schema(input: proc_macro::TokenStream) -> proc_macro::TokenSt
/// Implements the `Validate` trait to check if the config variable is present /// Implements the `Validate` trait to check if the config variable is present
/// Usage /// Usage
/// ``` /// ```
/// use router_derive::ConfigValidate;
///
/// #[derive(ConfigValidate)]
/// struct ConnectorParams {
/// base_url: String,
/// }
///
/// enum ApplicationError {
/// InvalidConfigurationValueError(String),
/// }
///
/// #[derive(ConfigValidate)] /// #[derive(ConfigValidate)]
/// struct Connectors { /// struct Connectors {
/// pub stripe: ConnectorParams, /// pub stripe: ConnectorParams,
@ -529,7 +544,7 @@ pub fn polymorphic_schema(input: proc_macro::TokenStream) -> proc_macro::TokenSt
/// ///
/// This will call the `validate()` function for all the fields in the struct /// This will call the `validate()` function for all the fields in the struct
/// ///
/// ``` /// ```rust, ignore
/// impl Connectors { /// impl Connectors {
/// fn validate(&self) -> Result<(), ApplicationError> { /// fn validate(&self) -> Result<(), ApplicationError> {
/// self.stripe.validate()?; /// self.stripe.validate()?;
@ -549,9 +564,26 @@ pub fn validate_config(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
/// Generates the function to get the value out of enum variant /// Generates the function to get the value out of enum variant
/// Usage /// Usage
/// ``` /// ```
/// use router_derive::TryGetEnumVariant;
///
/// impl std::fmt::Display for RedisError {
/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
/// match self {
/// Self::UnknownResult => write!(f, "Unknown result")
/// }
/// }
/// }
///
/// impl std::error::Error for RedisError {}
///
/// #[derive(Debug)]
/// enum RedisError {
/// UnknownResult
/// }
///
/// #[derive(TryGetEnumVariant)] /// #[derive(TryGetEnumVariant)]
/// #[error(RedisError(UnknownResult))] /// #[error(RedisError::UnknownResult)]
/// enum Result { /// enum RedisResult {
/// Set(String), /// Set(String),
/// Get(i32) /// Get(i32)
/// } /// }
@ -559,8 +591,8 @@ pub fn validate_config(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
/// ///
/// This will generate the function to get `String` and `i32` out of the variants /// This will generate the function to get `String` and `i32` out of the variants
/// ///
/// ``` /// ```rust, ignore
/// impl Result { /// impl RedisResult {
/// fn try_into_get(&self)-> Result<i32, RedisError> { /// fn try_into_get(&self)-> Result<i32, RedisError> {
/// match self { /// match self {
/// Self::Get(a) => Ok(a), /// Self::Get(a) => Ok(a),
@ -575,6 +607,7 @@ pub fn validate_config(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
/// } /// }
/// } /// }
/// } /// }
/// ```
#[proc_macro_derive(TryGetEnumVariant, attributes(error))] #[proc_macro_derive(TryGetEnumVariant, attributes(error))]
pub fn try_get_enum_variant(input: proc_macro::TokenStream) -> proc_macro::TokenStream { pub fn try_get_enum_variant(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = syn::parse_macro_input!(input as syn::DeriveInput); let input = syn::parse_macro_input!(input as syn::DeriveInput);

View File

@ -5,6 +5,9 @@ Environment of payment router: logger, basic config, its environment awareness.
## Example ## Example
```rust ```rust
use router_env::logger;
use tracing::{self, instrument};
#[instrument] #[instrument]
pub fn sample() -> () { pub fn sample() -> () {
logger::log!( logger::log!(

View File

@ -152,7 +152,7 @@ where
/// ///
/// ## Example /// ## Example
/// ```rust /// ```rust
/// let formatting_layer = router_env::FormattingLayer::new(router_env::service_name!(),std::io::stdout, CompactFormatter); /// let formatting_layer = router_env::FormattingLayer::new("my_service", std::io::stdout, serde_json::ser::CompactFormatter);
/// ``` /// ```
/// ///
pub fn new(service: &str, dst_writer: W, formatter: F) -> Self { pub fn new(service: &str, dst_writer: W, formatter: F) -> Self {