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