use crate::schema::{v1_11_0, v2_0_0};
use std::ops::Deref;
fn person_to_string(person: v2_0_0::receipt_unstrict::Person) -> String {
let first = person
.preferred_first_name
.or(person.first_name)
.unwrap_or_default();
match person.last_name {
Some(last) if !last.is_empty() => format!("{} {}", first, last),
_ => first,
}
}
impl From<v2_0_0::receipt_unstrict::FlightTicket> for v1_11_0::receipt::FlightTicket {
fn from(v2: v2_0_0::receipt_unstrict::FlightTicket) -> Self {
v1_11_0::receipt::FlightTicket {
fare: None, metadata: v2
.passenger
.as_ref()
.map(|person| {
person
.metadata
.clone()
.unwrap_or_default()
.iter()
.map(|m| v1_11_0::receipt::Metadatum {
key: m.key.clone(),
value: m.value.clone(),
})
.collect()
})
.unwrap_or_default(),
number: v2.number,
passenger: v2.passenger.map(|person| person_to_string(person)),
record_locator: None, segments: v2
.segments
.into_iter()
.map(|seg| {
v1_11_0::receipt::FlightSegment {
adjustments: vec![],
aircraft_type: None,
arrival_airport_code: seg.arrival_airport_code.to_string(),
arrival_tz: None,
class_of_service: None,
departure_airport_code: seg.departure_airport_code.to_string(),
departure_tz: None,
fare: None,
taxes: vec![],
arrival_at: seg.arrival_at,
departure_at: seg.departure_at,
flight_number: seg.flight_number,
metadata: vec![],
seat: None,
}
})
.collect(),
taxes: v2
.taxes
.unwrap_or_default()
.into_iter()
.map(|tax| v1_11_0::receipt::Tax {
amount: tax.amount,
name: tax.name,
rate: tax.rate,
})
.collect(),
}
}
}
impl From<v2_0_0::receipt_unstrict::TransitRouteItem> for v1_11_0::receipt::TransitRouteItem {
fn from(v2: v2_0_0::receipt_unstrict::TransitRouteItem) -> Self {
v1_11_0::receipt::TransitRouteItem {
adjustments: v2
.adjustments
.unwrap_or_default()
.into_iter()
.map(|adj| v1_11_0::receipt::Adjustment {
adjustment_type: match adj.adjustment_type {
v2_0_0::receipt_unstrict::AdjustmentType::AddOn => {
v1_11_0::receipt::AdjustmentType::Other
}
v2_0_0::receipt_unstrict::AdjustmentType::Discount => {
v1_11_0::receipt::AdjustmentType::Discount
}
v2_0_0::receipt_unstrict::AdjustmentType::Fee => v1_11_0::receipt::AdjustmentType::Fee,
v2_0_0::receipt_unstrict::AdjustmentType::Other => {
v1_11_0::receipt::AdjustmentType::Other
}
v2_0_0::receipt_unstrict::AdjustmentType::Tip => v1_11_0::receipt::AdjustmentType::Tip,
},
amount: adj.amount,
name: adj.name,
rate: adj.rate,
})
.collect(),
arrival_at: v2.arrival_at,
arrival_location: v2.arrival_location.map(|place| v1_11_0::receipt::Place {
name: place.name,
address: place.address.map(|addr| v1_11_0::receipt::Address {
city: addr.city,
country: addr
.country
.and_then(|c| v1_11_0::receipt::AddressCountry::try_from(c.deref().clone()).ok()),
lat: addr.lat,
lon: addr.lon,
postal_code: addr.postal_code,
region: addr
.region
.and_then(|r| v1_11_0::receipt::AddressRegion::try_from(r.deref().clone()).ok()),
street_address: addr.street_address,
tz: addr.tz,
}),
phone: place.phone.map(|p| p.to_string()),
url: place.url,
google_place_id: place.google_place_id,
image: place.image,
}),
departure_at: v2.departure_at,
departure_location: v2.departure_location.map(|place| v1_11_0::receipt::Place {
name: place.name,
address: place.address.map(|addr| v1_11_0::receipt::Address {
city: addr.city,
country: addr
.country
.and_then(|c| v1_11_0::receipt::AddressCountry::try_from(c.deref().clone()).ok()),
lat: addr.lat,
lon: addr.lon,
postal_code: addr.postal_code,
region: addr
.region
.and_then(|r| v1_11_0::receipt::AddressRegion::try_from(r.deref().clone()).ok()),
street_address: addr.street_address,
tz: addr.tz,
}),
phone: place.phone.map(|p| p.to_string()),
url: place.url,
google_place_id: place.google_place_id,
image: place.image,
}),
fare: v2.fare,
metadata: v2
.metadata
.unwrap_or_default()
.into_iter()
.map(|m| v1_11_0::receipt::Metadatum {
key: m.key,
value: m.value,
})
.collect(),
mode: match v2.mode {
Some(v2_0_0::receipt_unstrict::TransitRouteItemMode::Car) => {
Some(v1_11_0::receipt::TransitRouteItemMode::Car)
}
Some(v2_0_0::receipt_unstrict::TransitRouteItemMode::Taxi) => {
Some(v1_11_0::receipt::TransitRouteItemMode::Taxi)
}
Some(v2_0_0::receipt_unstrict::TransitRouteItemMode::Rail) => {
Some(v1_11_0::receipt::TransitRouteItemMode::Rail)
}
Some(v2_0_0::receipt_unstrict::TransitRouteItemMode::Bus) => {
Some(v1_11_0::receipt::TransitRouteItemMode::Bus)
}
Some(v2_0_0::receipt_unstrict::TransitRouteItemMode::Ferry) => {
Some(v1_11_0::receipt::TransitRouteItemMode::Ferry)
}
Some(v2_0_0::receipt_unstrict::TransitRouteItemMode::Other) => {
Some(v1_11_0::receipt::TransitRouteItemMode::Other)
}
None => None,
},
passenger: v2.passenger.map(|person| person_to_string(person)),
polyline: None,
taxes: vec![],
}
}
}
impl From<v2_0_0::receipt_unstrict::Receipt> for v1_11_0::receipt::Receipt {
fn from(v2: v2_0_0::receipt_unstrict::Receipt) -> Self {
v1_11_0::receipt::Receipt {
footer: v2.footer.into(),
header: v2.header.into(),
itemization: v2.itemization.into(),
payments: v2.payments.into_iter().map(Into::into).collect(),
schema_version: v1_11_0::receipt::SchemaVersion::try_from("1.11.0".to_string())
.unwrap_or_else(|_| v1_11_0::receipt::SchemaVersion::try_from("1.11.0").unwrap()),
}
}
}
impl From<v2_0_0::receipt_unstrict::Header> for v1_11_0::receipt::Header {
fn from(v2: v2_0_0::receipt_unstrict::Header) -> Self {
v1_11_0::receipt::Header {
currency: match v2.currency {
v2_0_0::receipt_unstrict::Currency::Usd => v1_11_0::receipt::Currency::Usd,
v2_0_0::receipt_unstrict::Currency::Eur => v1_11_0::receipt::Currency::Eur,
v2_0_0::receipt_unstrict::Currency::Jpy => v1_11_0::receipt::Currency::Jpy,
v2_0_0::receipt_unstrict::Currency::Gbp => v1_11_0::receipt::Currency::Gbp,
v2_0_0::receipt_unstrict::Currency::Aud => v1_11_0::receipt::Currency::Aud,
v2_0_0::receipt_unstrict::Currency::Cad => v1_11_0::receipt::Currency::Cad,
v2_0_0::receipt_unstrict::Currency::Chf => v1_11_0::receipt::Currency::Chf,
v2_0_0::receipt_unstrict::Currency::Cny => v1_11_0::receipt::Currency::Cnh, },
customer: v2.customer.map(Into::into),
invoice_asset_id: v2.invoice_asset_id,
invoice_number: v2.invoice_number,
invoiced_at: v2.invoiced_at,
location: v2.location.map(Into::into),
mcc: v2.mcc.map(|m| m.to_string()),
paid: v2.paid,
receipt_asset_id: v2.receipt_asset_id,
subtotal: v2.subtotal,
third_party: v2.third_party.map(Into::into),
total: v2.total,
}
}
}
impl From<v2_0_0::receipt_unstrict::Footer> for v1_11_0::receipt::Footer {
fn from(v2: v2_0_0::receipt_unstrict::Footer) -> Self {
v1_11_0::receipt::Footer {
actions: v2
.actions
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
supplemental_text: v2.supplemental_text,
}
}
}
impl From<v2_0_0::receipt_unstrict::Itemization> for v1_11_0::receipt::Itemization {
fn from(v2: v2_0_0::receipt_unstrict::Itemization) -> Self {
v1_11_0::receipt::Itemization {
car_rental: v2.car_rental.map(Into::into),
ecommerce: v2.ecommerce.map(Into::into),
flight: v2.flight.map(Into::into),
general: v2.general.map(Into::into),
lodging: v2.lodging.map(Into::into),
subscription: v2.subscription.map(Into::into),
transit_route: v2.transit_route.map(Into::into),
}
}
}
impl From<v2_0_0::receipt_unstrict::Payment> for v1_11_0::receipt::Payment {
fn from(v2: v2_0_0::receipt_unstrict::Payment) -> Self {
v1_11_0::receipt::Payment {
ach_payment: v2.ach_payment.map(Into::into),
amount: v2.amount,
card_payment: v2.card_payment.map(Into::into),
paid_at: v2.paid_at,
payment_type: v2.payment_type.map(Into::into),
}
}
}
impl From<v2_0_0::receipt_unstrict::Customer> for v1_11_0::receipt::Customer {
fn from(v2: v2_0_0::receipt_unstrict::Customer) -> Self {
v1_11_0::receipt::Customer {
address: v2.address.map(Into::into),
email: v2.email,
metadata: v2
.metadata
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
name: v2.name,
phone: v2.phone.map(|p| p.to_string()),
}
}
}
impl From<v2_0_0::receipt_unstrict::Place> for v1_11_0::receipt::Place {
fn from(v2: v2_0_0::receipt_unstrict::Place) -> Self {
v1_11_0::receipt::Place {
name: v2.name,
address: v2.address.map(Into::into),
phone: v2.phone.map(|p| p.to_string()),
url: v2.url,
google_place_id: v2.google_place_id,
image: v2.image,
}
}
}
impl From<v2_0_0::receipt_unstrict::Address> for v1_11_0::receipt::Address {
fn from(v2: v2_0_0::receipt_unstrict::Address) -> Self {
v1_11_0::receipt::Address {
city: v2.city,
country: v2
.country
.and_then(|c| v1_11_0::receipt::AddressCountry::try_from(c.deref().clone()).ok()),
lat: v2.lat,
lon: v2.lon,
postal_code: v2.postal_code,
region: v2
.region
.and_then(|r| v1_11_0::receipt::AddressRegion::try_from(r.deref().clone()).ok()),
street_address: v2.street_address,
tz: v2.tz,
}
}
}
impl From<v2_0_0::receipt_unstrict::HeaderThirdParty> for v1_11_0::receipt::HeaderThirdParty {
fn from(v2: v2_0_0::receipt_unstrict::HeaderThirdParty) -> Self {
v1_11_0::receipt::HeaderThirdParty {
make_primary: v2.make_primary,
merchant: v2.merchant.map(Into::into),
relation: match v2.relation {
v2_0_0::receipt_unstrict::HeaderThirdPartyRelation::Marketplace => {
v1_11_0::receipt::HeaderThirdPartyRelation::Marketplace
}
v2_0_0::receipt_unstrict::HeaderThirdPartyRelation::Bnpl => {
v1_11_0::receipt::HeaderThirdPartyRelation::Bnpl
}
v2_0_0::receipt_unstrict::HeaderThirdPartyRelation::DeliveryService => {
v1_11_0::receipt::HeaderThirdPartyRelation::DeliveryService
}
v2_0_0::receipt_unstrict::HeaderThirdPartyRelation::PaymentProcessor => {
v1_11_0::receipt::HeaderThirdPartyRelation::PaymentProcessor
}
v2_0_0::receipt_unstrict::HeaderThirdPartyRelation::Platform => {
v1_11_0::receipt::HeaderThirdPartyRelation::Platform
}
v2_0_0::receipt_unstrict::HeaderThirdPartyRelation::PointOfSale => {
v1_11_0::receipt::HeaderThirdPartyRelation::PointOfSale
}
},
}
}
}
impl From<v2_0_0::receipt_unstrict::Action> for v1_11_0::receipt::Action {
fn from(v2: v2_0_0::receipt_unstrict::Action) -> Self {
v1_11_0::receipt::Action {
name: v2.name,
url: v2.url,
}
}
}
impl From<v2_0_0::receipt_unstrict::Metadatum> for v1_11_0::receipt::Metadatum {
fn from(v2: v2_0_0::receipt_unstrict::Metadatum) -> Self {
v1_11_0::receipt::Metadatum {
key: v2.key,
value: v2.value,
}
}
}
impl From<v2_0_0::receipt_unstrict::Org> for v1_11_0::receipt::Org {
fn from(v2: v2_0_0::receipt_unstrict::Org) -> Self {
v1_11_0::receipt::Org {
address: v2.address.map(Into::into),
brand_color: v2
.brand_color
.and_then(|c| v1_11_0::receipt::OrgBrandColor::try_from(c.deref().clone()).ok()),
legal_name: v2.legal_name,
logo: v2.logo,
name: v2.name,
vat_number: v2.vat_number,
website: v2.website,
}
}
}
impl From<v2_0_0::receipt_unstrict::AchPayment> for v1_11_0::receipt::AchPayment {
fn from(v2: v2_0_0::receipt_unstrict::AchPayment) -> Self {
v1_11_0::receipt::AchPayment {
routing_number: v2.routing_number.to_string(),
}
}
}
impl From<v2_0_0::receipt_unstrict::CardPayment> for v1_11_0::receipt::CardPayment {
fn from(v2: v2_0_0::receipt_unstrict::CardPayment) -> Self {
v1_11_0::receipt::CardPayment {
last_four: v2.last_four.to_string(),
network: v2.network.map(Into::into),
}
}
}
impl From<v2_0_0::receipt_unstrict::CardPaymentNetwork> for v1_11_0::receipt::CardPaymentNetwork {
fn from(v2: v2_0_0::receipt_unstrict::CardPaymentNetwork) -> Self {
match v2 {
v2_0_0::receipt_unstrict::CardPaymentNetwork::Amex => {
v1_11_0::receipt::CardPaymentNetwork::Amex
}
v2_0_0::receipt_unstrict::CardPaymentNetwork::Diners => {
v1_11_0::receipt::CardPaymentNetwork::Diners
}
v2_0_0::receipt_unstrict::CardPaymentNetwork::Discover => {
v1_11_0::receipt::CardPaymentNetwork::Discover
}
v2_0_0::receipt_unstrict::CardPaymentNetwork::EftposAu => {
v1_11_0::receipt::CardPaymentNetwork::EftposAu
}
v2_0_0::receipt_unstrict::CardPaymentNetwork::Jcb => {
v1_11_0::receipt::CardPaymentNetwork::Jcb
}
v2_0_0::receipt_unstrict::CardPaymentNetwork::Mastercard => {
v1_11_0::receipt::CardPaymentNetwork::Mastercard
}
v2_0_0::receipt_unstrict::CardPaymentNetwork::Unionpay => {
v1_11_0::receipt::CardPaymentNetwork::Unionpay
}
v2_0_0::receipt_unstrict::CardPaymentNetwork::Visa => {
v1_11_0::receipt::CardPaymentNetwork::Visa
}
}
}
}
impl From<v2_0_0::receipt_unstrict::PaymentPaymentType> for v1_11_0::receipt::PaymentPaymentType {
fn from(v2: v2_0_0::receipt_unstrict::PaymentPaymentType) -> Self {
match v2 {
v2_0_0::receipt_unstrict::PaymentPaymentType::Card => {
v1_11_0::receipt::PaymentPaymentType::Card
}
v2_0_0::receipt_unstrict::PaymentPaymentType::Ach => {
v1_11_0::receipt::PaymentPaymentType::Ach
}
}
}
}
impl From<v2_0_0::receipt_unstrict::GeneralItemization> for v1_11_0::receipt::GeneralItemization {
fn from(v2: v2_0_0::receipt_unstrict::GeneralItemization) -> Self {
v1_11_0::receipt::GeneralItemization {
invoice_level_adjustments: v2
.invoice_level_adjustments
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
items: v2.items.into_iter().map(Into::into).collect(),
}
}
}
impl From<v2_0_0::receipt_unstrict::Ecommerce> for v1_11_0::receipt::Ecommerce {
fn from(v2: v2_0_0::receipt_unstrict::Ecommerce) -> Self {
v1_11_0::receipt::Ecommerce {
invoice_level_adjustments: v2
.invoice_level_adjustments
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
invoice_level_line_items: v2
.invoice_level_line_items
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
shipments: v2.shipments.into_iter().map(Into::into).collect(),
}
}
}
impl From<v2_0_0::receipt_unstrict::CarRental> for v1_11_0::receipt::CarRental {
fn from(v2: v2_0_0::receipt_unstrict::CarRental) -> Self {
v1_11_0::receipt::CarRental {
driver_name: v2.driver_name,
invoice_level_adjustments: v2
.invoice_level_adjustments
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
items: v2.items.into_iter().map(Into::into).collect(),
metadata: v2
.metadata
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
odometer_reading_in: v2.odometer_reading_in,
odometer_reading_out: v2.odometer_reading_out,
rental_at: v2.rental_at,
rental_location: v2.rental_location.into(),
return_at: v2.return_at,
return_location: v2.return_location.into(),
vehicle: v2.vehicle.map(Into::into),
}
}
}
impl From<v2_0_0::receipt_unstrict::Flight> for v1_11_0::receipt::Flight {
fn from(v2: v2_0_0::receipt_unstrict::Flight) -> Self {
v1_11_0::receipt::Flight {
invoice_level_adjustments: v2
.invoice_level_adjustments
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
itinerary_locator: v2.itinerary_locator,
tickets: v2.tickets.into_iter().map(Into::into).collect(),
}
}
}
impl From<v2_0_0::receipt_unstrict::Lodging> for v1_11_0::receipt::Lodging {
fn from(v2: v2_0_0::receipt_unstrict::Lodging) -> Self {
v1_11_0::receipt::Lodging {
check_in: v2.check_in,
check_out: v2.check_out,
guests: Some(
v2.guests
.unwrap_or_default()
.into_iter()
.map(|p| {
format!(
"{} {}",
p.first_name.unwrap_or_default(),
p.last_name.unwrap_or_default()
)
})
.collect::<Vec<_>>()
.join(","),
),
invoice_level_adjustments: v2
.invoice_level_adjustments
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
items: v2.items.into_iter().map(Into::into).collect(),
location: v2.location.into(),
metadata: v2
.metadata
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
room: v2.room,
}
}
}
impl From<v2_0_0::receipt_unstrict::Subscription> for v1_11_0::receipt::Subscription {
fn from(v2: v2_0_0::receipt_unstrict::Subscription) -> Self {
v1_11_0::receipt::Subscription {
invoice_level_adjustments: v2
.invoice_level_adjustments
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
subscription_items: v2.subscription_items.into_iter().map(Into::into).collect(),
}
}
}
impl From<v2_0_0::receipt_unstrict::TransitRoute> for v1_11_0::receipt::TransitRoute {
fn from(v2: v2_0_0::receipt_unstrict::TransitRoute) -> Self {
v1_11_0::receipt::TransitRoute {
invoice_level_adjustments: v2
.invoice_level_adjustments
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
transit_route_items: v2.transit_route_items.into_iter().map(Into::into).collect(),
}
}
}
impl From<v2_0_0::receipt_unstrict::Adjustment> for v1_11_0::receipt::Adjustment {
fn from(v2: v2_0_0::receipt_unstrict::Adjustment) -> Self {
v1_11_0::receipt::Adjustment {
adjustment_type: match v2.adjustment_type {
v2_0_0::receipt_unstrict::AdjustmentType::AddOn => v1_11_0::receipt::AdjustmentType::Other,
v2_0_0::receipt_unstrict::AdjustmentType::Discount => {
v1_11_0::receipt::AdjustmentType::Discount
}
v2_0_0::receipt_unstrict::AdjustmentType::Fee => v1_11_0::receipt::AdjustmentType::Fee,
v2_0_0::receipt_unstrict::AdjustmentType::Other => v1_11_0::receipt::AdjustmentType::Other,
v2_0_0::receipt_unstrict::AdjustmentType::Tip => v1_11_0::receipt::AdjustmentType::Tip,
},
amount: v2.amount,
name: v2.name,
rate: v2.rate,
}
}
}
impl From<v2_0_0::receipt_unstrict::Item> for v1_11_0::receipt::Item {
fn from(v2: v2_0_0::receipt_unstrict::Item) -> Self {
v1_11_0::receipt::Item {
adjustments: v2
.adjustments
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
amount: v2.amount,
date: v2.date,
description: v2.description,
group: v2.group,
metadata: v2
.metadata
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
product_image_asset_id: v2.product_image_asset_id,
quantity: v2.quantity,
taxes: v2
.taxes
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
unit: v2.unit,
unit_cost: v2.unit_cost,
unspsc: v2
.unspsc
.and_then(|u| v1_11_0::receipt::ItemUnspsc::try_from(u.deref().clone()).ok()),
url: v2.url,
}
}
}
impl From<v2_0_0::receipt_unstrict::Tax> for v1_11_0::receipt::Tax {
fn from(v2: v2_0_0::receipt_unstrict::Tax) -> Self {
v1_11_0::receipt::Tax {
amount: v2.amount,
name: v2.name,
rate: v2.rate,
}
}
}
impl From<v2_0_0::receipt_unstrict::Shipment> for v1_11_0::receipt::Shipment {
fn from(v2: v2_0_0::receipt_unstrict::Shipment) -> Self {
v1_11_0::receipt::Shipment {
destination_address: v2.destination_address.map(Into::into),
expected_delivery_at: v2.expected_delivery_at,
items: v2.items.into_iter().map(Into::into).collect(),
shipment_status: v2.shipment_status.map(Into::into),
tracking_number: v2.tracking_number,
}
}
}
impl From<v2_0_0::receipt_unstrict::ShipmentShipmentStatus>
for v1_11_0::receipt::ShipmentShipmentStatus
{
fn from(v2: v2_0_0::receipt_unstrict::ShipmentShipmentStatus) -> Self {
match v2 {
v2_0_0::receipt_unstrict::ShipmentShipmentStatus::Delivered => {
v1_11_0::receipt::ShipmentShipmentStatus::Delivered
}
v2_0_0::receipt_unstrict::ShipmentShipmentStatus::InTransit => {
v1_11_0::receipt::ShipmentShipmentStatus::InTransit
}
v2_0_0::receipt_unstrict::ShipmentShipmentStatus::Prep => {
v1_11_0::receipt::ShipmentShipmentStatus::Prep
}
}
}
}
impl From<v2_0_0::receipt_unstrict::CarRentalVehicle> for v1_11_0::receipt::CarRentalVehicle {
fn from(v2: v2_0_0::receipt_unstrict::CarRentalVehicle) -> Self {
v1_11_0::receipt::CarRentalVehicle {
description: v2.description,
image: v2.image,
}
}
}
impl From<v2_0_0::receipt_unstrict::SubscriptionItem> for v1_11_0::receipt::SubscriptionItem {
fn from(v2: v2_0_0::receipt_unstrict::SubscriptionItem) -> Self {
v1_11_0::receipt::SubscriptionItem {
adjustments: v2
.adjustments
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
amount: v2.amount,
current_period_end: v2.current_period_end_at,
current_period_start: v2.current_period_start_at,
description: v2.description,
interval: v2.interval.map(Into::into),
interval_count: v2.interval_count,
metadata: v2
.metadata
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
quantity: v2.quantity,
subscription_type: v2.subscription_type.into(),
taxes: v2
.taxes
.unwrap_or_default()
.into_iter()
.map(Into::into)
.collect(),
unit_cost: v2.unit_cost,
}
}
}
impl From<v2_0_0::receipt_unstrict::Interval> for v1_11_0::receipt::Interval {
fn from(v2: v2_0_0::receipt_unstrict::Interval) -> Self {
match v2 {
v2_0_0::receipt_unstrict::Interval::Day => v1_11_0::receipt::Interval::Day,
v2_0_0::receipt_unstrict::Interval::Week => v1_11_0::receipt::Interval::Week,
v2_0_0::receipt_unstrict::Interval::Month => v1_11_0::receipt::Interval::Month,
v2_0_0::receipt_unstrict::Interval::Year => v1_11_0::receipt::Interval::Year,
}
}
}
impl From<v2_0_0::receipt_unstrict::SubscriptionType> for v1_11_0::receipt::SubscriptionType {
fn from(v2: v2_0_0::receipt_unstrict::SubscriptionType) -> Self {
match v2 {
v2_0_0::receipt_unstrict::SubscriptionType::OneTime => {
v1_11_0::receipt::SubscriptionType::OneTime
}
v2_0_0::receipt_unstrict::SubscriptionType::Recurring => {
v1_11_0::receipt::SubscriptionType::Recurring
}
}
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use crate::schema::v2_0_0::receipt_unstrict::{
CardPaymentLastFour, FlightSegmentArrivalAirportCode, FlightSegmentDepartureAirportCode,
};
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn test_person_to_string_conversion() {
let person = v2_0_0::receipt_unstrict::Person {
first_name: Some("John".to_string()),
last_name: Some("Doe".to_string()),
preferred_first_name: None,
email: None,
phone: None,
metadata: Some(vec![]),
};
assert_eq!(person_to_string(person), "John Doe");
let person = v2_0_0::receipt_unstrict::Person {
first_name: Some("Jonathan".to_string()),
last_name: Some("Smith".to_string()),
preferred_first_name: Some("Jon".to_string()),
email: None,
phone: None,
metadata: Some(vec![]),
};
assert_eq!(person_to_string(person), "Jon Smith");
let person = v2_0_0::receipt_unstrict::Person {
first_name: Some("Alice".to_string()),
last_name: None,
preferred_first_name: None,
email: None,
phone: None,
metadata: Some(vec![]),
};
assert_eq!(person_to_string(person), "Alice");
let person = v2_0_0::receipt_unstrict::Person {
first_name: Some("Bob".to_string()),
last_name: Some("".to_string()),
preferred_first_name: None,
email: None,
phone: None,
metadata: Some(vec![]),
};
assert_eq!(person_to_string(person), "Bob");
let person = v2_0_0::receipt_unstrict::Person {
first_name: None,
last_name: None,
preferred_first_name: None,
email: Some("test@example.com".to_string()),
phone: None,
metadata: Some(vec![]),
};
assert_eq!(person_to_string(person), "");
}
#[test]
fn test_flight_ticket_conversion() {
let v2_ticket = v2_0_0::receipt_unstrict::FlightTicket {
segments: vec![v2_0_0::receipt_unstrict::FlightSegment {
adjustments: Some(vec![]),
aircraft_type: None,
arrival_airport_code: FlightSegmentArrivalAirportCode::from_str("LAX").unwrap(),
arrival_at: Some(1700000000),
arrival_tz: None,
class_of_service: None,
departure_airport_code: FlightSegmentDepartureAirportCode::from_str("JFK").unwrap(),
departure_at: Some(1699990000),
departure_tz: None,
fare: None,
flight_number: Some("AA123".to_string()),
metadata: Some(vec![]),
seat: None,
taxes: Some(vec![]),
}],
passenger: Some(v2_0_0::receipt_unstrict::Person {
first_name: Some("Jane".to_string()),
last_name: Some("Traveler".to_string()),
preferred_first_name: None,
email: Some("jane@example.com".to_string()),
phone: None,
metadata: Some(vec![v2_0_0::receipt_unstrict::Metadatum {
key: "frequent_flyer".to_string(),
value: "AA12345".to_string(),
}]),
}),
taxes: Some(vec![v2_0_0::receipt_unstrict::Tax {
name: "Federal Tax".to_string(),
rate: Some(0.075),
amount: 1500,
}]),
fare: None,
number: None,
record_locator: None,
};
let v1_ticket: v1_11_0::receipt::FlightTicket = v2_ticket.into();
assert_eq!(v1_ticket.segments.len(), 1);
assert_eq!(
v1_ticket.segments[0].flight_number,
Some("AA123".to_string())
);
assert_eq!(v1_ticket.passenger, Some("Jane Traveler".to_string()));
assert_eq!(v1_ticket.taxes.len(), 1);
assert_eq!(v1_ticket.metadata.len(), 1); assert_eq!(v1_ticket.metadata[0].key, "frequent_flyer".to_string());
assert_eq!(v1_ticket.metadata[0].value, "AA12345".to_string());
}
#[test]
fn test_flight_ticket_without_passenger() {
let v2_ticket = v2_0_0::receipt_unstrict::FlightTicket {
segments: vec![],
taxes: Some(vec![]),
fare: None,
number: None,
passenger: None,
record_locator: None,
};
let v1_ticket: v1_11_0::receipt::FlightTicket = v2_ticket.into();
assert_eq!(v1_ticket.passenger, None);
}
#[test]
fn test_person_to_string_in_flight_context() {
let person_with_preferred = v2_0_0::receipt_unstrict::Person {
first_name: Some("William".to_string()),
last_name: Some("Smith".to_string()),
preferred_first_name: Some("Bill".to_string()),
email: None,
phone: None,
metadata: Some(vec![]),
};
let v2_ticket = v2_0_0::receipt_unstrict::FlightTicket {
segments: vec![],
taxes: Some(vec![]),
passenger: Some(person_with_preferred),
fare: None,
number: None,
record_locator: None,
};
let v1_ticket: v1_11_0::receipt::FlightTicket = v2_ticket.into();
assert_eq!(v1_ticket.passenger, Some("Bill Smith".to_string()));
}
#[test]
fn test_unstrict_receipt_conversion() {
let v2_receipt = v2_0_0::receipt_unstrict::Receipt {
footer: v2_0_0::receipt_unstrict::Footer {
actions: Some(vec![]),
supplemental_text: Some("Thank you for your business!".to_string()),
},
header: v2_0_0::receipt_unstrict::Header {
currency: v2_0_0::receipt_unstrict::Currency::Usd,
customer: None,
invoice_asset_id: None,
invoice_number: Some("INV-12345".to_string()),
invoiced_at: 1700000000,
location: None,
mcc: Some(v2_0_0::receipt_unstrict::HeaderMcc::from_str("5812").unwrap()),
paid: 2500,
receipt_asset_id: None,
subtotal: 2300,
third_party: None,
total: 2500,
},
itemization: v2_0_0::receipt_unstrict::Itemization {
car_rental: None,
ecommerce: None,
flight: None,
general: Some(v2_0_0::receipt_unstrict::GeneralItemization {
invoice_level_adjustments: Some(vec![]),
items: vec![v2_0_0::receipt_unstrict::Item {
adjustments: Some(vec![]),
amount: 2300,
date: None,
description: "Test Item".to_string(),
group: None,
metadata: Some(vec![]),
product_image_asset_id: None,
quantity: Some(1.0),
taxes: Some(vec![]),
unit: Some("each".to_string()),
unit_cost: Some(2300),
unspsc: None,
url: None,
}],
}),
lodging: None,
subscription: None,
transit_route: None,
},
payments: vec![v2_0_0::receipt_unstrict::Payment {
ach_payment: None,
amount: 2500,
card_payment: Some(v2_0_0::receipt_unstrict::CardPayment {
last_four: CardPaymentLastFour::from_str("1234").unwrap(),
network: Some(v2_0_0::receipt_unstrict::CardPaymentNetwork::Visa),
}),
paid_at: 1700000000,
payment_type: Some(v2_0_0::receipt_unstrict::PaymentPaymentType::Card),
}],
schema_version: v2_0_0::receipt_unstrict::SchemaVersion::try_from("2.0.0".to_string())
.unwrap(),
};
let v1_receipt: v1_11_0::receipt::Receipt = v2_receipt.into();
assert_eq!(v1_receipt.header.currency, v1_11_0::receipt::Currency::Usd);
assert_eq!(
v1_receipt.header.invoice_number,
Some("INV-12345".to_string())
);
assert_eq!(v1_receipt.header.total, 2500);
assert_eq!(v1_receipt.payments.len(), 1);
assert_eq!(v1_receipt.payments[0].amount, 2500);
assert_eq!(
v1_receipt.footer.supplemental_text,
Some("Thank you for your business!".to_string())
);
assert!(v1_receipt.itemization.general.is_some());
let general = v1_receipt.itemization.general.unwrap();
assert_eq!(general.items.len(), 1);
assert_eq!(general.items[0].description, "Test Item");
assert_eq!(general.items[0].amount, 2300);
assert_eq!(general.items[0].unit, Some("each".to_string()));
}
}