1#![allow(clippy::large_enum_variant)]
8
9use ocpp_core::validate::Violation;
10
11use crate::messages::*;
12
13impl ocpp_core::Request for AuthorizeRequest {
14 const ACTION: &'static str = "Authorize";
15 type Response = AuthorizeResponse;
16}
17
18impl ocpp_core::Request for BootNotificationRequest {
19 const ACTION: &'static str = "BootNotification";
20 type Response = BootNotificationResponse;
21}
22
23impl ocpp_core::Request for CancelReservationRequest {
24 const ACTION: &'static str = "CancelReservation";
25 type Response = CancelReservationResponse;
26}
27
28impl ocpp_core::Request for ChangeAvailabilityRequest {
29 const ACTION: &'static str = "ChangeAvailability";
30 type Response = ChangeAvailabilityResponse;
31}
32
33impl ocpp_core::Request for ChangeConfigurationRequest {
34 const ACTION: &'static str = "ChangeConfiguration";
35 type Response = ChangeConfigurationResponse;
36}
37
38impl ocpp_core::Request for ClearCacheRequest {
39 const ACTION: &'static str = "ClearCache";
40 type Response = ClearCacheResponse;
41}
42
43impl ocpp_core::Request for ClearChargingProfileRequest {
44 const ACTION: &'static str = "ClearChargingProfile";
45 type Response = ClearChargingProfileResponse;
46}
47
48impl ocpp_core::Request for DataTransferRequest {
49 const ACTION: &'static str = "DataTransfer";
50 type Response = DataTransferResponse;
51}
52
53impl ocpp_core::Request for DiagnosticsStatusNotificationRequest {
54 const ACTION: &'static str = "DiagnosticsStatusNotification";
55 type Response = DiagnosticsStatusNotificationResponse;
56}
57
58impl ocpp_core::Request for FirmwareStatusNotificationRequest {
59 const ACTION: &'static str = "FirmwareStatusNotification";
60 type Response = FirmwareStatusNotificationResponse;
61}
62
63impl ocpp_core::Request for GetCompositeScheduleRequest {
64 const ACTION: &'static str = "GetCompositeSchedule";
65 type Response = GetCompositeScheduleResponse;
66}
67
68impl ocpp_core::Request for GetConfigurationRequest {
69 const ACTION: &'static str = "GetConfiguration";
70 type Response = GetConfigurationResponse;
71}
72
73impl ocpp_core::Request for GetDiagnosticsRequest {
74 const ACTION: &'static str = "GetDiagnostics";
75 type Response = GetDiagnosticsResponse;
76}
77
78impl ocpp_core::Request for GetLocalListVersionRequest {
79 const ACTION: &'static str = "GetLocalListVersion";
80 type Response = GetLocalListVersionResponse;
81}
82
83impl ocpp_core::Request for HeartbeatRequest {
84 const ACTION: &'static str = "Heartbeat";
85 type Response = HeartbeatResponse;
86}
87
88impl ocpp_core::Request for MeterValuesRequest {
89 const ACTION: &'static str = "MeterValues";
90 type Response = MeterValuesResponse;
91}
92
93impl ocpp_core::Request for RemoteStartTransactionRequest {
94 const ACTION: &'static str = "RemoteStartTransaction";
95 type Response = RemoteStartTransactionResponse;
96}
97
98impl ocpp_core::Request for RemoteStopTransactionRequest {
99 const ACTION: &'static str = "RemoteStopTransaction";
100 type Response = RemoteStopTransactionResponse;
101}
102
103impl ocpp_core::Request for ReserveNowRequest {
104 const ACTION: &'static str = "ReserveNow";
105 type Response = ReserveNowResponse;
106}
107
108impl ocpp_core::Request for ResetRequest {
109 const ACTION: &'static str = "Reset";
110 type Response = ResetResponse;
111}
112
113impl ocpp_core::Request for SendLocalListRequest {
114 const ACTION: &'static str = "SendLocalList";
115 type Response = SendLocalListResponse;
116}
117
118impl ocpp_core::Request for SetChargingProfileRequest {
119 const ACTION: &'static str = "SetChargingProfile";
120 type Response = SetChargingProfileResponse;
121}
122
123impl ocpp_core::Request for StartTransactionRequest {
124 const ACTION: &'static str = "StartTransaction";
125 type Response = StartTransactionResponse;
126}
127
128impl ocpp_core::Request for StatusNotificationRequest {
129 const ACTION: &'static str = "StatusNotification";
130 type Response = StatusNotificationResponse;
131}
132
133impl ocpp_core::Request for StopTransactionRequest {
134 const ACTION: &'static str = "StopTransaction";
135 type Response = StopTransactionResponse;
136}
137
138impl ocpp_core::Request for TriggerMessageRequest {
139 const ACTION: &'static str = "TriggerMessage";
140 type Response = TriggerMessageResponse;
141}
142
143impl ocpp_core::Request for UnlockConnectorRequest {
144 const ACTION: &'static str = "UnlockConnector";
145 type Response = UnlockConnectorResponse;
146}
147
148impl ocpp_core::Request for UpdateFirmwareRequest {
149 const ACTION: &'static str = "UpdateFirmware";
150 type Response = UpdateFirmwareResponse;
151}
152
153#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
155pub enum Direction {
156 StationToCsms,
158 CsmsToStation,
160 Both,
162}
163
164#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
166pub enum Action {
167 Authorize,
168 BootNotification,
169 CancelReservation,
170 ChangeAvailability,
171 ChangeConfiguration,
172 ClearCache,
173 ClearChargingProfile,
174 DataTransfer,
175 DiagnosticsStatusNotification,
176 FirmwareStatusNotification,
177 GetCompositeSchedule,
178 GetConfiguration,
179 GetDiagnostics,
180 GetLocalListVersion,
181 Heartbeat,
182 MeterValues,
183 RemoteStartTransaction,
184 RemoteStopTransaction,
185 ReserveNow,
186 Reset,
187 SendLocalList,
188 SetChargingProfile,
189 StartTransaction,
190 StatusNotification,
191 StopTransaction,
192 TriggerMessage,
193 UnlockConnector,
194 UpdateFirmware,
195}
196
197impl Action {
198 pub const ALL: &'static [Action] = &[
199 Action::Authorize,
200 Action::BootNotification,
201 Action::CancelReservation,
202 Action::ChangeAvailability,
203 Action::ChangeConfiguration,
204 Action::ClearCache,
205 Action::ClearChargingProfile,
206 Action::DataTransfer,
207 Action::DiagnosticsStatusNotification,
208 Action::FirmwareStatusNotification,
209 Action::GetCompositeSchedule,
210 Action::GetConfiguration,
211 Action::GetDiagnostics,
212 Action::GetLocalListVersion,
213 Action::Heartbeat,
214 Action::MeterValues,
215 Action::RemoteStartTransaction,
216 Action::RemoteStopTransaction,
217 Action::ReserveNow,
218 Action::Reset,
219 Action::SendLocalList,
220 Action::SetChargingProfile,
221 Action::StartTransaction,
222 Action::StatusNotification,
223 Action::StopTransaction,
224 Action::TriggerMessage,
225 Action::UnlockConnector,
226 Action::UpdateFirmware,
227 ];
228
229 pub const fn as_str(&self) -> &'static str {
230 match self {
231 Action::Authorize => "Authorize",
232 Action::BootNotification => "BootNotification",
233 Action::CancelReservation => "CancelReservation",
234 Action::ChangeAvailability => "ChangeAvailability",
235 Action::ChangeConfiguration => "ChangeConfiguration",
236 Action::ClearCache => "ClearCache",
237 Action::ClearChargingProfile => "ClearChargingProfile",
238 Action::DataTransfer => "DataTransfer",
239 Action::DiagnosticsStatusNotification => "DiagnosticsStatusNotification",
240 Action::FirmwareStatusNotification => "FirmwareStatusNotification",
241 Action::GetCompositeSchedule => "GetCompositeSchedule",
242 Action::GetConfiguration => "GetConfiguration",
243 Action::GetDiagnostics => "GetDiagnostics",
244 Action::GetLocalListVersion => "GetLocalListVersion",
245 Action::Heartbeat => "Heartbeat",
246 Action::MeterValues => "MeterValues",
247 Action::RemoteStartTransaction => "RemoteStartTransaction",
248 Action::RemoteStopTransaction => "RemoteStopTransaction",
249 Action::ReserveNow => "ReserveNow",
250 Action::Reset => "Reset",
251 Action::SendLocalList => "SendLocalList",
252 Action::SetChargingProfile => "SetChargingProfile",
253 Action::StartTransaction => "StartTransaction",
254 Action::StatusNotification => "StatusNotification",
255 Action::StopTransaction => "StopTransaction",
256 Action::TriggerMessage => "TriggerMessage",
257 Action::UnlockConnector => "UnlockConnector",
258 Action::UpdateFirmware => "UpdateFirmware",
259 }
260 }
261
262 pub fn from_name(s: &str) -> Option<Action> {
263 match s {
264 "Authorize" => Some(Action::Authorize),
265 "BootNotification" => Some(Action::BootNotification),
266 "CancelReservation" => Some(Action::CancelReservation),
267 "ChangeAvailability" => Some(Action::ChangeAvailability),
268 "ChangeConfiguration" => Some(Action::ChangeConfiguration),
269 "ClearCache" => Some(Action::ClearCache),
270 "ClearChargingProfile" => Some(Action::ClearChargingProfile),
271 "DataTransfer" => Some(Action::DataTransfer),
272 "DiagnosticsStatusNotification" => Some(Action::DiagnosticsStatusNotification),
273 "FirmwareStatusNotification" => Some(Action::FirmwareStatusNotification),
274 "GetCompositeSchedule" => Some(Action::GetCompositeSchedule),
275 "GetConfiguration" => Some(Action::GetConfiguration),
276 "GetDiagnostics" => Some(Action::GetDiagnostics),
277 "GetLocalListVersion" => Some(Action::GetLocalListVersion),
278 "Heartbeat" => Some(Action::Heartbeat),
279 "MeterValues" => Some(Action::MeterValues),
280 "RemoteStartTransaction" => Some(Action::RemoteStartTransaction),
281 "RemoteStopTransaction" => Some(Action::RemoteStopTransaction),
282 "ReserveNow" => Some(Action::ReserveNow),
283 "Reset" => Some(Action::Reset),
284 "SendLocalList" => Some(Action::SendLocalList),
285 "SetChargingProfile" => Some(Action::SetChargingProfile),
286 "StartTransaction" => Some(Action::StartTransaction),
287 "StatusNotification" => Some(Action::StatusNotification),
288 "StopTransaction" => Some(Action::StopTransaction),
289 "TriggerMessage" => Some(Action::TriggerMessage),
290 "UnlockConnector" => Some(Action::UnlockConnector),
291 "UpdateFirmware" => Some(Action::UpdateFirmware),
292 _ => None,
293 }
294 }
295
296 pub const fn direction(&self) -> Direction {
297 match self {
298 Action::Authorize => Direction::StationToCsms,
299 Action::BootNotification => Direction::StationToCsms,
300 Action::CancelReservation => Direction::CsmsToStation,
301 Action::ChangeAvailability => Direction::CsmsToStation,
302 Action::ChangeConfiguration => Direction::CsmsToStation,
303 Action::ClearCache => Direction::CsmsToStation,
304 Action::ClearChargingProfile => Direction::CsmsToStation,
305 Action::DataTransfer => Direction::Both,
306 Action::DiagnosticsStatusNotification => Direction::StationToCsms,
307 Action::FirmwareStatusNotification => Direction::StationToCsms,
308 Action::GetCompositeSchedule => Direction::CsmsToStation,
309 Action::GetConfiguration => Direction::CsmsToStation,
310 Action::GetDiagnostics => Direction::CsmsToStation,
311 Action::GetLocalListVersion => Direction::CsmsToStation,
312 Action::Heartbeat => Direction::StationToCsms,
313 Action::MeterValues => Direction::StationToCsms,
314 Action::RemoteStartTransaction => Direction::CsmsToStation,
315 Action::RemoteStopTransaction => Direction::CsmsToStation,
316 Action::ReserveNow => Direction::CsmsToStation,
317 Action::Reset => Direction::CsmsToStation,
318 Action::SendLocalList => Direction::CsmsToStation,
319 Action::SetChargingProfile => Direction::CsmsToStation,
320 Action::StartTransaction => Direction::StationToCsms,
321 Action::StatusNotification => Direction::StationToCsms,
322 Action::StopTransaction => Direction::StationToCsms,
323 Action::TriggerMessage => Direction::CsmsToStation,
324 Action::UnlockConnector => Direction::CsmsToStation,
325 Action::UpdateFirmware => Direction::CsmsToStation,
326 }
327 }
328
329 pub const fn is_send(&self) -> bool {
331 false
332 }
333}
334
335impl std::fmt::Display for Action {
336 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
337 f.write_str(self.as_str())
338 }
339}
340
341#[derive(Debug, Clone, PartialEq)]
343pub enum DecodeError {
344 UnknownAction(String),
346 WrongDirection(Action),
348 Invalid(Violation),
350}
351
352impl std::fmt::Display for DecodeError {
353 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
354 match self {
355 DecodeError::UnknownAction(a) => write!(f, "unknown action '{a}'"),
356 DecodeError::WrongDirection(a) => {
357 write!(f, "action '{a}' is not accepted in this direction")
358 }
359 DecodeError::Invalid(v) => write!(f, "{v}"),
360 }
361 }
362}
363
364impl std::error::Error for DecodeError {}
365
366#[derive(Debug, Clone, PartialEq)]
368pub enum StationCall {
369 Authorize(AuthorizeRequest),
370 BootNotification(BootNotificationRequest),
371 DataTransfer(DataTransferRequest),
372 DiagnosticsStatusNotification(DiagnosticsStatusNotificationRequest),
373 FirmwareStatusNotification(FirmwareStatusNotificationRequest),
374 Heartbeat(HeartbeatRequest),
375 MeterValues(MeterValuesRequest),
376 StartTransaction(StartTransactionRequest),
377 StatusNotification(StatusNotificationRequest),
378 StopTransaction(StopTransactionRequest),
379}
380
381impl StationCall {
382 pub const fn action(&self) -> Action {
383 match self {
384 StationCall::Authorize(_) => Action::Authorize,
385 StationCall::BootNotification(_) => Action::BootNotification,
386 StationCall::DataTransfer(_) => Action::DataTransfer,
387 StationCall::DiagnosticsStatusNotification(_) => Action::DiagnosticsStatusNotification,
388 StationCall::FirmwareStatusNotification(_) => Action::FirmwareStatusNotification,
389 StationCall::Heartbeat(_) => Action::Heartbeat,
390 StationCall::MeterValues(_) => Action::MeterValues,
391 StationCall::StartTransaction(_) => Action::StartTransaction,
392 StationCall::StatusNotification(_) => Action::StatusNotification,
393 StationCall::StopTransaction(_) => Action::StopTransaction,
394 }
395 }
396
397 pub fn decode(action: &str, payload: &str) -> Result<Self, DecodeError> {
399 let a = Action::from_name(action)
400 .ok_or_else(|| DecodeError::UnknownAction(action.to_owned()))?;
401 match a {
402 Action::Authorize => ocpp_core::decode_payload(payload)
403 .map(StationCall::Authorize)
404 .map_err(DecodeError::Invalid),
405 Action::BootNotification => ocpp_core::decode_payload(payload)
406 .map(StationCall::BootNotification)
407 .map_err(DecodeError::Invalid),
408 Action::DataTransfer => ocpp_core::decode_payload(payload)
409 .map(StationCall::DataTransfer)
410 .map_err(DecodeError::Invalid),
411 Action::DiagnosticsStatusNotification => ocpp_core::decode_payload(payload)
412 .map(StationCall::DiagnosticsStatusNotification)
413 .map_err(DecodeError::Invalid),
414 Action::FirmwareStatusNotification => ocpp_core::decode_payload(payload)
415 .map(StationCall::FirmwareStatusNotification)
416 .map_err(DecodeError::Invalid),
417 Action::Heartbeat => ocpp_core::decode_payload(payload)
418 .map(StationCall::Heartbeat)
419 .map_err(DecodeError::Invalid),
420 Action::MeterValues => ocpp_core::decode_payload(payload)
421 .map(StationCall::MeterValues)
422 .map_err(DecodeError::Invalid),
423 Action::StartTransaction => ocpp_core::decode_payload(payload)
424 .map(StationCall::StartTransaction)
425 .map_err(DecodeError::Invalid),
426 Action::StatusNotification => ocpp_core::decode_payload(payload)
427 .map(StationCall::StatusNotification)
428 .map_err(DecodeError::Invalid),
429 Action::StopTransaction => ocpp_core::decode_payload(payload)
430 .map(StationCall::StopTransaction)
431 .map_err(DecodeError::Invalid),
432 #[allow(unreachable_patterns)]
433 other => Err(DecodeError::WrongDirection(other)),
434 }
435 }
436
437 pub fn from_value(action: &str, payload: serde_json::Value) -> Result<Self, DecodeError> {
439 let a = Action::from_name(action)
440 .ok_or_else(|| DecodeError::UnknownAction(action.to_owned()))?;
441 match a {
442 Action::Authorize => ocpp_core::decode_value(payload)
443 .map(StationCall::Authorize)
444 .map_err(DecodeError::Invalid),
445 Action::BootNotification => ocpp_core::decode_value(payload)
446 .map(StationCall::BootNotification)
447 .map_err(DecodeError::Invalid),
448 Action::DataTransfer => ocpp_core::decode_value(payload)
449 .map(StationCall::DataTransfer)
450 .map_err(DecodeError::Invalid),
451 Action::DiagnosticsStatusNotification => ocpp_core::decode_value(payload)
452 .map(StationCall::DiagnosticsStatusNotification)
453 .map_err(DecodeError::Invalid),
454 Action::FirmwareStatusNotification => ocpp_core::decode_value(payload)
455 .map(StationCall::FirmwareStatusNotification)
456 .map_err(DecodeError::Invalid),
457 Action::Heartbeat => ocpp_core::decode_value(payload)
458 .map(StationCall::Heartbeat)
459 .map_err(DecodeError::Invalid),
460 Action::MeterValues => ocpp_core::decode_value(payload)
461 .map(StationCall::MeterValues)
462 .map_err(DecodeError::Invalid),
463 Action::StartTransaction => ocpp_core::decode_value(payload)
464 .map(StationCall::StartTransaction)
465 .map_err(DecodeError::Invalid),
466 Action::StatusNotification => ocpp_core::decode_value(payload)
467 .map(StationCall::StatusNotification)
468 .map_err(DecodeError::Invalid),
469 Action::StopTransaction => ocpp_core::decode_value(payload)
470 .map(StationCall::StopTransaction)
471 .map_err(DecodeError::Invalid),
472 #[allow(unreachable_patterns)]
473 other => Err(DecodeError::WrongDirection(other)),
474 }
475 }
476
477 pub fn to_payload(&self) -> serde_json::Value {
479 match self {
480 StationCall::Authorize(r) => serde_json::to_value(r).expect("serializable"),
481 StationCall::BootNotification(r) => serde_json::to_value(r).expect("serializable"),
482 StationCall::DataTransfer(r) => serde_json::to_value(r).expect("serializable"),
483 StationCall::DiagnosticsStatusNotification(r) => {
484 serde_json::to_value(r).expect("serializable")
485 }
486 StationCall::FirmwareStatusNotification(r) => {
487 serde_json::to_value(r).expect("serializable")
488 }
489 StationCall::Heartbeat(r) => serde_json::to_value(r).expect("serializable"),
490 StationCall::MeterValues(r) => serde_json::to_value(r).expect("serializable"),
491 StationCall::StartTransaction(r) => serde_json::to_value(r).expect("serializable"),
492 StationCall::StatusNotification(r) => serde_json::to_value(r).expect("serializable"),
493 StationCall::StopTransaction(r) => serde_json::to_value(r).expect("serializable"),
494 }
495 }
496}
497
498#[derive(Debug, Clone, PartialEq)]
500pub enum CsmsCall {
501 CancelReservation(CancelReservationRequest),
502 ChangeAvailability(ChangeAvailabilityRequest),
503 ChangeConfiguration(ChangeConfigurationRequest),
504 ClearCache(ClearCacheRequest),
505 ClearChargingProfile(ClearChargingProfileRequest),
506 DataTransfer(DataTransferRequest),
507 GetCompositeSchedule(GetCompositeScheduleRequest),
508 GetConfiguration(GetConfigurationRequest),
509 GetDiagnostics(GetDiagnosticsRequest),
510 GetLocalListVersion(GetLocalListVersionRequest),
511 RemoteStartTransaction(RemoteStartTransactionRequest),
512 RemoteStopTransaction(RemoteStopTransactionRequest),
513 ReserveNow(ReserveNowRequest),
514 Reset(ResetRequest),
515 SendLocalList(SendLocalListRequest),
516 SetChargingProfile(SetChargingProfileRequest),
517 TriggerMessage(TriggerMessageRequest),
518 UnlockConnector(UnlockConnectorRequest),
519 UpdateFirmware(UpdateFirmwareRequest),
520}
521
522impl CsmsCall {
523 pub const fn action(&self) -> Action {
524 match self {
525 CsmsCall::CancelReservation(_) => Action::CancelReservation,
526 CsmsCall::ChangeAvailability(_) => Action::ChangeAvailability,
527 CsmsCall::ChangeConfiguration(_) => Action::ChangeConfiguration,
528 CsmsCall::ClearCache(_) => Action::ClearCache,
529 CsmsCall::ClearChargingProfile(_) => Action::ClearChargingProfile,
530 CsmsCall::DataTransfer(_) => Action::DataTransfer,
531 CsmsCall::GetCompositeSchedule(_) => Action::GetCompositeSchedule,
532 CsmsCall::GetConfiguration(_) => Action::GetConfiguration,
533 CsmsCall::GetDiagnostics(_) => Action::GetDiagnostics,
534 CsmsCall::GetLocalListVersion(_) => Action::GetLocalListVersion,
535 CsmsCall::RemoteStartTransaction(_) => Action::RemoteStartTransaction,
536 CsmsCall::RemoteStopTransaction(_) => Action::RemoteStopTransaction,
537 CsmsCall::ReserveNow(_) => Action::ReserveNow,
538 CsmsCall::Reset(_) => Action::Reset,
539 CsmsCall::SendLocalList(_) => Action::SendLocalList,
540 CsmsCall::SetChargingProfile(_) => Action::SetChargingProfile,
541 CsmsCall::TriggerMessage(_) => Action::TriggerMessage,
542 CsmsCall::UnlockConnector(_) => Action::UnlockConnector,
543 CsmsCall::UpdateFirmware(_) => Action::UpdateFirmware,
544 }
545 }
546
547 pub fn decode(action: &str, payload: &str) -> Result<Self, DecodeError> {
549 let a = Action::from_name(action)
550 .ok_or_else(|| DecodeError::UnknownAction(action.to_owned()))?;
551 match a {
552 Action::CancelReservation => ocpp_core::decode_payload(payload)
553 .map(CsmsCall::CancelReservation)
554 .map_err(DecodeError::Invalid),
555 Action::ChangeAvailability => ocpp_core::decode_payload(payload)
556 .map(CsmsCall::ChangeAvailability)
557 .map_err(DecodeError::Invalid),
558 Action::ChangeConfiguration => ocpp_core::decode_payload(payload)
559 .map(CsmsCall::ChangeConfiguration)
560 .map_err(DecodeError::Invalid),
561 Action::ClearCache => ocpp_core::decode_payload(payload)
562 .map(CsmsCall::ClearCache)
563 .map_err(DecodeError::Invalid),
564 Action::ClearChargingProfile => ocpp_core::decode_payload(payload)
565 .map(CsmsCall::ClearChargingProfile)
566 .map_err(DecodeError::Invalid),
567 Action::DataTransfer => ocpp_core::decode_payload(payload)
568 .map(CsmsCall::DataTransfer)
569 .map_err(DecodeError::Invalid),
570 Action::GetCompositeSchedule => ocpp_core::decode_payload(payload)
571 .map(CsmsCall::GetCompositeSchedule)
572 .map_err(DecodeError::Invalid),
573 Action::GetConfiguration => ocpp_core::decode_payload(payload)
574 .map(CsmsCall::GetConfiguration)
575 .map_err(DecodeError::Invalid),
576 Action::GetDiagnostics => ocpp_core::decode_payload(payload)
577 .map(CsmsCall::GetDiagnostics)
578 .map_err(DecodeError::Invalid),
579 Action::GetLocalListVersion => ocpp_core::decode_payload(payload)
580 .map(CsmsCall::GetLocalListVersion)
581 .map_err(DecodeError::Invalid),
582 Action::RemoteStartTransaction => ocpp_core::decode_payload(payload)
583 .map(CsmsCall::RemoteStartTransaction)
584 .map_err(DecodeError::Invalid),
585 Action::RemoteStopTransaction => ocpp_core::decode_payload(payload)
586 .map(CsmsCall::RemoteStopTransaction)
587 .map_err(DecodeError::Invalid),
588 Action::ReserveNow => ocpp_core::decode_payload(payload)
589 .map(CsmsCall::ReserveNow)
590 .map_err(DecodeError::Invalid),
591 Action::Reset => ocpp_core::decode_payload(payload)
592 .map(CsmsCall::Reset)
593 .map_err(DecodeError::Invalid),
594 Action::SendLocalList => ocpp_core::decode_payload(payload)
595 .map(CsmsCall::SendLocalList)
596 .map_err(DecodeError::Invalid),
597 Action::SetChargingProfile => ocpp_core::decode_payload(payload)
598 .map(CsmsCall::SetChargingProfile)
599 .map_err(DecodeError::Invalid),
600 Action::TriggerMessage => ocpp_core::decode_payload(payload)
601 .map(CsmsCall::TriggerMessage)
602 .map_err(DecodeError::Invalid),
603 Action::UnlockConnector => ocpp_core::decode_payload(payload)
604 .map(CsmsCall::UnlockConnector)
605 .map_err(DecodeError::Invalid),
606 Action::UpdateFirmware => ocpp_core::decode_payload(payload)
607 .map(CsmsCall::UpdateFirmware)
608 .map_err(DecodeError::Invalid),
609 #[allow(unreachable_patterns)]
610 other => Err(DecodeError::WrongDirection(other)),
611 }
612 }
613
614 pub fn from_value(action: &str, payload: serde_json::Value) -> Result<Self, DecodeError> {
616 let a = Action::from_name(action)
617 .ok_or_else(|| DecodeError::UnknownAction(action.to_owned()))?;
618 match a {
619 Action::CancelReservation => ocpp_core::decode_value(payload)
620 .map(CsmsCall::CancelReservation)
621 .map_err(DecodeError::Invalid),
622 Action::ChangeAvailability => ocpp_core::decode_value(payload)
623 .map(CsmsCall::ChangeAvailability)
624 .map_err(DecodeError::Invalid),
625 Action::ChangeConfiguration => ocpp_core::decode_value(payload)
626 .map(CsmsCall::ChangeConfiguration)
627 .map_err(DecodeError::Invalid),
628 Action::ClearCache => ocpp_core::decode_value(payload)
629 .map(CsmsCall::ClearCache)
630 .map_err(DecodeError::Invalid),
631 Action::ClearChargingProfile => ocpp_core::decode_value(payload)
632 .map(CsmsCall::ClearChargingProfile)
633 .map_err(DecodeError::Invalid),
634 Action::DataTransfer => ocpp_core::decode_value(payload)
635 .map(CsmsCall::DataTransfer)
636 .map_err(DecodeError::Invalid),
637 Action::GetCompositeSchedule => ocpp_core::decode_value(payload)
638 .map(CsmsCall::GetCompositeSchedule)
639 .map_err(DecodeError::Invalid),
640 Action::GetConfiguration => ocpp_core::decode_value(payload)
641 .map(CsmsCall::GetConfiguration)
642 .map_err(DecodeError::Invalid),
643 Action::GetDiagnostics => ocpp_core::decode_value(payload)
644 .map(CsmsCall::GetDiagnostics)
645 .map_err(DecodeError::Invalid),
646 Action::GetLocalListVersion => ocpp_core::decode_value(payload)
647 .map(CsmsCall::GetLocalListVersion)
648 .map_err(DecodeError::Invalid),
649 Action::RemoteStartTransaction => ocpp_core::decode_value(payload)
650 .map(CsmsCall::RemoteStartTransaction)
651 .map_err(DecodeError::Invalid),
652 Action::RemoteStopTransaction => ocpp_core::decode_value(payload)
653 .map(CsmsCall::RemoteStopTransaction)
654 .map_err(DecodeError::Invalid),
655 Action::ReserveNow => ocpp_core::decode_value(payload)
656 .map(CsmsCall::ReserveNow)
657 .map_err(DecodeError::Invalid),
658 Action::Reset => ocpp_core::decode_value(payload)
659 .map(CsmsCall::Reset)
660 .map_err(DecodeError::Invalid),
661 Action::SendLocalList => ocpp_core::decode_value(payload)
662 .map(CsmsCall::SendLocalList)
663 .map_err(DecodeError::Invalid),
664 Action::SetChargingProfile => ocpp_core::decode_value(payload)
665 .map(CsmsCall::SetChargingProfile)
666 .map_err(DecodeError::Invalid),
667 Action::TriggerMessage => ocpp_core::decode_value(payload)
668 .map(CsmsCall::TriggerMessage)
669 .map_err(DecodeError::Invalid),
670 Action::UnlockConnector => ocpp_core::decode_value(payload)
671 .map(CsmsCall::UnlockConnector)
672 .map_err(DecodeError::Invalid),
673 Action::UpdateFirmware => ocpp_core::decode_value(payload)
674 .map(CsmsCall::UpdateFirmware)
675 .map_err(DecodeError::Invalid),
676 #[allow(unreachable_patterns)]
677 other => Err(DecodeError::WrongDirection(other)),
678 }
679 }
680
681 pub fn to_payload(&self) -> serde_json::Value {
683 match self {
684 CsmsCall::CancelReservation(r) => serde_json::to_value(r).expect("serializable"),
685 CsmsCall::ChangeAvailability(r) => serde_json::to_value(r).expect("serializable"),
686 CsmsCall::ChangeConfiguration(r) => serde_json::to_value(r).expect("serializable"),
687 CsmsCall::ClearCache(r) => serde_json::to_value(r).expect("serializable"),
688 CsmsCall::ClearChargingProfile(r) => serde_json::to_value(r).expect("serializable"),
689 CsmsCall::DataTransfer(r) => serde_json::to_value(r).expect("serializable"),
690 CsmsCall::GetCompositeSchedule(r) => serde_json::to_value(r).expect("serializable"),
691 CsmsCall::GetConfiguration(r) => serde_json::to_value(r).expect("serializable"),
692 CsmsCall::GetDiagnostics(r) => serde_json::to_value(r).expect("serializable"),
693 CsmsCall::GetLocalListVersion(r) => serde_json::to_value(r).expect("serializable"),
694 CsmsCall::RemoteStartTransaction(r) => serde_json::to_value(r).expect("serializable"),
695 CsmsCall::RemoteStopTransaction(r) => serde_json::to_value(r).expect("serializable"),
696 CsmsCall::ReserveNow(r) => serde_json::to_value(r).expect("serializable"),
697 CsmsCall::Reset(r) => serde_json::to_value(r).expect("serializable"),
698 CsmsCall::SendLocalList(r) => serde_json::to_value(r).expect("serializable"),
699 CsmsCall::SetChargingProfile(r) => serde_json::to_value(r).expect("serializable"),
700 CsmsCall::TriggerMessage(r) => serde_json::to_value(r).expect("serializable"),
701 CsmsCall::UnlockConnector(r) => serde_json::to_value(r).expect("serializable"),
702 CsmsCall::UpdateFirmware(r) => serde_json::to_value(r).expect("serializable"),
703 }
704 }
705}
706
707pub fn validate_response(action: Action, payload: &str) -> Result<serde_json::Value, Violation> {
709 match action {
710 Action::Authorize => ocpp_core::decode_payload::<AuthorizeResponse>(payload)
711 .map(|r| serde_json::to_value(r).expect("serializable")),
712 Action::BootNotification => ocpp_core::decode_payload::<BootNotificationResponse>(payload)
713 .map(|r| serde_json::to_value(r).expect("serializable")),
714 Action::CancelReservation => {
715 ocpp_core::decode_payload::<CancelReservationResponse>(payload)
716 .map(|r| serde_json::to_value(r).expect("serializable"))
717 }
718 Action::ChangeAvailability => {
719 ocpp_core::decode_payload::<ChangeAvailabilityResponse>(payload)
720 .map(|r| serde_json::to_value(r).expect("serializable"))
721 }
722 Action::ChangeConfiguration => {
723 ocpp_core::decode_payload::<ChangeConfigurationResponse>(payload)
724 .map(|r| serde_json::to_value(r).expect("serializable"))
725 }
726 Action::ClearCache => ocpp_core::decode_payload::<ClearCacheResponse>(payload)
727 .map(|r| serde_json::to_value(r).expect("serializable")),
728 Action::ClearChargingProfile => {
729 ocpp_core::decode_payload::<ClearChargingProfileResponse>(payload)
730 .map(|r| serde_json::to_value(r).expect("serializable"))
731 }
732 Action::DataTransfer => ocpp_core::decode_payload::<DataTransferResponse>(payload)
733 .map(|r| serde_json::to_value(r).expect("serializable")),
734 Action::DiagnosticsStatusNotification => {
735 ocpp_core::decode_payload::<DiagnosticsStatusNotificationResponse>(payload)
736 .map(|r| serde_json::to_value(r).expect("serializable"))
737 }
738 Action::FirmwareStatusNotification => {
739 ocpp_core::decode_payload::<FirmwareStatusNotificationResponse>(payload)
740 .map(|r| serde_json::to_value(r).expect("serializable"))
741 }
742 Action::GetCompositeSchedule => {
743 ocpp_core::decode_payload::<GetCompositeScheduleResponse>(payload)
744 .map(|r| serde_json::to_value(r).expect("serializable"))
745 }
746 Action::GetConfiguration => ocpp_core::decode_payload::<GetConfigurationResponse>(payload)
747 .map(|r| serde_json::to_value(r).expect("serializable")),
748 Action::GetDiagnostics => ocpp_core::decode_payload::<GetDiagnosticsResponse>(payload)
749 .map(|r| serde_json::to_value(r).expect("serializable")),
750 Action::GetLocalListVersion => {
751 ocpp_core::decode_payload::<GetLocalListVersionResponse>(payload)
752 .map(|r| serde_json::to_value(r).expect("serializable"))
753 }
754 Action::Heartbeat => ocpp_core::decode_payload::<HeartbeatResponse>(payload)
755 .map(|r| serde_json::to_value(r).expect("serializable")),
756 Action::MeterValues => ocpp_core::decode_payload::<MeterValuesResponse>(payload)
757 .map(|r| serde_json::to_value(r).expect("serializable")),
758 Action::RemoteStartTransaction => {
759 ocpp_core::decode_payload::<RemoteStartTransactionResponse>(payload)
760 .map(|r| serde_json::to_value(r).expect("serializable"))
761 }
762 Action::RemoteStopTransaction => {
763 ocpp_core::decode_payload::<RemoteStopTransactionResponse>(payload)
764 .map(|r| serde_json::to_value(r).expect("serializable"))
765 }
766 Action::ReserveNow => ocpp_core::decode_payload::<ReserveNowResponse>(payload)
767 .map(|r| serde_json::to_value(r).expect("serializable")),
768 Action::Reset => ocpp_core::decode_payload::<ResetResponse>(payload)
769 .map(|r| serde_json::to_value(r).expect("serializable")),
770 Action::SendLocalList => ocpp_core::decode_payload::<SendLocalListResponse>(payload)
771 .map(|r| serde_json::to_value(r).expect("serializable")),
772 Action::SetChargingProfile => {
773 ocpp_core::decode_payload::<SetChargingProfileResponse>(payload)
774 .map(|r| serde_json::to_value(r).expect("serializable"))
775 }
776 Action::StartTransaction => ocpp_core::decode_payload::<StartTransactionResponse>(payload)
777 .map(|r| serde_json::to_value(r).expect("serializable")),
778 Action::StatusNotification => {
779 ocpp_core::decode_payload::<StatusNotificationResponse>(payload)
780 .map(|r| serde_json::to_value(r).expect("serializable"))
781 }
782 Action::StopTransaction => ocpp_core::decode_payload::<StopTransactionResponse>(payload)
783 .map(|r| serde_json::to_value(r).expect("serializable")),
784 Action::TriggerMessage => ocpp_core::decode_payload::<TriggerMessageResponse>(payload)
785 .map(|r| serde_json::to_value(r).expect("serializable")),
786 Action::UnlockConnector => ocpp_core::decode_payload::<UnlockConnectorResponse>(payload)
787 .map(|r| serde_json::to_value(r).expect("serializable")),
788 Action::UpdateFirmware => ocpp_core::decode_payload::<UpdateFirmwareResponse>(payload)
789 .map(|r| serde_json::to_value(r).expect("serializable")),
790 }
791}