Skip to main content

price_cdr_with_known_version/
price_cdr_with_known_version.rs

1#![expect(clippy::expect_used, reason = "examples can panic")]
2#![expect(clippy::print_stderr, reason = "examples can log to stderr")]
3
4use chrono_tz::Tz;
5
6use ocpi_tariffs::{cdr, price, warning, Version};
7
8fn main() {
9    const CDR_JSON: &str = include_str!("data/cdr_time_and_parking_time.json");
10
11    // If you know the version and timezone of a CDR you simply pass them into the `cdr::parse_with_version` fn.
12    let report = cdr::parse_with_version(CDR_JSON, Version::V211).expect("unable to parse CDR");
13    let cdr::ParseReport {
14        cdr,
15        unexpected_fields,
16    } = report;
17
18    if !unexpected_fields.is_empty() {
19        eprintln!("Strange... there are fields in the CDR that are not defined in the spec.");
20
21        for path in &unexpected_fields {
22            eprintln!("{path}");
23        }
24    }
25
26    let report = match cdr::price(&cdr, price::TariffSource::UseCdr, Tz::Europe__Amsterdam) {
27        Ok(r) => r,
28        Err(set) => {
29            let (error, warnings) = set.into_parts();
30            print_pricing_error(&error);
31            print_pricing_warnings(&warnings);
32            return;
33        }
34    };
35
36    let (report, warnings) = report.into_parts();
37    print_pricing_warnings(&warnings);
38
39    // The various fields of the `price::Report` can be examined or converted to JSON.
40    let price::Report {
41        periods: _,
42        tariff_used: _,
43        tariff_reports: _,
44        timezone: _,
45        billed_energy: _,
46        billed_parking_time: _,
47        total_charging_time: _,
48        billed_charging_time: _,
49        total_cost: _,
50        total_fixed_cost: _,
51        total_time: _,
52        total_time_cost: _,
53        total_energy: _,
54        total_energy_cost: _,
55        total_parking_time: _,
56        total_parking_cost: _,
57        total_reservation_cost: _,
58    } = report;
59}
60
61fn print_pricing_error(error: &warning::Error<price::Warning>) {
62    eprintln!(
63        "ERR: Unable to price CDR due to error at path `{}`: {}",
64        error.element().path(),
65        error.warning()
66    );
67}
68
69fn print_pricing_warnings(warnings: &warning::Set<price::Warning>) {
70    if warnings.is_empty() {
71        return;
72    }
73
74    eprintln!(
75        "WARN: {} warnings from the pricing:\n {}",
76        warnings.len_warnings(),
77        warning::SetWriter::new(warnings)
78    );
79}