Skip to main content

commerce_theory/
event_language.rs

1use crate::event_sourcing::*;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5pub enum OrderEventSymbol {
6    OrderPlaced,
7    PaymentCaptured,
8    RefundIssued,
9    StockReserved,
10    OrderShipped,
11    Other,
12}
13
14#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub enum OrderEventValidationState {
17    Start,
18    Placed,
19    Captured,
20    Refunded,
21    Shipped,
22    Invalid,
23}
24
25#[must_use]
26pub const fn domain_event_symbol(event: &DomainEvent) -> OrderEventSymbol {
27    match event {
28        DomainEvent::OrderPlaced(_, _) => OrderEventSymbol::OrderPlaced,
29        DomainEvent::PaymentCaptured(_, _) => OrderEventSymbol::PaymentCaptured,
30        DomainEvent::RefundIssued(_, _) => OrderEventSymbol::RefundIssued,
31        DomainEvent::StockReserved(_, _) => OrderEventSymbol::StockReserved,
32        DomainEvent::OrderShipped(_) => OrderEventSymbol::OrderShipped,
33        DomainEvent::ReservationReleased(_, _)
34        | DomainEvent::ReservedShipmentConfirmed(_, _)
35        | DomainEvent::TaxLiabilityRecorded(_, _)
36        | DomainEvent::LeadConverted(_, _)
37        | DomainEvent::SupportCaseOpened(_, _)
38        | DomainEvent::ShipmentPlanned(_, _)
39        | DomainEvent::ShipmentDelivered(_)
40        | DomainEvent::ReturnApproved(_, _, _) => OrderEventSymbol::Other,
41    }
42}
43
44pub fn domain_event_symbols(events: &[DomainEvent]) -> Vec<OrderEventSymbol> {
45    events.iter().map(domain_event_symbol).collect()
46}
47
48#[must_use]
49pub const fn order_event_validation_step(
50    state: OrderEventValidationState,
51    symbol: OrderEventSymbol,
52) -> OrderEventValidationState {
53    match (state, symbol) {
54        (OrderEventValidationState::Start, OrderEventSymbol::OrderPlaced)
55        | (OrderEventValidationState::Placed, OrderEventSymbol::StockReserved) => {
56            OrderEventValidationState::Placed
57        }
58        (OrderEventValidationState::Placed, OrderEventSymbol::PaymentCaptured)
59        | (OrderEventValidationState::Captured, OrderEventSymbol::StockReserved) => {
60            OrderEventValidationState::Captured
61        }
62        (OrderEventValidationState::Captured, OrderEventSymbol::RefundIssued) => {
63            OrderEventValidationState::Refunded
64        }
65        (OrderEventValidationState::Captured, OrderEventSymbol::OrderShipped) => {
66            OrderEventValidationState::Shipped
67        }
68        (state, OrderEventSymbol::Other) => state,
69        _ => OrderEventValidationState::Invalid,
70    }
71}
72
73pub fn validate_order_event_symbols(symbols: &[OrderEventSymbol]) -> OrderEventValidationState {
74    symbols.iter().copied().fold(
75        OrderEventValidationState::Start,
76        order_event_validation_step,
77    )
78}
79
80#[must_use]
81pub fn order_event_word_accepted(symbols: &[OrderEventSymbol]) -> bool {
82    matches!(
83        validate_order_event_symbols(symbols),
84        OrderEventValidationState::Shipped | OrderEventValidationState::Refunded
85    )
86}
87
88#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
89pub struct OrderEventValidator;
90
91impl OrderEventValidator {
92    #[must_use]
93    pub const fn start(self) -> OrderEventValidationState {
94        OrderEventValidationState::Start
95    }
96
97    #[must_use]
98    pub const fn step(
99        self,
100        state: OrderEventValidationState,
101        symbol: OrderEventSymbol,
102    ) -> OrderEventValidationState {
103        order_event_validation_step(state, symbol)
104    }
105
106    #[must_use]
107    pub fn run(self, symbols: &[OrderEventSymbol]) -> OrderEventValidationState {
108        validate_order_event_symbols(symbols)
109    }
110
111    #[must_use]
112    pub fn accepts(self, symbols: &[OrderEventSymbol]) -> bool {
113        order_event_word_accepted(symbols)
114    }
115}
116
117#[must_use]
118pub const fn order_event_validator() -> OrderEventValidator {
119    OrderEventValidator
120}