use super::State;
use serde::ser::SerializeMap;
use serde::Serialize;
use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventAction {
Created { state: State },
StatusChanged { from: State, to: State },
}
impl EventAction {
pub fn as_str(&self) -> &str {
match self {
EventAction::Created { .. } => "created",
EventAction::StatusChanged { .. } => "status_changed",
}
}
pub fn is_created(&self) -> bool {
matches!(self, EventAction::Created { .. })
}
pub fn is_status_changed(&self) -> bool {
matches!(self, EventAction::StatusChanged { .. })
}
}
impl fmt::Display for EventAction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl Serialize for EventAction {
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
match self {
EventAction::Created { state } => {
let mut m = s.serialize_map(Some(2))?;
m.serialize_entry("name", "created")?;
m.serialize_entry("status", state.as_str())?;
m.end()
}
EventAction::StatusChanged { from, to } => {
let mut m = s.serialize_map(Some(3))?;
m.serialize_entry("name", "status_changed")?;
m.serialize_entry("from", from.as_str())?;
m.serialize_entry("to", to.as_str())?;
m.end()
}
}
}
}
#[cfg(test)]
pub mod strategy {
use super::super::state::strategy::state;
use super::EventAction;
use proptest::prelude::*;
pub fn event_action() -> impl Strategy<Value = EventAction> {
prop_oneof![
state().prop_map(|s| EventAction::Created { state: s }),
(state(), state()).prop_map(|(from, to)| EventAction::StatusChanged { from, to }),
]
}
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn as_str_is_one_of_known_labels(a in strategy::event_action()) {
prop_assert!(matches!(a.as_str(), "created" | "status_changed"));
}
#[test]
fn classifier_methods_partition_variants(a in strategy::event_action()) {
prop_assert_ne!(a.is_created(), a.is_status_changed());
}
}
}