1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub enum RpcErrorCode {
14 NotImplemented,
16 NotSupported,
18 InternalError,
21 ProtocolError,
23 SecurityError,
26 FormationViolation,
29 PropertyConstraintViolation,
32 OccurenceConstraintViolation,
35 TypeConstraintViolation,
38 GenericError,
40}
41
42impl RpcErrorCode {
43 pub const fn description(&self) -> &'static str {
46 match self {
47 Self::NotImplemented => "Requested Action is not known by receiver",
48 Self::NotSupported => {
49 "Requested Action is recognized but not supported by the receiver"
50 }
51 Self::InternalError => {
52 "An internal error occurred and the receiver was not able to process the requested Action successfully"
53 }
54 Self::ProtocolError => "Payload for Action is incomplete",
55 Self::SecurityError => {
56 "During the processing of Action a security issue occurred preventing receiver from completing the Action successfully"
57 }
58 Self::FormationViolation => {
59 "Payload for Action is syntactically incorrect or not conform the PDU structure for Action"
60 }
61 Self::PropertyConstraintViolation => {
62 "Payload is syntactically correct but at least one field contains an invalid value"
63 }
64 Self::OccurenceConstraintViolation => {
65 "Payload for Action is syntactically correct but at least one of the fields violates occurence constraints"
66 }
67 Self::TypeConstraintViolation => {
68 "Payload for Action is syntactically correct but at least one of the fields violates data type constraints (e.g. \"somestring\": 12)"
69 }
70 Self::GenericError => "Any other error not covered by the previous ones",
71 }
72 }
73}
74
75impl core::fmt::Display for RpcErrorCode {
76 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
77 f.write_str(self.description())
78 }
79}
80
81impl core::error::Error for RpcErrorCode {}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn has_exactly_the_ten_codes_defined_by_the_ocpp_1_6j_spec() {
89 let all = [
90 RpcErrorCode::NotImplemented,
91 RpcErrorCode::NotSupported,
92 RpcErrorCode::InternalError,
93 RpcErrorCode::ProtocolError,
94 RpcErrorCode::SecurityError,
95 RpcErrorCode::FormationViolation,
96 RpcErrorCode::PropertyConstraintViolation,
97 RpcErrorCode::OccurenceConstraintViolation,
98 RpcErrorCode::TypeConstraintViolation,
99 RpcErrorCode::GenericError,
100 ];
101
102 assert_eq!(all.len(), 10);
103 }
104
105 #[test]
106 fn display_shows_the_spec_description() {
107 use core::fmt::Write;
108 let mut buf = heapless::String::<128>::new();
109 write!(buf, "{}", RpcErrorCode::NotImplemented).unwrap();
110
111 assert_eq!(buf.as_str(), "Requested Action is not known by receiver");
112 }
113
114 #[test]
115 fn implements_the_core_error_trait() {
116 fn assert_error<T: core::error::Error>() {}
117 assert_error::<RpcErrorCode>();
118 }
119
120 #[cfg(feature = "serde")]
121 #[test]
122 fn serializes_using_the_exact_wire_spelling() {
123 let mut buf = [0u8; 64];
124 let json = serde_json_core::to_slice(&RpcErrorCode::OccurenceConstraintViolation, &mut buf)
125 .unwrap();
126
127 assert_eq!(&buf[..json], br#""OccurenceConstraintViolation""#);
128 }
129}