1use crate::conversion::*;
2use crate::en1545date::from_en1545_date_and_time;
3use chrono::prelude::*;
4
5#[derive(Debug)]
6pub struct History {
7 pub transaction_type: TransactionType,
8 pub boarding_datetime: DateTime<Utc>,
9 pub transfer_end_datetime: DateTime<Utc>,
10 pub ticket_fare_cents: u16,
11 pub group_size: u8,
12 pub remaining_value: u32,
14}
15
16pub fn create_history_entries(history_bytes: &[u8]) -> Vec<History> {
17 let num_entries = history_bytes.len() / 12; let entry_size = 96; let mut history_entries: Vec<History> = vec![];
20
21 for i in 0..num_entries {
22 if history_bytes[i * 12 + 1] == 0
26 && history_bytes[i * 12 + 2] == 0
27 && history_bytes[i * 12 + 3] == 0
28 && history_bytes[i * 13 + 3] == 0
29 {
30 continue;
31 }
32 let entry_offset = i * entry_size;
33 let transaction_type = get_bits_as_u8(history_bytes, 0 + entry_offset, 1);
34 let boarding_date = get_bits_as_u16(history_bytes, 1 + entry_offset, 14);
35 let boarding_time = get_bits_as_u16(history_bytes, 15 + entry_offset, 11);
36 let end_date = get_bits_as_u16(history_bytes, 26 + entry_offset, 14);
37 let end_time = get_bits_as_u16(history_bytes, 40 + entry_offset, 11);
38 let ticket_fare = get_bits_as_u16(history_bytes, 51 + entry_offset, 14);
39 let group_size = get_bits_as_u8(history_bytes, 65 + entry_offset, 6);
40 let remaining_value = get_bits_as_u32(history_bytes, 71 + entry_offset, 20);
41
42 history_entries.push(History {
43 transaction_type: TransactionType::new(transaction_type),
44 boarding_datetime: from_en1545_date_and_time(boarding_date, boarding_time),
45 transfer_end_datetime: from_en1545_date_and_time(end_date, end_time),
46 ticket_fare_cents: ticket_fare,
47 group_size,
48 remaining_value,
49 });
50 }
51
52 history_entries
53}
54
55#[repr(u32)]
56#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
57pub enum TransactionType {
58 SeasonPass = 0,
59 ValueTicket = 1,
60}
61
62impl TransactionType {
63 pub(crate) fn new(type_value: u8) -> TransactionType {
64 match type_value {
65 0 => TransactionType::SeasonPass,
66 1 => TransactionType::ValueTicket,
67 _ => panic!("Unsupported TransactionType value"),
68 }
69 }
70}