polyoxide_rt/lib.rs
1//! # polyoxide-rt
2//!
3//! The runtime seam of the polyoxide crates. A crate that sleeps, reads the
4//! clock or spawns takes a [`Runtime`] instead of calling a runtime's own
5//! functions, so a runtime can be injected rather than assumed.
6//!
7//! - [`Runtime`] is a detached `spawn`, a `sleep`, a monotonic `now` and a
8//! defaulted `sleep_until`. An implementor writes only those.
9//! - [`spawn`] turns any future into a [`Task`], which resolves to `Some`
10//! output, or to `None` when it was aborted or panicked, and keeps running
11//! when it is dropped.
12//! - [`timeout`] bounds a future by a duration on a runtime's clock, polling
13//! the future first, so a ready future wins at `Duration::ZERO`.
14//! - [`interval`] ticks at once and then every period, and an [`Interval`]
15//! takes a [`MissedTick`] to say what to do about ticks it was late for.
16//! - `TokioRuntime` is the native runtime, on tokio's own clock so a paused
17//! clock drives it, and [`default_runtime`] returns it off wasm32. On wasm32
18//! `BrowserRuntime` is the default: `spawn_local`, `setTimeout` and
19//! `performance.now`.
20//! - [`Instant`], [`SystemTime`] and [`UNIX_EPOCH`] are `web-time`'s: std's own
21//! types on native.
22//!
23//! ```
24//! use std::time::Duration;
25//!
26//! use polyoxide_rt::{default_runtime, spawn, timeout};
27//!
28//! #[tokio::main(flavor = "current_thread")]
29//! async fn main() {
30//! let runtime = default_runtime();
31//!
32//! let task = spawn(&*runtime, async { 6 * 7 });
33//! assert_eq!(task.await, Some(42));
34//!
35//! let slow = runtime.sleep(Duration::from_secs(60));
36//! let waited = timeout(&*runtime, Duration::from_millis(10), slow).await;
37//! assert_eq!(waited, None);
38//! }
39//! ```
40//!
41//! The crate depends on nothing in the workspace and names no venue, so it
42//! publishes first and every other crate can use it.
43
44#![warn(missing_docs)]
45
46#[cfg(doctest)]
47#[doc = include_str!("../README.md")]
48struct ReadmeDoctests;
49
50mod browser;
51mod runtime;
52mod task;
53mod time;
54#[cfg(not(target_arch = "wasm32"))]
55mod tokio;
56
57use std::future::Future;
58use std::pin::Pin;
59
60pub use runtime::Runtime;
61pub use task::{spawn, Task};
62pub use time::{interval, timeout, Interval, MissedTick};
63pub use web_time::{Instant, SystemTime, UNIX_EPOCH};
64
65#[cfg(not(target_arch = "wasm32"))]
66pub use self::tokio::TokioRuntime;
67#[cfg(target_arch = "wasm32")]
68pub use browser::BrowserRuntime;
69
70/// An owned, sendable future: what a [`Runtime`] spawns and sleeps on.
71pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>;
72
73/// The runtime a client uses when none is injected: `TokioRuntime` on a host
74/// target and `BrowserRuntime` on `wasm32`.
75#[cfg(not(target_arch = "wasm32"))]
76pub fn default_runtime() -> std::sync::Arc<dyn Runtime> {
77 std::sync::Arc::new(TokioRuntime)
78}
79
80/// The runtime a client uses when none is injected: `TokioRuntime` on a host
81/// target and `BrowserRuntime` on `wasm32`.
82#[cfg(target_arch = "wasm32")]
83pub fn default_runtime() -> std::sync::Arc<dyn Runtime> {
84 std::sync::Arc::new(BrowserRuntime)
85}