sovran_example/
sovran_example.rs1use sovran_state::{Store, State, Action};
2use std::sync::Arc;
3use std::thread;
4use std::time::Duration;
5
6#[derive(Clone, Debug)]
8struct BankState {
9 balance: f64,
10 transaction_count: u32,
11}
12
13impl State for BankState {}
14
15struct DepositAction(f64);
17struct WithdrawAction(f64);
18
19impl Action<BankState> for DepositAction {
20 fn reduce(&self, state: BankState) -> BankState {
21 BankState {
22 balance: state.balance + self.0,
23 transaction_count: state.transaction_count + 1,
24 }
25 }
26}
27
28impl Action<BankState> for WithdrawAction {
29 fn reduce(&self, state: BankState) -> BankState {
30 BankState {
31 balance: state.balance - self.0,
32 transaction_count: state.transaction_count + 1,
33 }
34 }
35}
36
37struct AccountMonitor {
39 store: Arc<Store>,
40}
41
42struct TransactionLogger {
43 store: Arc<Store>,
44}
45
46impl AccountMonitor {
47 fn new(store: Arc<Store>) -> Self {
48 let monitor = AccountMonitor { store: store.clone() };
49
50 monitor.store.subscribe(move |state: &BankState| {
52 println!("🏦 Account Monitor: Balance changed to ${:.2}", state.balance);
53 }).expect("Failed to subscribe to state changes");
54
55 monitor
56 }
57
58 fn check_balance(&self) -> f64 {
59 self.store.get_state::<BankState>()
60 .map(|state| state.balance)
61 .unwrap_or(0.0)
62 }
63}
64
65impl TransactionLogger {
66 fn new(store: Arc<Store>) -> Self {
67 let logger = TransactionLogger { store: store.clone() };
68
69 logger.store.subscribe(move |state: &BankState| {
71 println!("📝 Transaction Logger: Transaction #{} processed",
72 state.transaction_count);
73 }).expect("Failed to subscribe to state changes");
74
75 logger
76 }
77}
78
79fn main() {
80 let store = Arc::new(Store::new());
82 store.provide(BankState {
83 balance: 1000.0,
84 transaction_count: 0,
85 }).expect("Failed to provide initial state");
86
87 let monitor = AccountMonitor::new(store.clone());
89 let _logger = TransactionLogger::new(store.clone());
90
91 println!("Initial balance: ${:.2}", monitor.check_balance());
92
93 println!("\nProcessing transactions...\n");
95
96 store.dispatch(DepositAction(500.0))
98 .expect("Failed to process deposit");
99 thread::sleep(Duration::from_millis(500));
100
101 store.dispatch(WithdrawAction(200.0))
103 .expect("Failed to process withdrawal");
104 thread::sleep(Duration::from_millis(500));
105
106 store.dispatch(DepositAction(750.0))
108 .expect("Failed to process deposit");
109 thread::sleep(Duration::from_millis(500));
110
111 println!("\nFinal balance: ${:.2}", monitor.check_balance());
112}