Skip to main content

armature_eventsourcing/
lib.rs

1//! Event Sourcing for Armature
2//!
3//! This crate provides event sourcing capabilities with aggregates and event stores.
4//!
5//! ## Features
6//!
7//! - **Aggregates** - Event-sourced aggregate roots
8//! - **Event Store** - Persistent event storage
9//! - **Snapshots** - Aggregate snapshots for performance
10//! - **Repository** - Load/save aggregates
11//! - **Optimistic Concurrency** - Version-based conflict detection
12//!
13//! ## Quick Start
14//!
15//! ```rust,ignore
16//! use armature_eventsourcing::*;
17//! use armature_events::DomainEvent;
18//! use async_trait::async_trait;
19//! use serde::{Deserialize, Serialize};
20//!
21//! // Define aggregate state
22//! #[derive(Debug, Clone, Serialize, Deserialize)]
23//! struct UserState {
24//!     email: String,
25//!     active: bool,
26//! }
27//!
28//! // Define aggregate
29//! #[derive(Debug, Clone, Serialize, Deserialize)]
30//! struct UserAggregate {
31//!     #[serde(flatten)]
32//!     root: AggregateRoot<UserState>,
33//! }
34//!
35//! #[async_trait]
36//! impl Aggregate for UserAggregate {
37//!     fn aggregate_id(&self) -> &str { &self.root.id }
38//!     fn aggregate_type() -> &'static str { "User" }
39//!     fn version(&self) -> u64 { self.root.version }
40//!
41//!     fn apply_event(&mut self, event: &DomainEvent) -> Result<(), AggregateError> {
42//!         match event.metadata.name.as_str() {
43//!             "user_created" => {
44//!                 self.root.state.email = event.payload["email"].as_str().unwrap().to_string();
45//!                 self.root.state.active = true;
46//!                 self.root.increment_version();
47//!             }
48//!             "user_deactivated" => {
49//!                 self.root.state.active = false;
50//!                 self.root.increment_version();
51//!             }
52//!             _ => {}
53//!         }
54//!         Ok(())
55//!     }
56//!
57//!     fn uncommitted_events(&self) -> &[DomainEvent] { &self.root.uncommitted_events }
58//!     fn mark_events_committed(&mut self) { self.root.uncommitted_events.clear(); }
59//!
60//!     fn new_instance(id: String) -> Self {
61//!         Self {
62//!             root: AggregateRoot::new(id, UserState {
63//!                 email: String::new(),
64//!                 active: false,
65//!             }),
66//!         }
67//!     }
68//! }
69//!
70//! // Use the repository
71//! #[tokio::main]
72//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
73//!     // Create event store
74//!     let store = Arc::new(InMemoryEventStore::new());
75//!
76//!     // Create repository
77//!     let repo = AggregateRepository::<UserAggregate, _>::new(store);
78//!
79//!     // Create new aggregate
80//!     let mut user = UserAggregate::new_instance("user-123".to_string());
81//!
82//!     // Add event
83//!     user.root.add_event(DomainEvent::new(
84//!         "user_created",
85//!         "user-123",
86//!         "User",
87//!         serde_json::json!({"email": "alice@example.com"}),
88//!     ));
89//!
90//!     // Apply event
91//!     let event = user.root.uncommitted_events[0].clone();
92//!     user.apply_event(&event)?;
93//!
94//!     // Save aggregate
95//!     repo.save(&mut user).await?;
96//!
97//!     // Load aggregate
98//!     let loaded = repo.load("user-123").await?;
99//!     println!("Loaded user: {:?}", loaded);
100//!
101//!     Ok(())
102//! }
103//! ```
104//!
105//! ## Snapshots
106//!
107//! ```rust,ignore
108//! // Enable snapshots every 10 events
109//! let repo = AggregateRepository::<UserAggregate, _>::with_snapshots(store, 10);
110//! ```
111
112pub mod aggregate;
113pub mod repository;
114pub mod store;
115
116pub use aggregate::{Aggregate, AggregateError, AggregateRoot, Snapshot};
117pub use repository::AggregateRepository;
118pub use store::{EventStore, EventStoreError, InMemoryEventStore};
119
120#[cfg(test)]
121mod tests {
122    #[test]
123    fn test_module_exports() {
124        // Ensure module compiles
125    }
126}