Skip to main content

gust_stdlib/
lib.rs

1#![warn(missing_docs)]
2//! # Gust Standard Library
3//!
4//! A collection of reusable, production-ready Gust state machines that solve
5//! common distributed systems and application patterns.
6//!
7//! Each machine is shipped as a `.gu` source string embedded at compile time.
8//! You can feed these sources directly to the Gust compiler or include them
9//! alongside your own `.gu` files.
10//!
11//! ## Available machines
12//!
13//! | Machine | Constant | Description |
14//! |---------|----------|-------------|
15//! | **CircuitBreaker** | [`CIRCUIT_BREAKER`] | Protects calls to external services by tracking failures and opening the circuit when a threshold is reached. Transitions through `Closed`, `Open`, and `HalfOpen` states. |
16//! | **Retry** | [`RETRY`] | Implements retry-with-backoff logic. Tracks attempt counts, computes exponential delays with jitter, and caps at a maximum delay. |
17//! | **Saga** | [`SAGA`] | Orchestrates a sequence of distributed steps with automatic compensation (rollback) on failure, following the saga pattern. |
18//! | **RateLimiter** | [`RATE_LIMITER`] | Token-bucket rate limiter that transitions between `Available` and `Exhausted` states based on remaining tokens. |
19//! | **HealthCheck** | [`HEALTH_CHECK`] | Models service health with `Healthy`, `Degraded`, and `Unhealthy` states, tracking consecutive failures before transitioning. |
20//! | **RequestResponse** | [`REQUEST_RESPONSE`] | Models an async request lifecycle with `Pending`, `Completed`, `Failed`, and `TimedOut` states. |
21//!
22//! ## Available types
23//!
24//! | Type | Constant | Description |
25//! |------|----------|-------------|
26//! | **EngineFailure** | [`ENGINE_FAILURE`] | Typed runtime/engine failure for workflow-style machines: `UserError`, `SystemError`, `IntegrationError`, `Timeout`, `Cancelled`. |
27//!
28//! ## Usage
29//!
30//! Use [`all_sources`] to iterate over every standard-library source for
31//! bulk compilation, or access individual constants directly:
32//!
33//! ```rust
34//! let sources = gust_stdlib::all_sources();
35//! assert_eq!(sources.len(), 7);
36//!
37//! // Each entry is a (filename, source_code) pair
38//! for (filename, source) in &sources {
39//!     println!("{filename}: {} bytes", source.len());
40//! }
41//! ```
42
43/// The Gust source for the **RequestResponse** machine.
44///
45/// Models an async request lifecycle through `Pending`, `Completed`,
46/// `Failed`, and `TimedOut` states. Generic over the request type `T`
47/// and response type `R`.
48pub const REQUEST_RESPONSE: &str = include_str!("../request_response.gu");
49
50/// The Gust source for the **CircuitBreaker** machine.
51///
52/// Implements the circuit breaker pattern with three states:
53/// - **Closed** -- requests pass through; failures are counted against a threshold.
54/// - **Open** -- requests are blocked; a timeout controls when to probe again.
55/// - **HalfOpen** -- a limited number of probe requests are allowed to test recovery.
56///
57/// Generic over `T` for the protected call's context type.
58pub const CIRCUIT_BREAKER: &str = include_str!("../circuit_breaker.gu");
59
60/// The Gust source for the **Saga** machine.
61///
62/// Orchestrates a multi-step workflow with compensation. States include
63/// `Planning`, `Executing`, `Compensating`, and `Committed`. If any step
64/// fails during execution, the machine transitions to `Compensating` and
65/// rolls back previously completed steps in reverse order.
66///
67/// Generic over `S`, the type representing individual saga steps.
68pub const SAGA: &str = include_str!("../saga.gu");
69
70/// The Gust source for the **Retry** machine.
71///
72/// Provides configurable retry logic with exponential backoff and jitter.
73/// States include `Ready`, `Attempting`, `Waiting`, `Succeeded`, and
74/// `Failed`. Tracks attempt count, base and max delay, and jitter
75/// percentage.
76///
77/// Generic over `T` for the value type returned on success.
78pub const RETRY: &str = include_str!("../retry.gu");
79
80/// The Gust source for the **RateLimiter** machine.
81///
82/// A token-bucket rate limiter with two states:
83/// - **Available** -- tokens remain; requests can proceed.
84/// - **Exhausted** -- no tokens left; a `retry_after_ms` value indicates
85///   when tokens will be replenished.
86///
87/// Generic over `K` for the rate-limit key type.
88pub const RATE_LIMITER: &str = include_str!("../rate_limiter.gu");
89
90/// The Gust source for the **HealthCheck** machine.
91///
92/// Models service health monitoring with three states:
93/// - **Healthy** -- the service is operating normally.
94/// - **Degraded** -- some health checks are failing but the service is
95///   partially functional; tracks a failure count.
96/// - **Unhealthy** -- the service is down, with a reason string.
97///
98/// Generic over `T` for the health status payload type.
99pub const HEALTH_CHECK: &str = include_str!("../health_check.gu");
100
101/// The Gust source for the **EngineFailure** enum.
102///
103/// A typed runtime/engine failure surface for workflow-style machines.
104/// Workflow runtimes (e.g. Corsac) use this as a stable failure type so
105/// retry policies, replay semantics, and observability can reason about
106/// failures without parsing strings. Domain-specific failure enums can
107/// wrap `EngineFailure` to preserve the engine layer while adding
108/// domain variants.
109///
110/// Variants (positional payloads — see the source for field descriptions):
111/// - `UserError(String)`
112/// - `SystemError(String, i64)`
113/// - `IntegrationError(String, i64, String)`
114/// - `Timeout(i64)`
115/// - `Cancelled(String)`
116///
117/// Import in a `.gu` file with `use std::EngineFailure;`.
118pub const ENGINE_FAILURE: &str = include_str!("../engine_failure.gu");
119
120/// Returns all standard library machine sources as an array of
121/// `(filename, source_code)` pairs.
122///
123/// This is useful for bulk-compiling the entire standard library or
124/// for tooling that needs to enumerate available machines.
125///
126/// # Examples
127///
128/// ```rust
129/// let sources = gust_stdlib::all_sources();
130/// assert_eq!(sources.len(), 7);
131///
132/// // Find a specific machine by filename
133/// let circuit_breaker = sources.iter()
134///     .find(|(name, _)| *name == "circuit_breaker.gu")
135///     .expect("circuit_breaker.gu should exist");
136/// assert!(circuit_breaker.1.contains("machine CircuitBreaker"));
137/// ```
138pub fn all_sources() -> [(&'static str, &'static str); 7] {
139    [
140        ("request_response.gu", REQUEST_RESPONSE),
141        ("circuit_breaker.gu", CIRCUIT_BREAKER),
142        ("saga.gu", SAGA),
143        ("retry.gu", RETRY),
144        ("rate_limiter.gu", RATE_LIMITER),
145        ("health_check.gu", HEALTH_CHECK),
146        ("engine_failure.gu", ENGINE_FAILURE),
147    ]
148}