Skip to main content

allsource/
lib.rs

1//! # AllSource Rust SDK
2//!
3//! Official Rust client for the [AllSource](https://github.com/all-source-os/allsource-monorepo)
4//! event store. Provides two clients:
5//!
6//! - [`QueryClient`] — reads from the Query Service (events, projections, streams)
7//! - [`CoreClient`] — writes directly to Core (event ingestion, batch ingest)
8//!
9//! Plus the [`EventFolder`] trait for reconstructing domain state from event streams.
10//!
11//! ## Quick Start
12//!
13//! ```rust,no_run
14//! use allsource::{QueryClient, IngestEventInput};
15//! use serde_json::json;
16//!
17//! #[tokio::main]
18//! async fn main() -> Result<(), allsource::Error> {
19//!     let qs = QueryClient::new("http://localhost:3902", "your-api-key")?;
20//!
21//!     // Query events
22//!     let result = qs.query_events(
23//!         allsource::QueryEventsParams::new().entity_id("user-123").limit(10),
24//!     ).await?;
25//!
26//!     for event in &result.events {
27//!         println!("{}: {}", event.event_type, event.timestamp);
28//!     }
29//!
30//!     Ok(())
31//! }
32//! ```
33//!
34//! ## Event Folding
35//!
36//! ```rust,no_run
37//! use allsource::{Event, EventFolder, fold_events};
38//!
39//! #[derive(Default)]
40//! struct UserState {
41//!     email: Option<String>,
42//!     name: Option<String>,
43//!     active: bool,
44//! }
45//!
46//! impl EventFolder for UserState {
47//!     type State = Self;
48//!
49//!     fn apply(&mut self, event: &Event) -> bool {
50//!         match event.event_type.as_str() {
51//!             "user.created" => {
52//!                 self.email = event.payload.get("email").and_then(|v| v.as_str()).map(String::from);
53//!                 self.name = event.payload.get("name").and_then(|v| v.as_str()).map(String::from);
54//!                 self.active = true;
55//!                 true
56//!             }
57//!             "user.deactivated" => { self.active = false; true }
58//!             _ => false,
59//!         }
60//!     }
61//!
62//!     fn finalize(self) -> Option<Self::State> {
63//!         if self.email.is_some() { Some(self) } else { None }
64//!     }
65//! }
66//! ```
67
68mod circuit_breaker;
69mod client;
70mod error;
71mod fold;
72mod normalize;
73mod types;
74
75pub use circuit_breaker::CircuitBreaker;
76pub use client::{ClientConfig, CoreClient, QueryClient, RetryConfig};
77pub use error::Error;
78pub use fold::{fold_events, EventFolder};
79pub use normalize::normalize_event_type;
80pub use types::*;
81
82// Re-export for payload construction
83pub use serde_json::{self, json, Value};