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