ocpp_client/ocpp_1_6/
error.rs1use crate::error::ProtocolError;
2use alloc::format;
3use alloc::string::{String, ToString};
4use core::fmt;
5use ocpp_types::v16::RpcErrorCode;
6use serde_json::{Value, json};
7
8#[derive(Debug, Clone)]
13pub struct OCPP1_6Error {
14 pub code: RpcErrorCode,
15 pub description: String,
16 pub details: Value,
17}
18
19fn wire_code(code: RpcErrorCode) -> &'static str {
24 match code {
25 RpcErrorCode::NotImplemented => "NotImplemented",
26 RpcErrorCode::NotSupported => "NotSupported",
27 RpcErrorCode::InternalError => "InternalError",
28 RpcErrorCode::ProtocolError => "ProtocolError",
29 RpcErrorCode::SecurityError => "SecurityError",
30 RpcErrorCode::FormationViolation => "FormationViolation",
31 RpcErrorCode::PropertyConstraintViolation => "PropertyConstraintViolation",
32 RpcErrorCode::OccurenceConstraintViolation => "OccurenceConstraintViolation",
33 RpcErrorCode::TypeConstraintViolation => "TypeConstraintViolation",
34 RpcErrorCode::GenericError => "GenericError",
35 }
36}
37
38impl ProtocolError for OCPP1_6Error {
39 fn code(&self) -> &str {
40 wire_code(self.code)
41 }
42
43 fn description(&self) -> &str {
44 &self.description
45 }
46
47 fn details(&self) -> &Value {
48 &self.details
49 }
50
51 fn not_implemented(action: &str) -> Self {
52 OCPP1_6Error {
53 code: RpcErrorCode::NotImplemented,
54 description: format!("Action '{action}' is not implemented"),
55 details: json!({}),
56 }
57 }
58
59 fn from_wire(code: &str, description: &str, details: Value) -> Self {
60 let code = match code {
61 "NotImplemented" => RpcErrorCode::NotImplemented,
62 "NotSupported" => RpcErrorCode::NotSupported,
63 "InternalError" => RpcErrorCode::InternalError,
64 "ProtocolError" => RpcErrorCode::ProtocolError,
65 "SecurityError" => RpcErrorCode::SecurityError,
66 "FormationViolation" => RpcErrorCode::FormationViolation,
67 "PropertyConstraintViolation" => RpcErrorCode::PropertyConstraintViolation,
68 "OccurenceConstraintViolation" => RpcErrorCode::OccurenceConstraintViolation,
69 "TypeConstraintViolation" => RpcErrorCode::TypeConstraintViolation,
70 _ => RpcErrorCode::GenericError,
71 };
72 OCPP1_6Error {
73 code,
74 description: description.to_string(),
75 details,
76 }
77 }
78}
79
80#[cfg(feature = "validate")]
87impl From<ocpp_types::validate::ValidationError> for OCPP1_6Error {
88 fn from(error: ocpp_types::validate::ValidationError) -> Self {
89 use ocpp_types::validate::ConstraintClass;
90
91 let code = match error.kind().constraint_class() {
92 ConstraintClass::Property => RpcErrorCode::PropertyConstraintViolation,
93 ConstraintClass::Occurrence => RpcErrorCode::OccurenceConstraintViolation,
94 };
95 let (description, details) = crate::error::validation_error_parts(&error);
96 OCPP1_6Error {
97 code,
98 description,
99 details,
100 }
101 }
102}
103
104impl fmt::Display for OCPP1_6Error {
105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 write!(f, "{}: {}", self.code(), self.description())
107 }
108}
109
110impl core::error::Error for OCPP1_6Error {}