depot/rust/passgen/src/walletobjects.rs

153 lines
5.2 KiB
Rust

use anyhow::{anyhow, Result};
pub use google_walletobjects1::api::*;
use crate::resolution792::BoardingPass;
use crate::static_data::AIRLINE_DATA;
pub fn passes_from_barcode(
issuer_id: &str,
boarding_pass: BoardingPass,
) -> Result<(Vec<FlightClass>, Vec<FlightObject>)> {
if boarding_pass.legs.len() > 1 {
return Err(anyhow!("multi-leg trips aren't supported yet"));
}
let leg = &boarding_pass.legs[0];
let airline_data = AIRLINE_DATA.get(&leg.operating_carrier).ok_or_else(|| {
anyhow!(
"no AIRLINE_DATA has been provided for {} yet",
leg.operating_carrier
)
})?;
let frequent_flyer_program_data = if leg.frequent_flyer_airline.is_none() {
None
} else {
AIRLINE_DATA.get(&leg.frequent_flyer_airline.as_ref().unwrap())
};
let id_prefix = format!(
"{}.{}{}-{}-{}{}",
issuer_id,
leg.operating_carrier,
leg.flight_number,
leg.date_of_flight,
leg.origin_airport,
leg.destination_airport
);
let class_id = &id_prefix;
let pass_id = format!("{}-{}", &id_prefix, leg.check_in_sequence);
let class = FlightClass {
id: Some(class_id.clone()),
issuer_name: Some(airline_data.name.to_string()),
hex_background_color: Some(airline_data.boarding_pass_background_colour.to_string()),
review_status: Some("UNDER_REVIEW".to_string()),
boarding_and_seating_policy: Some(BoardingAndSeatingPolicy {
boarding_policy: Some(airline_data.boarding_policy.to_string()),
seat_class_policy: Some(airline_data.seat_class_policy.to_string()),
..Default::default()
}),
origin: Some(AirportInfo {
airport_iata_code: Some(leg.origin_airport.clone()),
..Default::default()
}),
destination: Some(AirportInfo {
airport_iata_code: Some(leg.destination_airport.clone()),
..Default::default()
}),
flight_header: Some(FlightHeader {
carrier: Some(FlightCarrier {
airline_alliance_logo: airline_data.alliance_logo_url.map(url_to_image),
airline_logo: Some(url_to_image(airline_data.logo_url)),
airline_name: Some(localized_string("en-GB", airline_data.name)),
carrier_iata_code: Some(leg.operating_carrier.to_string()),
..Default::default()
}),
flight_number: Some(leg.flight_number.to_string()),
..Default::default()
}),
..Default::default()
};
let pass_barcode = String::from_utf8(boarding_pass.initial_data)?;
let eticket_number =
if leg.airline_numeric_code.is_some() && leg.document_serial_number.is_some() {
Some(format!(
"{}-{}",
leg.airline_numeric_code.as_ref().unwrap(),
leg.document_serial_number.as_ref().unwrap()
))
} else {
Some("125-2150000000".to_string())
};
let pass = FlightObject {
id: Some(pass_id),
class_id: Some(class_id.clone()),
state: Some("ACTIVE".to_string()),
passenger_name: Some(boarding_pass.passenger_name.clone()),
reservation_info: Some(ReservationInfo {
confirmation_code: Some(leg.operating_carrier_pnr.clone()),
eticket_number,
frequent_flyer_info: if frequent_flyer_program_data.is_none() {
None
} else {
Some(FrequentFlyerInfo {
frequent_flyer_program_name: frequent_flyer_program_data
.unwrap().frequent_flyer_program_name
.map(|n| localized_string("en-GB", n)),
frequent_flyer_number: leg.frequent_flyer_number.clone(),
..Default::default()
})
},
..Default::default()
}),
boarding_and_seating_info: Some(BoardingAndSeatingInfo {
boarding_group: Some("GROUP1".to_string()),
seat_class: Some("Club World".to_string()),
seat_number: Some(leg.seat_number.clone()),
sequence_number: Some(leg.check_in_sequence.clone()),
boarding_privilege_image: airline_data
.boarding_privilege_logo_url
.clone()
.map(|u| url_to_image(u)),
..Default::default()
}),
barcode: Some(Barcode {
type_: Some("aztec".to_string()),
value: Some(pass_barcode),
..Default::default()
}),
hex_background_color: Some("#b38f47".to_string()),
..Default::default()
};
Ok((vec![class], vec![pass]))
}
pub fn localized_string(locale: &str, s: &str) -> LocalizedString {
LocalizedString {
default_value: Some(TranslatedString {
language: Some(locale.to_string()),
value: Some(s.to_string()),
..Default::default()
}),
..Default::default()
}
}
pub fn url_to_image(url: &str) -> Image {
Image {
source_uri: Some(ImageUri {
uri: Some(url.to_string()),
..Default::default()
}),
..Default::default()
}
}