Skip to content

Commit

Permalink
feat: custom deserializer and serializer for ElementSize
Browse files Browse the repository at this point in the history
  • Loading branch information
kashif-m committed Dec 3, 2024
1 parent 0c2691f commit 376253d
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 10 deletions.
6 changes: 5 additions & 1 deletion crates/api_models/src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2680,6 +2680,8 @@ pub struct PaymentLinkConfigRequest {
pub transaction_details: Option<Vec<PaymentLinkTransactionDetails>>,
/// Configurations for image
pub background_image: Option<PaymentLinkBackgroundImageConfig>,
/// Custom layout for details section
pub details_layout: Option<api_enums::PaymentLinkDetailsLayout>
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)]
Expand Down Expand Up @@ -2711,7 +2713,7 @@ pub struct TransactionDetailsUiConfiguration {
pub struct PaymentLinkBackgroundImageConfig {
/// URL of the image
#[schema(value_type = String, example = "https://hyperswitch.io/favicon.ico")]
pub url: url::Url,
pub url: common_utils::types::Url,
/// Position of the image in the UI
#[schema(value_type = Option<ElementPosition>, example = "top-left")]
pub position: Option<api_enums::ElementPosition>,
Expand Down Expand Up @@ -2744,6 +2746,8 @@ pub struct PaymentLinkConfig {
pub transaction_details: Option<Vec<PaymentLinkTransactionDetails>>,
/// Configurations for image
pub background_image: Option<PaymentLinkBackgroundImageConfig>,
/// Custom layout for details section
pub details_layout: Option<api_enums::PaymentLinkDetailsLayout>
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
Expand Down
128 changes: 124 additions & 4 deletions crates/common_enums/src/enums/ui.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
use serde;
use std::fmt;
use serde::{Serialize, Deserialize, Deserializer, de::Visitor};
use utoipa::ToSchema;

#[derive(Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
#[derive(
Clone,
Copy,
Debug,
Default,
Eq,
Hash,
PartialEq,
Serialize,
Deserialize,
strum::Display,
strum::EnumString,
ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "kebab-case")]
#[strum(serialize_all = "kebab-case")]
pub enum ElementPosition {
Left,
#[default]
Expand All @@ -16,15 +32,119 @@ pub enum ElementPosition {
Center,
}

#[derive(Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
#[derive(
Clone,
Copy,
Debug,
Eq,
Hash,
PartialEq,
strum::Display,
strum::EnumString,
ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
pub enum ElementSize {
Variants(SizeVariants),
Percentage(u32),
Pixels(u32),
}

#[derive(Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
#[derive(
Clone,
Copy,
Debug,
Default,
Eq,
Hash,
PartialEq,
Serialize,
Deserialize,
strum::Display,
strum::EnumString,
ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
pub enum SizeVariants {
#[default]
Cover,
Contain,
}

#[derive(
Clone,
Copy,
Debug,
Default,
Eq,
Hash,
PartialEq,
Serialize,
Deserialize,
strum::Display,
strum::EnumString,
ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
pub enum PaymentLinkDetailsLayout {
#[default]
Layout1,
Layout2,
}

impl<'de> Deserialize<'de> for ElementSize {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ElementSizeVisitor;

impl<'de> Visitor<'de> for ElementSizeVisitor {
type Value = ElementSize;

fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a string with possible values - contain, cover or values in percentage or pixels. For eg: 48px or 50%")
}

fn visit_str<E>(self, value: &str) -> Result<ElementSize, E>
where
E: serde::de::Error,
{
if let Some(percent) = value.strip_suffix('%') {
percent.parse::<u32>()
.map(ElementSize::Percentage)
.map_err(E::custom)
} else if let Some(px) = value.strip_suffix("px") {
px.parse::<u32>()
.map(ElementSize::Pixels)
.map_err(E::custom)
} else {
match value {
"cover" => Ok(ElementSize::Variants(SizeVariants::Cover)),
"contain" => Ok(ElementSize::Variants(SizeVariants::Contain)),
_ => Err(E::custom("invalid size variant")),
}
}
}
}

deserializer.deserialize_str(ElementSizeVisitor)
}
}

impl Serialize for ElementSize {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
match self {
ElementSize::Variants(variant) => serializer.serialize_str(variant.to_string().as_str()),
ElementSize::Pixels(pixel_count) => serializer.serialize_str(format!("{}px", pixel_count).as_str()),
ElementSize::Percentage(pixel_count) => serializer.serialize_str(format!("{}%", pixel_count).as_str()),
}
}
}
9 changes: 9 additions & 0 deletions crates/diesel_models/src/business_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,15 @@ pub struct PaymentLinkConfigRequest {
pub enabled_saved_payment_method: Option<bool>,
pub hide_card_nickname_field: Option<bool>,
pub show_card_form_by_default: Option<bool>,
pub background_image: Option<PaymentLinkBackgroundImageConfig>,
pub details_layout: Option<common_enums::PaymentLinkDetailsLayout>
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct PaymentLinkBackgroundImageConfig {
pub url: common_utils::types::Url,
pub position: Option<common_enums::ElementPosition>,
pub size: Option<common_enums::ElementSize>,
}

common_utils::impl_to_sql_from_sql_json!(BusinessPaymentLinkConfig);
Expand Down
5 changes: 5 additions & 0 deletions crates/router/src/core/payment_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ pub async fn form_payment_link_data(
allowed_domains: DEFAULT_ALLOWED_DOMAINS,
transaction_details: None,
background_image: None,
details_layout: None,
}
};

Expand Down Expand Up @@ -648,6 +649,9 @@ pub fn get_payment_link_config_based_on_priority(
hide_card_nickname_field,
show_card_form_by_default,
allowed_domains,
details_layout: payment_create_link_config
.as_ref()
.and_then(|payment_link_config| payment_link_config.theme_config.details_layout.clone()),
transaction_details: payment_create_link_config
.as_ref()
.and_then(|payment_link_config| payment_link_config.theme_config.transaction_details.clone()),
Expand Down Expand Up @@ -758,6 +762,7 @@ pub async fn get_payment_link_status(
allowed_domains: DEFAULT_ALLOWED_DOMAINS,
transaction_details: None,
background_image: None,
details_layout: None,
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ body {
#hyper-checkout-merchant-image,
#hyper-checkout-cart-image {
height: 64px;
width: 64px;
padding: 0 10px;
border-radius: 4px;
display: flex;
align-self: flex-start;
Expand All @@ -153,8 +153,7 @@ body {
}

#hyper-checkout-merchant-image > img {
height: 48px;
width: 48px;
height: 40px;
}

#hyper-checkout-cart-image {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,6 @@ function renderPaymentDetails(paymentDetails) {
// Create merchant logo's node
var merchantLogoNode = document.createElement("img");
merchantLogoNode.src = paymentDetails.merchant_logo;
merchantLogoNode.setAttribute("width", "48"); // Set width to 100 pixels
merchantLogoNode.setAttribute("height", "48");

// Create expiry node
Expand Down
37 changes: 36 additions & 1 deletion crates/router/src/types/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1946,6 +1946,10 @@ impl ForeignFrom<api_models::admin::PaymentLinkConfigRequest>
enabled_saved_payment_method: item.enabled_saved_payment_method,
hide_card_nickname_field: item.hide_card_nickname_field,
show_card_form_by_default: item.show_card_form_by_default,
details_layout: item.details_layout,
background_image: item
.background_image
.map(|background_image| background_image.foreign_into()),
}
}
}
Expand All @@ -1964,7 +1968,38 @@ impl ForeignFrom<diesel_models::business_profile::PaymentLinkConfigRequest>
hide_card_nickname_field: item.hide_card_nickname_field,
show_card_form_by_default: item.show_card_form_by_default,
transaction_details: None,
background_image: item.background_image,
details_layout: item.details_layout,
background_image: item
.background_image
.map(|background_image| background_image.foreign_into()),
}
}
}

impl ForeignFrom<diesel_models::business_profile::PaymentLinkBackgroundImageConfig>
for api_models::admin::PaymentLinkBackgroundImageConfig
{
fn foreign_from(
item: diesel_models::business_profile::PaymentLinkBackgroundImageConfig,
) -> Self {
Self {
url: item.url,
position: item.position,
size: item.size,
}
}
}

impl ForeignFrom<api_models::admin::PaymentLinkBackgroundImageConfig>
for diesel_models::business_profile::PaymentLinkBackgroundImageConfig
{
fn foreign_from(
item: api_models::admin::PaymentLinkBackgroundImageConfig,
) -> Self {
Self {
url: item.url,
position: item.position,
size: item.size,
}
}
}
Expand Down

0 comments on commit 376253d

Please sign in to comment.