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