ocpp_client/ocpp_2_0_1/
error.rs1use crate::error::ProtocolError;
2use alloc::format;
3use alloc::string::{String, ToString};
4use core::fmt;
5use ocpp_types::v201::RpcErrorCode;
6use serde_json::{Value, json};
7
8#[derive(Debug, Clone)]
13pub struct OCPP2_0_1Error {
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::FormatViolation => "FormatViolation",
26 RpcErrorCode::GenericError => "GenericError",
27 RpcErrorCode::InternalError => "InternalError",
28 RpcErrorCode::MessageTypeNotSupported => "MessageTypeNotSupported",
29 RpcErrorCode::NotImplemented => "NotImplemented",
30 RpcErrorCode::NotSupported => "NotSupported",
31 RpcErrorCode::OccurrenceConstraintViolation => "OccurrenceConstraintViolation",
32 RpcErrorCode::PropertyConstraintViolation => "PropertyConstraintViolation",
33 RpcErrorCode::ProtocolError => "ProtocolError",
34 RpcErrorCode::RpcFrameworkError => "RpcFrameworkError",
35 RpcErrorCode::SecurityError => "SecurityError",
36 RpcErrorCode::TypeConstraintViolation => "TypeConstraintViolation",
37 }
38}
39
40impl ProtocolError for OCPP2_0_1Error {
41 fn code(&self) -> &str {
42 wire_code(self.code)
43 }
44
45 fn description(&self) -> &str {
46 &self.description
47 }
48
49 fn details(&self) -> &Value {
50 &self.details
51 }
52
53 fn not_implemented(action: &str) -> Self {
54 OCPP2_0_1Error {
55 code: RpcErrorCode::NotImplemented,
56 description: format!("Action '{action}' is not implemented"),
57 details: json!({}),
58 }
59 }
60
61 fn from_wire(code: &str, description: &str, details: Value) -> Self {
62 let code = match code {
63 "FormatViolation" => RpcErrorCode::FormatViolation,
64 "InternalError" => RpcErrorCode::InternalError,
65 "MessageTypeNotSupported" => RpcErrorCode::MessageTypeNotSupported,
66 "NotImplemented" => RpcErrorCode::NotImplemented,
67 "NotSupported" => RpcErrorCode::NotSupported,
68 "OccurrenceConstraintViolation" => RpcErrorCode::OccurrenceConstraintViolation,
69 "PropertyConstraintViolation" => RpcErrorCode::PropertyConstraintViolation,
70 "ProtocolError" => RpcErrorCode::ProtocolError,
71 "RpcFrameworkError" => RpcErrorCode::RpcFrameworkError,
72 "SecurityError" => RpcErrorCode::SecurityError,
73 "TypeConstraintViolation" => RpcErrorCode::TypeConstraintViolation,
74 _ => RpcErrorCode::GenericError,
75 };
76 OCPP2_0_1Error {
77 code,
78 description: description.to_string(),
79 details,
80 }
81 }
82}
83
84#[cfg(feature = "validate")]
87impl From<ocpp_types::validate::ValidationError> for OCPP2_0_1Error {
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::OccurrenceConstraintViolation,
94 };
95 let (description, details) = crate::error::validation_error_parts(&error);
96 OCPP2_0_1Error {
97 code,
98 description,
99 details,
100 }
101 }
102}
103
104impl fmt::Display for OCPP2_0_1Error {
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 OCPP2_0_1Error {}