This is an opinionated fork of Eventually-rs.
Eventastic enforces the use of transactions, handles idempotency and removes command handling abstractions.
See full examples in examples/bank
```rust // Setup postgres repo
let connectionoptions = PgConnectOptions::fromstr("postgres://postgres:password@localhost/postgres")?;
let pool_options = PoolOptions::default();
let repository = PostgresRepository::new(connectionoptions, pooloptions).await?;
// Start transaction let mut transaction = repository.transaction().await?;
let accountid = Uuid::newv4(); let eventid = Uuid::newv4(); let addeventid = Uuid::new_v4();
// Open bank account
let event = AccountEvent::Open(eventid, accountid, 21);
let mut account = Account::record_new(event)?;
// Add funds to newly created event let addevent = AccountEvent::Add(addevent_id, 324);
// Record takes in the transaction, as it does idempotency checks with the db. account .recordthat(&mut transaction, addevent.clone()) .await?;
// Save uncommitted events in the db. transaction.store(&mut account).await?;
// Since we have access to the transaction // We could use a transactional outbox to store our side effects
// Commit the transaction transaction.commit().await?;
// Get the aggregate from the db let mut transaction = repository.transaction().await?;
let mut account: Context
assert_eq!(account.state().balance, 345);
// Trying to apply the same event id but with different content gives us an IdempotencyError let changedaddevent = AccountEvent::Add(addeventid, 123);
let err = account .recordthat(&mut transaction, changedaddevent) .await .expecterr("failed to get error");
assert!(matches!(err, RecordError::IdempotencyError(_, _)));
// Applying the already applied event, will be ignored and return Ok account.recordthat(&mut transaction, addevent).await?;
// Balance hasn't changed since the event wasn't actually applied assert_eq!(account.state().balance, 345);
println!("Got account {account:?}"); Ok(()) ```