Skip to main content

generate_cdr_from_tariff/
generate_cdr_from_tariff.rs

1#![expect(clippy::unwrap_used, reason = "examples can panic")]
2#![expect(clippy::print_stdout, reason = "examples can log to stdout")]
3#![expect(clippy::print_stderr, reason = "examples can log to stderr")]
4
5use std::str::FromStr as _;
6
7use chrono::{DateTime, Utc};
8use ocpi_tariffs::{cdr, generate, guess, tariff, warning, Version};
9use rust_decimal::Decimal;
10
11fn main() {
12    const TARIFF_JSON: &str = include_str!("data/tariff_time_and_parking_time_separate.json");
13
14    let report = tariff::parse_and_report(TARIFF_JSON).unwrap();
15    let guess::Report {
16        unexpected_fields,
17        version,
18    } = report;
19
20    if !unexpected_fields.is_empty() {
21        eprintln!("Strange... there are fields in the tariff that are not defined in the spec.");
22
23        for path in &unexpected_fields {
24            eprintln!("  * {path}");
25        }
26
27        eprintln!();
28    }
29
30    let tariff = version.certain_or(Version::V221);
31
32    let config = generate::Config {
33        timezone: chrono_tz::Europe::Amsterdam,
34        start_date_time: DateTime::<Utc>::from_str("2025-06-12 18:22:33+00:00").unwrap(),
35        end_date_time: DateTime::<Utc>::from_str("2025-06-12 22:33:44+00:00").unwrap(),
36        max_current_supply_amp: Decimal::from(4),
37        requested_kwh: Decimal::from(24),
38        max_power_supply_kw: Decimal::from(80),
39    };
40    let report = match cdr::generate_from_tariff(&tariff, &config) {
41        Ok(r) => r,
42        Err(set) => {
43            let (error, warnings) = set.into_parts();
44            print_error(&error);
45            print_warnings(&warnings);
46            return;
47        }
48    };
49    let (report, warnings) = report.into_parts();
50
51    print_warnings(&warnings);
52
53    let generate::Report {
54        tariff_id,
55        tariff_currency_code,
56        partial_cdr,
57    } = report;
58
59    println!("CDR genereated for tariff with id: `{tariff_id}` and currency code: `{tariff_currency_code}`");
60    println!("{partial_cdr:#?}");
61}
62
63fn print_error(error: &warning::Error<generate::Warning>) {
64    eprintln!(
65        "ERR: Unable to generate CDR due to error at path `{}`: {}",
66        error.element().path(),
67        error.warning()
68    );
69}
70
71fn print_warnings(warnings: &warning::Set<generate::Warning>) {
72    if warnings.is_empty() {
73        return;
74    }
75
76    eprintln!(
77        "WARN: {} warnings from the linting:\n {}",
78        warnings.len_warnings(),
79        warning::SetWriter::new(warnings)
80    );
81}