price_cdr_with_unknown_version/
price_cdr_with_unknown_version.rs1#![expect(clippy::expect_used, reason = "examples can panic")]
2#![expect(clippy::print_stderr, reason = "examples can log to stderr")]
3
4use ocpi_tariffs::{cdr, price, timezone, warning, Version};
5
6fn main() {
7 const CDR_JSON: &str = include_str!("data/cdr_time_and_parking_time.json");
8
9 let cdr = cdr::parse(CDR_JSON).expect("Unable to parse CDR JSON");
13
14 let cdr = cdr.certain_or(Version::V211);
18
19 let timezone = match timezone::find_or_infer(&cdr) {
21 Ok(tz) => tz,
22 Err(err_set) => {
23 let (error, warnings) = err_set.into_parts();
24 eprintln!("Unable to infer timezone");
25 print_timezone_error(&error);
26 print_timezone_warnings(&warnings);
27 return;
28 }
29 };
30 let (timezone_source, warnings) = timezone.into_parts();
31
32 if !warnings.is_empty() {
33 print_timezone_warnings(&warnings);
34 }
35
36 let timezone = timezone_source.into_timezone();
38 let report = cdr::parse_with_version(CDR_JSON, Version::V211).expect("Unable to parse CDR");
39 let cdr::ParseReport {
40 cdr,
41 unexpected_fields,
42 } = report;
43
44 if !unexpected_fields.is_empty() {
45 eprintln!("Strange... there are fields in the CDR that are not defined in the spec.");
46
47 for path in &unexpected_fields {
48 eprintln!("{path}");
49 }
50 }
51
52 let report = match cdr::price(&cdr, price::TariffSource::UseCdr, timezone) {
53 Ok(r) => r,
54 Err(set) => {
55 let (error, warnings) = set.into_parts();
56 print_pricing_error(&error);
57 print_pricing_warnings(&warnings);
58 return;
59 }
60 };
61
62 let (report, warnings) = report.into_parts();
63
64 print_pricing_warnings(&warnings);
65
66 let price::Report {
68 periods: _,
69 tariff_used: _,
70 tariff_reports: _,
71 timezone: _,
72 billed_energy: _,
73 billed_parking_time: _,
74 total_charging_time: _,
75 billed_charging_time: _,
76 total_cost: _,
77 total_fixed_cost: _,
78 total_time: _,
79 total_time_cost: _,
80 total_energy: _,
81 total_energy_cost: _,
82 total_parking_time: _,
83 total_parking_cost: _,
84 total_reservation_cost: _,
85 } = report;
86}
87
88fn print_timezone_error(error: &warning::Error<timezone::Warning>) {
89 eprintln!(
90 "ERR: Unable to find timezone due to error at path `{}`: {}",
91 error.element().path(),
92 error.warning()
93 );
94}
95
96fn print_timezone_warnings(warnings: &warning::Set<timezone::Warning>) {
97 if warnings.is_empty() {
98 return;
99 }
100
101 eprintln!(
102 "WARN: {} warnings from the timezone search",
103 warnings.len_warnings()
104 );
105
106 eprintln!(
107 "WARN: {} warnings from the timezone search:\n {}",
108 warnings.len_warnings(),
109 warning::SetWriter::new(warnings)
110 );
111}
112
113fn print_pricing_error(error: &warning::Error<price::Warning>) {
114 eprintln!(
115 "ERR: Unable to price CDR due to error at path `{}`: {}",
116 error.element().path(),
117 error.warning()
118 );
119}
120
121fn print_pricing_warnings(warnings: &warning::Set<price::Warning>) {
122 if warnings.is_empty() {
123 return;
124 }
125
126 eprintln!(
127 "WARN: {} warnings from the linting:\n {}",
128 warnings.len_warnings(),
129 warning::SetWriter::new(warnings)
130 );
131}