commerce_theory/
event_language.rs1use 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}