Skip to main content

Module convert

Module convert 

Source
Available on crate feature convert only.
Expand description

Carrying objects between OCPI versions, with an explicit account of what was lost.

A hub that connects a 2.2.1 CPO to a 2.3.0 eMSP has to translate every object that crosses it. The translations are not symmetric: going forward is almost always total, going back means deciding what to do with the fields the older version does not have. Silently dropping them — which is what a hand-written From impl does — turns a hub into a data shredder that nobody notices until an invoice is wrong.

So both directions return a Converted<T>: the object, plus a Lossy report naming every field that could not be carried, by JSON Pointer, with the reason.

use ocpi_kit::convert::{Downgrade, Upgrade};
use ocpi_kit::{v2_2_1, v2_3_0};

// 2.2.1 → 2.3.0: `incl_vat` becomes a VAT tax line.
let old = v2_2_1::Price::with_vat("5.00".parse().unwrap(), "5.50".parse().unwrap());
let new: v2_3_0::Price = old.upgrade().expect_lossless();
assert_eq!(new.taxes.len(), 1);
assert_eq!(new.after_taxes().to_string(), "5.50");

// 2.3.0 → 2.2.1: several named taxes collapse into one `incl_vat`, and that is reported.
let mut multi = v2_3_0::Price::new("5.00".parse().unwrap());
multi.taxes.push(v2_3_0::TaxAmount::new("GST", None, "0.25".parse().unwrap()).unwrap());
multi.taxes.push(v2_3_0::TaxAmount::new("QST", None, "0.50".parse().unwrap()).unwrap());
let back = multi.downgrade();
let old: v2_2_1::Price = back.value;
assert_eq!(old.incl_vat.unwrap().to_string(), "5.75");
assert!(!back.lossy.is_empty(), "the tax names did not survive");

§What the direction of a conversion means

  • Upgrade goes to a newer version. Where the newer version added a required field, the default is chosen from the older version’s semantics and documented on the impl — for example a 2.2.1 Tariff becomes a 2.3.0 one with tax_included: NO, because a 2.2.1 PriceComponent.price is “Price per unit (excl. VAT)” by definition.
  • Downgrade goes to an older version, and is where losses accumulate.

§Enum values survive both directions

Because the enums OCPI 2.3.0 opened are decoded leniently in 2.2.1 too (ocpi_lenient_enum!), a 2.3.0 ConnectorType::Mcs downgrades to a 2.2.1 ConnectorType::Custom("MCS") — same string on the wire, no data lost — and upgrades straight back. Only fields that do not exist in the older version are ever dropped.

Modules§

v2_2_1_v2_3_0
Conversions between OCPI 2.2.1 and OCPI 2.3.0.
wire
Translating a JSON document from one OCPI version to another.

Structs§

Converted
The result of a version conversion: the object, and what it cost.
Loss
One piece of information that a conversion could not carry.
Lossy
Everything a conversion could not carry, in document order.

Traits§

Downgrade
Converts an object to an older OCPI version.
Upgrade
Converts an object to a newer OCPI version.