use bon::Builder;
use serde::{Deserialize, Serialize};
use crate::types::validate_fields;
use crate::types::{CiString, DateTime, Extensions, Url, Validate, Validator, ViolationCode};
use super::tokens::Token;
pub use crate::v2_3_0::commands::{
CancelReservation, CommandResponse, CommandResponseType, CommandResult, CommandResultType, CommandType,
StopSession, UnlockConnector,
};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Builder)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[builder(on(_, into))]
pub struct StartSession {
pub response_url: Url,
pub token: Token,
pub location_id: CiString<36>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub evse_uid: Option<CiString<36>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub connector_id: Option<CiString<36>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub authorization_reference: Option<CiString<36>>,
#[serde(flatten, default, skip_serializing_if = "Extensions::is_empty")]
#[builder(default)]
pub extensions: Extensions,
}
impl Validate for StartSession {
fn validate_in(&self, v: &mut Validator) {
validate_fields!(
self,
v,
response_url,
token,
location_id,
evse_uid,
connector_id,
authorization_reference,
);
if self.connector_id.is_some() && self.evse_uid.is_none() {
v.report_at(
"evse_uid",
ViolationCode::MissingConditional,
"is required when `connector_id` is set",
);
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Builder)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[builder(on(_, into))]
pub struct ReserveNow {
pub response_url: Url,
pub token: Token,
pub expiry_date: DateTime,
pub reservation_id: CiString<36>,
pub location_id: CiString<36>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub evse_uid: Option<CiString<36>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub authorization_reference: Option<CiString<36>>,
#[serde(flatten, default, skip_serializing_if = "Extensions::is_empty")]
#[builder(default)]
pub extensions: Extensions,
}
impl Validate for ReserveNow {
fn validate_in(&self, v: &mut Validator) {
validate_fields!(
self,
v,
response_url,
token,
expiry_date,
reservation_id,
location_id,
evse_uid,
authorization_reference,
);
}
}
#[derive(Clone, Debug, PartialEq)]
#[non_exhaustive]
pub enum Command {
CancelReservation(CancelReservation),
ReserveNow(Box<ReserveNow>),
StartSession(Box<StartSession>),
StopSession(StopSession),
UnlockConnector(UnlockConnector),
}
impl Command {
#[must_use]
pub fn command_type(&self) -> CommandType {
match self {
Self::CancelReservation(_) => CommandType::CancelReservation,
Self::ReserveNow(_) => CommandType::ReserveNow,
Self::StartSession(_) => CommandType::StartSession,
Self::StopSession(_) => CommandType::StopSession,
Self::UnlockConnector(_) => CommandType::UnlockConnector,
}
}
#[must_use]
pub fn response_url(&self) -> &Url {
match self {
Self::CancelReservation(c) => &c.response_url,
Self::ReserveNow(c) => &c.response_url,
Self::StartSession(c) => &c.response_url,
Self::StopSession(c) => &c.response_url,
Self::UnlockConnector(c) => &c.response_url,
}
}
}
impl Validate for Command {
fn validate_in(&self, v: &mut Validator) {
match self {
Self::CancelReservation(c) => c.validate_in(v),
Self::ReserveNow(c) => c.validate_in(v),
Self::StartSession(c) => c.validate_in(v),
Self::StopSession(c) => c.validate_in(v),
Self::UnlockConnector(c) => c.validate_in(v),
}
}
}