Skip to main content

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::{RecurringSchedule, 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(RecurringSchedule::new(Duration::from_millis(10)).with_expiration_count(2))
50//!     .start(|| async { Ok::<(), TimerError>(()) })
51//!     .await
52//!     .unwrap();
53//!
54//! let outcome = timer.join().await.unwrap();
55//! assert_eq!(outcome.reason, TimerFinishReason::Completed);
56//! assert_eq!(outcome.statistics.execution_count, 2);
57//! # });
58//! ```
59//!
60//! Observe completion without relying on lossy broadcast delivery:
61//!
62//! ```rust
63//! use std::time::Duration;
64//! use timer_lib::{Timer, TimerError};
65//!
66//! # let runtime = tokio::runtime::Builder::new_current_thread()
67//! #     .enable_all()
68//! #     .build()
69//! #     .unwrap();
70//! # runtime.block_on(async {
71//! let timer = Timer::new();
72//! let mut completion = timer.completion();
73//! let run_id = timer
74//!     .start_once(Duration::from_millis(10), || async { Ok::<(), TimerError>(()) })
75//!     .await
76//!     .unwrap();
77//!
78//! let outcome = completion.wait_for_run(run_id).await.unwrap();
79//! assert_eq!(outcome.run_id, run_id);
80//! # });
81//! ```
82//!
83//! # Runtime
84//!
85//! This crate currently targets Tokio.
86//!
87//! # Errors
88//!
89//! Public operations return [`TimerError`] for invalid configuration or invalid
90//! lifecycle transitions.
91
92pub mod errors;
93pub mod registry;
94pub mod timer;
95
96pub use errors::TimerError;
97pub use registry::TimerRegistry;
98#[deprecated(note = "Use TimerRegistry instead.")]
99pub type TimerManager = TimerRegistry;
100pub use timer::{
101    RecurringCadence, RecurringSchedule, RetryPolicy, Timer, TimerBuilder, TimerCallback,
102    TimerCompletion, TimerEvent, TimerEvents, TimerFinishReason, TimerOutcome, TimerState,
103    TimerStatistics,
104};
105
106// Rust guideline compliant 2026-02-21