Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 78 additions & 20 deletions codegen/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,25 +171,23 @@ pub fn generate_structs_for_schemas(
}
openapiv3::SchemaKind::Type(openapiv3::Type::String(s)) => {
if !s.enumeration.is_empty() {
let variants_tokens: Vec<TokenStream> = s
.enumeration
.iter()
.filter_map(|v| v.as_ref())
.map(|variant| {
let variant_name = sanitize_enum_variant(variant);
let variant_ident = Ident::new(&variant_name, Span::call_site());
if variant != &variant_name {
quote! {
#[serde(rename = #variant)]
#variant_ident
}
} else {
quote! { #variant_ident }
}
})
.collect();
let mut used_variant_names = HashSet::new();
let mut variant_entries: Vec<(String, Ident)> = Vec::new();

for value in s.enumeration.iter().flatten() {
let mut variant_name = sanitize_enum_variant(value);
if variant_name == "Unknown" {
variant_name.push_str("Value");
}
while used_variant_names.contains(&variant_name) {
variant_name.push('_');
}
used_variant_names.insert(variant_name.clone());
let variant_ident = Ident::new(&variant_name, Span::call_site());
variant_entries.push((value.clone(), variant_ident));
}

if !variants_tokens.is_empty() {
if !variant_entries.is_empty() {
let description = schema
.schema_data
.description
Expand All @@ -198,12 +196,72 @@ pub fn generate_structs_for_schemas(

let deprecation = generate_deprecation_attribute(&schema.schema_data);

let variant_defs: Vec<_> = variant_entries
.iter()
.map(|(_, ident)| quote! { #ident })
.collect();

let as_str_matchers: Vec<_> = variant_entries
.iter()
.map(|(value, ident)| {
let value = value.as_str();
quote! { Self::#ident => #value }
})
.collect();

let deserialize_matchers: Vec<_> = variant_entries
.iter()
.map(|(value, ident)| {
let value = value.as_str();
quote! { #value => Some(Self::#ident) }
})
.collect();

items.push(quote! {
#description
#deprecation
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum #struct_name {
#(#variants_tokens,)*
#(#variant_defs,)*
#[doc = "Fallback variant for values unknown to this SDK."]
Unknown(String),
}

impl #struct_name {
pub fn as_str(&self) -> &str {
match self {
#(#as_str_matchers,)*
Self::Unknown(value) => value.as_str(),
}
}
}

impl serde::Serialize for #struct_name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.as_str())
}
}

impl<'de> serde::Deserialize<'de> for #struct_name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = <String as serde::Deserialize>::deserialize(deserializer)?;
let known = match value.as_str() {
#(#deserialize_matchers,)*
_ => None,
};

if let Some(variant) = known {
Ok(variant)
} else {
Ok(Self::Unknown(value))
}
}
}
});
} else {
Expand Down
217 changes: 197 additions & 20 deletions sdk/src/resources/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub type AmountEvent = f32;
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct Attributes {}
/// Three-letter [ISO4217](https://en.wikipedia.org/wiki/ISO_4217) code of the currency for the amount. Currently supported currency values are enumerated above.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Currency {
BGN,
BRL,
Expand All @@ -44,6 +44,69 @@ pub enum Currency {
RON,
SEK,
USD,
///Fallback variant for values unknown to this SDK.
Unknown(String),
}
impl Currency {
pub fn as_str(&self) -> &str {
match self {
Self::BGN => "BGN",
Self::BRL => "BRL",
Self::CHF => "CHF",
Self::CLP => "CLP",
Self::CZK => "CZK",
Self::DKK => "DKK",
Self::EUR => "EUR",
Self::GBP => "GBP",
Self::HRK => "HRK",
Self::HUF => "HUF",
Self::NOK => "NOK",
Self::PLN => "PLN",
Self::RON => "RON",
Self::SEK => "SEK",
Self::USD => "USD",
Self::Unknown(value) => value.as_str(),
}
}
}
impl serde::Serialize for Currency {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.as_str())
}
}
impl<'de> serde::Deserialize<'de> for Currency {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = <String as serde::Deserialize>::deserialize(deserializer)?;
let known = match value.as_str() {
"BGN" => Some(Self::BGN),
"BRL" => Some(Self::BRL),
"CHF" => Some(Self::CHF),
"CLP" => Some(Self::CLP),
"CZK" => Some(Self::CZK),
"DKK" => Some(Self::DKK),
"EUR" => Some(Self::EUR),
"GBP" => Some(Self::GBP),
"HRK" => Some(Self::HRK),
"HUF" => Some(Self::HUF),
"NOK" => Some(Self::NOK),
"PLN" => Some(Self::PLN),
"RON" => Some(Self::RON),
"SEK" => Some(Self::SEK),
"USD" => Some(Self::USD),
_ => None,
};
if let Some(variant) = known {
Ok(variant)
} else {
Ok(Self::Unknown(value))
}
}
}
/// Error message structure.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
Expand Down Expand Up @@ -90,32 +153,108 @@ impl std::fmt::Display for ErrorForbidden {
impl std::error::Error for ErrorForbidden {}
pub type EventId = i64;
/// Status of the transaction event.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventStatus {
#[serde(rename = "PENDING")]
Pending,
#[serde(rename = "SCHEDULED")]
Scheduled,
#[serde(rename = "FAILED")]
Failed,
#[serde(rename = "REFUNDED")]
Refunded,
#[serde(rename = "SUCCESSFUL")]
Successful,
#[serde(rename = "PAID_OUT")]
PaidOut,
///Fallback variant for values unknown to this SDK.
Unknown(String),
}
impl EventStatus {
pub fn as_str(&self) -> &str {
match self {
Self::Pending => "PENDING",
Self::Scheduled => "SCHEDULED",
Self::Failed => "FAILED",
Self::Refunded => "REFUNDED",
Self::Successful => "SUCCESSFUL",
Self::PaidOut => "PAID_OUT",
Self::Unknown(value) => value.as_str(),
}
}
}
impl serde::Serialize for EventStatus {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.as_str())
}
}
impl<'de> serde::Deserialize<'de> for EventStatus {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = <String as serde::Deserialize>::deserialize(deserializer)?;
let known = match value.as_str() {
"PENDING" => Some(Self::Pending),
"SCHEDULED" => Some(Self::Scheduled),
"FAILED" => Some(Self::Failed),
"REFUNDED" => Some(Self::Refunded),
"SUCCESSFUL" => Some(Self::Successful),
"PAID_OUT" => Some(Self::PaidOut),
_ => None,
};
if let Some(variant) = known {
Ok(variant)
} else {
Ok(Self::Unknown(value))
}
}
}
/// Type of the transaction event.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventType {
#[serde(rename = "PAYOUT")]
Payout,
#[serde(rename = "CHARGE_BACK")]
ChargeBack,
#[serde(rename = "REFUND")]
Refund,
#[serde(rename = "PAYOUT_DEDUCTION")]
PayoutDeduction,
///Fallback variant for values unknown to this SDK.
Unknown(String),
}
impl EventType {
pub fn as_str(&self) -> &str {
match self {
Self::Payout => "PAYOUT",
Self::ChargeBack => "CHARGE_BACK",
Self::Refund => "REFUND",
Self::PayoutDeduction => "PAYOUT_DEDUCTION",
Self::Unknown(value) => value.as_str(),
}
}
}
impl serde::Serialize for EventType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.as_str())
}
}
impl<'de> serde::Deserialize<'de> for EventType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = <String as serde::Deserialize>::deserialize(deserializer)?;
let known = match value.as_str() {
"PAYOUT" => Some(Self::Payout),
"CHARGE_BACK" => Some(Self::ChargeBack),
"REFUND" => Some(Self::Refund),
"PAYOUT_DEDUCTION" => Some(Self::PayoutDeduction),
_ => None,
};
if let Some(variant) = known {
Ok(variant)
} else {
Ok(Self::Unknown(value))
}
}
}
/// Pending invitation for membership.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
Expand All @@ -139,18 +278,56 @@ pub struct MandateResponse {
pub merchant_code: Option<String>,
}
/// The status of the membership.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MembershipStatus {
#[serde(rename = "accepted")]
Accepted,
#[serde(rename = "pending")]
Pending,
#[serde(rename = "expired")]
Expired,
#[serde(rename = "disabled")]
Disabled,
#[serde(rename = "unknown")]
Unknown,
UnknownValue,
///Fallback variant for values unknown to this SDK.
Unknown(String),
}
impl MembershipStatus {
pub fn as_str(&self) -> &str {
match self {
Self::Accepted => "accepted",
Self::Pending => "pending",
Self::Expired => "expired",
Self::Disabled => "disabled",
Self::UnknownValue => "unknown",
Self::Unknown(value) => value.as_str(),
}
}
}
impl serde::Serialize for MembershipStatus {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.as_str())
}
}
impl<'de> serde::Deserialize<'de> for MembershipStatus {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = <String as serde::Deserialize>::deserialize(deserializer)?;
let known = match value.as_str() {
"accepted" => Some(Self::Accepted),
"pending" => Some(Self::Pending),
"expired" => Some(Self::Expired),
"disabled" => Some(Self::Disabled),
"unknown" => Some(Self::UnknownValue),
_ => None,
};
if let Some(variant) = known {
Ok(variant)
} else {
Ok(Self::Unknown(value))
}
}
}
/// Set of user-defined key-value pairs attached to the object. Partial updates are not supported. When updating, always submit whole metadata. Maximum of 64 parameters are allowed in the object.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
Expand Down
Loading