1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! A toolkit for the [OCPI](https://evroaming.org/ocpi/) (Open Charge Point Interface) protocol
//! used for EV roaming between Charge Point Operators, e-Mobility Service Providers and roaming
//! hubs.
//!
//! # What is here
//!
//! | Layer | Feature | What it gives you |
//! |---|---|---|
//! | [`types`] | *(always)* | `CiString`, `DateTime`, `Number`, `Url`, `Extensions`, validation |
//! | [`v2_3_0`] | `v2_3_0` | the OCPI 2.3.0 wire model, all ten modules |
//! | [`v2_2_1`] | `v2_2_1` | the OCPI 2.2.1 wire model |
//! | [`v2_1_1`] | `v2_1_1` | the OCPI 2.1.1 wire model |
//! | [`convert`] | `convert` | `Upgrade`/`Downgrade` between versions, with loss accounting |
//! | [`transport`] | `transport` | envelope, headers, credentials tokens, pagination, routing, PATCH |
//! | [`client`] | `client` | an async client over `reqwest`, with the registration handshake |
//! | [`server`] | `server` | an `axum` router driven by one trait per module and interface |
//! | [`hub`] | `hub` | routing, broadcast push, open routing, GET All, version bridging |
//! | [`tariffs`] | `tariffs` | an auditable pricing engine over CDRs and Sessions |
//! | [`testkit`] | `testkit` | sample objects, in-memory stores and a conformant mock peer |
//!
//! # Four properties worth knowing about
//!
//! **Money is never a float.** Every `number` in every object is a [`types::Number`], an exact
//! decimal. No public field of any OCPI object in this crate is an `f32` or `f64`, and the
//! modules where money is computed deny floats by lint.
//!
//! **Nothing a peer sent is thrown away.** Undocumented JSON fields land in
//! [`types::Extensions`] and are written back verbatim; an open-enum value this crate does not
//! know keeps its text in a `Custom` variant. A hub built on `ocpi-kit` forwards a vendor
//! extension it has never seen without damaging it, which is what OCPI 2.3.0's extensibility
//! chapter asks for.
//!
//! **Parsing and conformance are separate questions.** A peer that overruns a `string(45)`
//! cannot make a whole page of Locations undecodable; the value arrives, and
//! [`types::Validate::validate`] reports it with a JSON Pointer. See [`types::validate`].
//!
//! **The peer's OCPI version is not your problem.** [`client`], [`server`] and [`hub`] speak the
//! canonical [`v2_3_0`] model and translate at the wire, so a 2.2.1 peer — most of the market —
//! reads and writes as 2.3.0 objects, and anything that cannot cross is reported rather than
//! dropped. See [`convert`].
//!
//! # Getting started
//!
// The example needs the 2.3.0 model, which is a default feature but can be switched off; the
// fence becomes `ignore` rather than the example disappearing, so the docs read the same either
// way.
//! use ocpi_kit::types::Validate;
//! use ocpi_kit::v2_3_0::locations::Location;
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let json = std::fs::read_to_string("fixtures/2.3.0/location_example.json")?;
//! let location: Location = serde_json::from_str(&json)?;
//!
//! assert_eq!(location.country_code.as_str(), "BE");
//! location.validate()?; // every length limit and cross-field rule of the spec
//! # Ok(())
//! # }
//! ```
//!
//! # Spec traceability
//!
//! Every public item carries a `Spec: <version> §<anchor>` line naming the AsciiDoc anchor in
//! the OCPI source it implements, so a reviewer — or a partner's compliance team — can go from
//! a Rust type straight to the sentence that defines it.
//!
//! # Further reading
//!
//! The [guide](https://hupe1980.github.io/ocpi-kit/docs/) covers the concepts behind these APIs —
//! the parse/validate/construct rule, open enums, extensions, version bridging — plus per-layer
//! walkthroughs, the interop quirks registry and the specification errata.
//!
//! OCPI is a protocol owned and maintained by the [EVRoaming Foundation](https://evroaming.org/).
//! This project is not affiliated with the EVRoaming Foundation.
pub use ;
/// The version of OCPI this crate treats as canonical: every other version is described as a
/// delta from it.
pub const CANONICAL_VERSION: VersionNumber = V2_3_0;