use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
#[cfg(feature = "diesel")]
use std::io::Write;
#[cfg(feature = "diesel")]
use diesel::deserialize::{self, FromSql, FromSqlRow};
#[cfg(feature = "diesel")]
use diesel::prelude::*;
#[cfg(feature = "diesel")]
use diesel::serialize::{self, IsNull, Output, ToSql};
#[cfg(feature = "diesel")]
use diesel::{expression::AsExpression, sql_types::Text};
#[cfg(feature = "diesel")]
use diesel::mysql::{Mysql, MysqlValue};
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq, Hash)]
#[cfg_attr(
feature = "diesel",
derive(diesel::expression::AsExpression, diesel::deserialize::FromSqlRow)
)]
#[cfg_attr(feature = "diesel", diesel(sql_type = Text))]
pub enum TransactionEvent {
#[serde(rename = "booking")]
Booking,
#[serde(rename = "invoice")]
Invoice,
#[serde(rename = "itinerary")]
Itinerary,
#[serde(rename = "receipt")]
Receipt,
}
impl fmt::Display for TransactionEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let serialized = serde_json::to_string(self).unwrap().replace("\"", "");
write!(f, "{}", serialized)
}
}
impl FromStr for TransactionEvent {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"booking" => Ok(TransactionEvent::Booking),
"invoice" => Ok(TransactionEvent::Invoice),
"itinerary" => Ok(TransactionEvent::Itinerary),
"receipt" => Ok(TransactionEvent::Receipt),
_ => Err("Unrecognized TransactionEvent enum variant".to_string()),
}
}
}
impl Into<WebhookEventType> for TransactionEvent {
fn into(self) -> WebhookEventType {
match self {
TransactionEvent::Booking => WebhookEventType::Booking,
TransactionEvent::Invoice => WebhookEventType::Invoice,
TransactionEvent::Itinerary => WebhookEventType::Itinerary,
TransactionEvent::Receipt => WebhookEventType::Receipt,
}
}
}
impl TryFrom<WebhookEventType> for TransactionEvent {
type Error = String;
fn try_from(value: WebhookEventType) -> Result<Self, Self::Error> {
match value {
WebhookEventType::Itinerary => Ok(TransactionEvent::Itinerary),
WebhookEventType::Receipt => Ok(TransactionEvent::Receipt),
_ => Err(format!(
"TransactionEvent cannot be created from WebhookEventType::{}",
value
)),
}
}
}
#[cfg(feature = "diesel")]
impl ToSql<Text, Mysql> for TransactionEvent {
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> serialize::Result {
out.write_all(&*self.to_string().as_bytes())?;
Ok(IsNull::No)
}
}
#[cfg(feature = "diesel")]
impl FromSql<Text, Mysql> for TransactionEvent {
fn from_sql(bytes: MysqlValue<'_>) -> deserialize::Result<Self> {
match bytes.as_bytes() {
b"itinerary" => Ok(TransactionEvent::Itinerary),
b"receipt" => Ok(TransactionEvent::Receipt),
_ => Err("Unrecognized misuse_code enum variant".into()),
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq, Hash)]
#[cfg_attr(
feature = "diesel",
derive(diesel::expression::AsExpression, diesel::deserialize::FromSqlRow)
)]
#[cfg_attr(feature = "diesel", diesel(sql_type = Text))]
pub enum WebhookEventType {
#[serde(rename = "booking")]
Booking,
#[serde(rename = "booking.decrypted")]
BookingDecrypted,
#[serde(rename = "customer.deregistered_by_sender")]
CustomerDeregisteredBySender,
#[serde(rename = "customer.registered_by_sender")]
CustomerRegisteredBySender,
#[serde(rename = "invoice")]
Invoice,
#[serde(rename = "invoice.decrypted")]
InvoiceDecrypted,
#[serde(rename = "itinerary")]
Itinerary,
#[serde(rename = "itinerary.decrypted")]
ItineraryDecrypted,
#[serde(rename = "receipt")]
Receipt,
#[serde(rename = "receipt.decrypted")]
ReceiptDecrypted,
#[serde(rename = "transit_route.status.updated")]
TransitRouteStatusUpdated,
#[serde(rename = "transit_route.location.updated")]
TransitRouteLocationUpdated,
}
impl fmt::Display for WebhookEventType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let serialized = serde_json::to_string(self).unwrap().replace("\"", "");
write!(f, "{}", serialized)
}
}
impl FromStr for WebhookEventType {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"customer.deregistered_by_sender" => Ok(WebhookEventType::CustomerDeregisteredBySender),
"customer.registered_by_sender" => Ok(WebhookEventType::CustomerRegisteredBySender),
"itinerary" => Ok(WebhookEventType::Itinerary),
"itinerary.decrypted" => Ok(WebhookEventType::ItineraryDecrypted),
"receipt" => Ok(WebhookEventType::Receipt),
"receipt.decrypted" => Ok(WebhookEventType::ReceiptDecrypted),
"transit_route.status.updated" => Ok(WebhookEventType::TransitRouteStatusUpdated),
"transit_route.location.updated" => Ok(WebhookEventType::TransitRouteLocationUpdated),
_ => Err("Unrecognized WebhookEventType enum variant".to_string()),
}
}
}
#[cfg(feature = "diesel")]
impl ToSql<Text, Mysql> for WebhookEventType {
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> serialize::Result {
out.write_all(&*self.to_string().as_bytes())?;
Ok(IsNull::No)
}
}
#[cfg(feature = "diesel")]
impl FromSql<Text, Mysql> for WebhookEventType {
fn from_sql(bytes: MysqlValue<'_>) -> deserialize::Result<Self> {
match bytes.as_bytes() {
b"customer.deregistered_by_sender" => Ok(WebhookEventType::CustomerDeregisteredBySender),
b"customer.registered_by_sender" => Ok(WebhookEventType::CustomerRegisteredBySender),
b"itinerary" => Ok(WebhookEventType::Itinerary),
b"itinerary.decrypted" => Ok(WebhookEventType::ItineraryDecrypted),
b"receipt" => Ok(WebhookEventType::Receipt),
b"receipt.decrypted" => Ok(WebhookEventType::ReceiptDecrypted),
b"transit_route.status.updated" => Ok(WebhookEventType::TransitRouteStatusUpdated),
b"transit_route.location.updated" => Ok(WebhookEventType::TransitRouteLocationUpdated),
_ => Err("Unrecognized misuse_code enum variant".into()),
}
}
}
#[derive(Deserialize, Serialize)]
pub struct WebhookEvent<T> {
pub event: WebhookEventType,
pub event_id: Option<String>,
pub event_at: Option<i64>,
pub delivery_id: Option<String>,
pub delivery_at: Option<i64>,
pub data: T,
}