parse

Function parse 

Source
pub fn parse(cdr_json: &str) -> Result<CdrVersion<'_>, ParseError>
Expand description

Parse the JSON and try guess the Version based on fields defined in the OCPI v2.1.1[^spec-v211] and v2.2.1[^spec-v221] CDR spec.

The parser is forgiving and will not complain if the CDR JSON is missing required fields. The parser will also not complain if unexpected fields are present in the JSON. The Version guess is based on fields that exist.

§Example

let cdr = cdr::parse(CDR_JSON)?;

match cdr {
    guess::Version::Certain(cdr) => {
        println!("The CDR version is `{}`", cdr.version());
    },
    guess::Version::Uncertain(_cdr) => {
        eprintln!("Unable to guess the version of given CDR JSON.");
    }
}
Examples found in repository?
examples/price_cdr_with_unknown_version.rs (line 13)
6fn main() {
7    const CDR_JSON: &str =
8        include_str!("../test_data/v211/real_world/time_and_parking_time/cdr.json");
9
10    // First the raw JSON should be parsed into a `cdr::Versioned` object.
11    // The `cdr::Report` returned from calling `cdr::parse` contains a `cdr::Versioned` object
12    // and a potential list of unexpected fields based on the OCPI v221 spec.
13    let cdr = cdr::parse(CDR_JSON).expect("Unable to parse CDR JSON");
14
15    // The guessed Version can be either certain or uncertain.
16    // In this case we discard the CDR object and try convert it into a version.
17    // If the version is uncertain then fallback to presuming the CDR is v211.
18    let cdr = cdr.certain_or(Version::V211);
19
20    // The timezone can be inferred or found in the CDR, but a versioned CDR is required.
21    let (timezone_source, warnings) = timezone::find_or_infer(&cdr).into_parts();
22
23    let Some(timezone_source) = timezone_source else {
24        eprintln!("Unable to infer timezone");
25        print_timezone_warnings(&cdr, &warnings.into_report());
26        return;
27    };
28
29    if !warnings.is_empty() {
30        print_timezone_warnings(&cdr, &warnings.into_report());
31    }
32
33    // We don't care whether the timezone was found or inferred.
34    let timezone = timezone_source.into_timezone();
35    let report = cdr::parse_with_version(CDR_JSON, Version::V211).expect("unable to parse CDR");
36    let cdr::ParseReport {
37        cdr,
38        unexpected_fields,
39    } = report;
40
41    if !unexpected_fields.is_empty() {
42        eprintln!("Strange... there are fields in the CDR that are not defined in the spec.");
43
44        for path in &unexpected_fields {
45            eprintln!("{path}");
46        }
47    }
48
49    let report =
50        cdr::price(cdr, price::TariffSource::UseCdr, timezone).expect("unable to price CDR JSON");
51
52    // The various fields of the `price::Report` can be examined or converted to JSON.
53    let price::Report {
54        warnings: _,
55        periods: _,
56        tariff: _,
57        tariff_reports: _,
58        timezone: _,
59        billed_energy: _,
60        billed_parking_time: _,
61        total_charging_time: _,
62        billed_charging_time: _,
63        total_cost: _,
64        total_fixed_cost: _,
65        total_time: _,
66        total_time_cost: _,
67        total_energy: _,
68        total_energy_cost: _,
69        total_parking_time: _,
70        total_parking_cost: _,
71        total_reservation_cost: _,
72    } = report;
73}