use serde::{Deserialize, Deserializer, Serialize, Serializer};
use super::ExtensionMap;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SchedulingIntent {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub mode: SchedulingMode,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cron: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub timezone: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub frequency: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub windows: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub blackouts: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub deadlines: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub events: Vec<SchedulingEvent>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub constraints: Option<SchedulingConstraints>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub policies: Vec<String>,
#[serde(default, flatten)]
pub extensions: ExtensionMap,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SchedulingMode {
Manual,
OnDemand,
Scheduled,
EventDriven,
Streaming,
Continuous,
Extension(String),
}
impl SchedulingMode {
pub fn as_str(&self) -> &str {
match self {
Self::Manual => "manual",
Self::OnDemand => "onDemand",
Self::Scheduled => "scheduled",
Self::EventDriven => "eventDriven",
Self::Streaming => "streaming",
Self::Continuous => "continuous",
Self::Extension(value) => value.as_str(),
}
}
pub fn is_scheduled(&self) -> bool {
matches!(self, Self::Scheduled)
}
pub fn is_event_driven(&self) -> bool {
matches!(self, Self::EventDriven)
}
}
impl Serialize for SchedulingMode {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.as_str())
}
}
impl<'de> Deserialize<'de> for SchedulingMode {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let value = String::deserialize(deserializer)?;
let normalized: String = value
.chars()
.filter(|ch| ch.is_ascii_alphanumeric())
.flat_map(char::to_lowercase)
.collect();
Ok(match normalized.as_str() {
"manual" => Self::Manual,
"ondemand" => Self::OnDemand,
"scheduled" => Self::Scheduled,
"eventdriven" => Self::EventDriven,
"streaming" => Self::Streaming,
"continuous" => Self::Continuous,
_ => Self::Extension(value),
})
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SchedulingEvent {
pub id: String,
pub source: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub condition: Option<String>,
#[serde(default, flatten)]
pub extensions: ExtensionMap,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct SchedulingConstraints {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub earliest: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub latest: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub deadline: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub concurrency: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ordering: Option<String>,
#[serde(default, flatten)]
pub extensions: ExtensionMap,
}