codetics-ocpp-core 0.1.0

Codetics OCPP: version-independent OCPP-J building blocks (RPC framing, error codes, RFC 3339 date-time, validation, subprotocol negotiation, message ids)
Documentation
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 Kevin Vavelin, Codetics (https://codetics.fr)

//! Version-independent building blocks shared by every OCPP-J version.
//!
//! Each OCPP version lives in its own crate (`ocpp16`, `ocpp201`, `ocpp21`);
//! this crate only holds what the OCPP-J transport specifications define
//! identically (or near-identically) for all of them.

pub mod datetime;
pub mod error;
pub mod msgid;
pub mod rpc;
pub mod validate;
pub mod version;

pub use datetime::DateTime;
pub use error::{ErrorCode, ErrorDialect, RpcError};
pub use msgid::MessageIdGenerator;
pub use rpc::{Frame, MessageTypeId};
pub use validate::{Path, Validate, Violation, ViolationKind};
pub use version::OcppVersion;

/// Ties a request payload type to its action name and response type.
///
/// Implemented by the generated code of every version crate.
pub trait Request: serde::Serialize + serde::de::DeserializeOwned + Validate {
    /// Action name as sent in the CALL frame (message name without the `Request` suffix).
    const ACTION: &'static str;
    type Response: serde::Serialize + serde::de::DeserializeOwned + Validate;
}

/// Deserializes and validates an OCPP payload, mapping failures to the
/// OCPP-J RPC error code that best describes them.
pub fn decode_payload<T>(raw: &str) -> Result<T, Violation>
where
    T: serde::de::DeserializeOwned + Validate,
{
    let value: T = serde_json::from_str(raw).map_err(Violation::from_serde)?;
    value.validate(&Path::root())?;
    Ok(value)
}

/// Same as [`decode_payload`] but starting from an already parsed JSON value.
pub fn decode_value<T>(value: serde_json::Value) -> Result<T, Violation>
where
    T: serde::de::DeserializeOwned + Validate,
{
    let value: T = serde_json::from_value(value).map_err(Violation::from_serde)?;
    value.validate(&Path::root())?;
    Ok(value)
}

/// Compiles and runs the examples of the README.
#[cfg(doctest)]
#[doc = include_str!("../README.md")]
pub struct ReadmeDoctests;