Skip to main content

codetics_ocpp_core/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Kevin Vavelin, Codetics (https://codetics.fr)
3
4//! Version-independent building blocks shared by every OCPP-J version.
5//!
6//! Each OCPP version lives in its own crate (`ocpp16`, `ocpp201`, `ocpp21`);
7//! this crate only holds what the OCPP-J transport specifications define
8//! identically (or near-identically) for all of them.
9
10pub mod datetime;
11pub mod error;
12pub mod msgid;
13pub mod rpc;
14pub mod validate;
15pub mod version;
16
17pub use datetime::DateTime;
18pub use error::{ErrorCode, ErrorDialect, RpcError};
19pub use msgid::MessageIdGenerator;
20pub use rpc::{Frame, MessageTypeId};
21pub use validate::{Path, Validate, Violation, ViolationKind};
22pub use version::OcppVersion;
23
24/// Ties a request payload type to its action name and response type.
25///
26/// Implemented by the generated code of every version crate.
27pub trait Request: serde::Serialize + serde::de::DeserializeOwned + Validate {
28    /// Action name as sent in the CALL frame (message name without the `Request` suffix).
29    const ACTION: &'static str;
30    type Response: serde::Serialize + serde::de::DeserializeOwned + Validate;
31}
32
33/// Deserializes and validates an OCPP payload, mapping failures to the
34/// OCPP-J RPC error code that best describes them.
35pub fn decode_payload<T>(raw: &str) -> Result<T, Violation>
36where
37    T: serde::de::DeserializeOwned + Validate,
38{
39    let value: T = serde_json::from_str(raw).map_err(Violation::from_serde)?;
40    value.validate(&Path::root())?;
41    Ok(value)
42}
43
44/// Same as [`decode_payload`] but starting from an already parsed JSON value.
45pub fn decode_value<T>(value: serde_json::Value) -> Result<T, Violation>
46where
47    T: serde::de::DeserializeOwned + Validate,
48{
49    let value: T = serde_json::from_value(value).map_err(Violation::from_serde)?;
50    value.validate(&Path::root())?;
51    Ok(value)
52}
53
54/// Compiles and runs the examples of the README.
55#[cfg(doctest)]
56#[doc = include_str!("../README.md")]
57pub struct ReadmeDoctests;