timer_lib/lib.rs
1//! Tokio-based timers for one-shot and recurring async work.
2//!
3//! `timer-lib` provides a handle-first API for scheduling async callbacks and
4//! observing their lifecycle.
5//!
6//! # Overview
7//!
8//! - [`Timer`] runs one-shot or recurring work.
9//! - [`TimerBuilder`] reduces setup boilerplate for common configurations.
10//! - [`TimerRegistry`] tracks timers by ID and supports bulk operations.
11//! - [`TimerEvents`] exposes broadcast lifecycle events.
12//! - [`TimerCompletion`] exposes lossless completed-run delivery.
13//!
14//! # Examples
15//!
16//! Start a one-shot timer and wait for it to finish:
17//!
18//! ```rust
19//! use std::time::Duration;
20//! use timer_lib::{Timer, TimerError, TimerFinishReason};
21//!
22//! # let runtime = tokio::runtime::Builder::new_current_thread()
23//! # .enable_all()
24//! # .build()
25//! # .unwrap();
26//! # runtime.block_on(async {
27//! let timer = Timer::new();
28//! timer
29//! .start_once(Duration::from_millis(10), || async { Ok::<(), TimerError>(()) })
30//! .await
31//! .unwrap();
32//!
33//! let outcome = timer.join().await.unwrap();
34//! assert_eq!(outcome.reason, TimerFinishReason::Completed);
35//! # });
36//! ```
37//!
38//! Build a recurring timer:
39//!
40//! ```rust
41//! use std::time::Duration;
42//! use timer_lib::{Timer, TimerError, TimerFinishReason};
43//!
44//! # let runtime = tokio::runtime::Builder::new_current_thread()
45//! # .enable_all()
46//! # .build()
47//! # .unwrap();
48//! # runtime.block_on(async {
49//! let timer = Timer::recurring(Duration::from_millis(10))
50//! .expiration_count(2)
51//! .start(|| async { Ok::<(), TimerError>(()) })
52//! .await
53//! .unwrap();
54//!
55//! let outcome = timer.join().await.unwrap();
56//! assert_eq!(outcome.reason, TimerFinishReason::Completed);
57//! assert_eq!(outcome.statistics.execution_count, 2);
58//! # });
59//! ```
60//!
61//! Observe completion without relying on lossy broadcast delivery:
62//!
63//! ```rust
64//! use std::time::Duration;
65//! use timer_lib::{Timer, TimerError};
66//!
67//! # let runtime = tokio::runtime::Builder::new_current_thread()
68//! # .enable_all()
69//! # .build()
70//! # .unwrap();
71//! # runtime.block_on(async {
72//! let timer = Timer::new();
73//! let mut completion = timer.completion();
74//! let run_id = timer
75//! .start_once(Duration::from_millis(10), || async { Ok::<(), TimerError>(()) })
76//! .await
77//! .unwrap();
78//!
79//! let outcome = completion.wait_for_run(run_id).await.unwrap();
80//! assert_eq!(outcome.run_id, run_id);
81//! # });
82//! ```
83//!
84//! # Runtime
85//!
86//! This crate currently targets Tokio.
87//!
88//! # Errors
89//!
90//! Public operations return [`TimerError`] for invalid configuration or invalid
91//! lifecycle transitions.
92
93pub mod errors;
94pub mod registry;
95pub mod timer;
96
97pub use errors::TimerError;
98pub use registry::TimerRegistry;
99#[deprecated(note = "Use TimerRegistry instead.")]
100pub type TimerManager = TimerRegistry;
101pub use timer::{
102 RetryPolicy, Timer, TimerBuilder, TimerCallback, TimerCompletion, TimerEvent, TimerEvents,
103 TimerFinishReason, TimerOutcome, TimerState, TimerStatistics,
104};
105
106// Rust guideline compliant 2026-02-21