From 2277b2e7dabec000b92cafcb290e7b44b13f2b4e Mon Sep 17 00:00:00 2001 From: tison Date: Tue, 1 Sep 2026 01:47:16 +0800 Subject: [PATCH 1/2] docs: keep links valid across feature selections Asyncband exposes no APIs by default, but the crate overview and the rwlock guide linked directly to modules that may be disabled. Documentation builds with warnings denied therefore failed for legitimate dependency configurations. Use docs.rs targets so the feature catalog remains navigable without requiring unrelated features. Signed-off-by: tison --- asyncband/src/lib.rs | 58 +++++++++++++++++++------------------ asyncband/src/rwlock/mod.rs | 2 +- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/asyncband/src/lib.rs b/asyncband/src/lib.rs index 934e28af..828ddf19 100644 --- a/asyncband/src/lib.rs +++ b/asyncband/src/lib.rs @@ -54,35 +54,36 @@ //! //! # API map //! -//! | Area | API | Feature | Use | -//! |----------------------------|-----------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------| -//! | Shared state | [`Mutex`](mutex::Mutex) | `mutex` | Protect shared data with asynchronous mutual exclusion. | -//! | | [`RwLock`](rwlock::RwLock) | `rwlock` | Allow multiple readers or one writer. | -//! | | [`Condvar`](condvar::Condvar) | `condvar` | Wait for notifications while releasing a mutex. | -//! | Initialization and caching | [`Once`](once::Once) | `once` | Complete one asynchronous initialization; cancelled or panicked attempts may be retried. | -//! | | [`OnceCell`](once::OnceCell) | `once-cell` | Store one value from an access-time initializer; failed, cancelled, or panicked attempts may be retried. | -//! | | [`LazyCell`](once::LazyCell) | `lazy-cell` | Initialize one value with a stored function and resume the same in-flight future after caller cancellation. | -//! | | [`OnceMap`](once::OnceMap) | `once-map` | Cache one successfully initialized value per key until explicitly removed. | -//! | Task coordination | [`Barrier`](barrier::Barrier) | `barrier` | Synchronize a fixed number of participants at a reusable rendezvous. | -//! | | [`Completion`](completion::Completion) | `completion` | Publish one shared result to any number of current and future observers. | -//! | | [`ManualResetEvent`](event::ManualResetEvent) | `event` | Signal current and future waits until explicitly reset. | -//! | | [`Latch`](latch::Latch) | `latch` | Wait until a fixed one-way countdown reaches zero. | -//! | | [`WaitGroup`](waitgroup::WaitGroup) | `waitgroup` | Wait until all cloned worker handles are dropped. | -//! | | [`Shutdown`](shutdown::Shutdown) | `shutdown` | Request shutdown and wait until all completion guards are dropped. | -//! | Channels | [`oneshot`] | `oneshot` | Send one value from one sender to one receiver. | -//! | | [`mpsc`] | `mpsc` | Send each value from multiple producers to one receiver with bounded backpressure or an unbounded queue. | -//! | | [`broadcast`] | `broadcast` | Deliver every value to receivers active at send time; retain an unbounded backlog until each consumes or drops. | -//! | | [`watch`] | `watch` | Publish the latest state to independently tracked receivers and coalesce intermediate updates. | -//! | Resource reuse | [`pool`] | `pool` | Reuse objects through bounded or unbounded pool variants. | -//! | Concurrency limiting | [`Semaphore`](semaphore::Semaphore) | `semaphore` | Limit concurrent work by acquiring permits. | -//! | Duplicate suppression | [`Group`](singleflight::Group) | `singleflight` | Coalesce overlapping calls for the same key without caching completed results. | -//! | Sync interop | [`FutureExt`](blocking::FutureExt) | `blocking` | Drive one runtime-agnostic future from a blocking thread. | +//! | Area | API | Feature | Use | +//! |----------------------------|--------------------------------------------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------| +//! | Shared state | [`Mutex`](https://docs.rs/asyncband/*/asyncband/mutex/struct.Mutex.html) | `mutex` | Protect shared data with asynchronous mutual exclusion. | +//! | | [`RwLock`](https://docs.rs/asyncband/*/asyncband/rwlock/struct.RwLock.html) | `rwlock` | Allow multiple readers or one writer. | +//! | | [`Condvar`](https://docs.rs/asyncband/*/asyncband/condvar/struct.Condvar.html) | `condvar` | Wait for notifications while releasing a mutex. | +//! | Initialization and caching | [`Once`](https://docs.rs/asyncband/*/asyncband/once/struct.Once.html) | `once` | Complete one asynchronous initialization; cancelled or panicked attempts may be retried. | +//! | | [`OnceCell`](https://docs.rs/asyncband/*/asyncband/once/struct.OnceCell.html) | `once-cell` | Store one value from an access-time initializer; failed, cancelled, or panicked attempts may be retried. | +//! | | [`LazyCell`](https://docs.rs/asyncband/*/asyncband/once/struct.LazyCell.html) | `lazy-cell` | Initialize one value with a stored function and resume the same in-flight future after caller cancellation. | +//! | | [`OnceMap`](https://docs.rs/asyncband/*/asyncband/once/struct.OnceMap.html) | `once-map` | Cache one successfully initialized value per key until explicitly removed. | +//! | Task coordination | [`Barrier`](https://docs.rs/asyncband/*/asyncband/barrier/struct.Barrier.html) | `barrier` | Synchronize a fixed number of participants at a reusable rendezvous. | +//! | | [`Completion`](https://docs.rs/asyncband/*/asyncband/completion/struct.Completion.html) | `completion` | Publish one shared result to any number of current and future observers. | +//! | | [`ManualResetEvent`](https://docs.rs/asyncband/*/asyncband/event/struct.ManualResetEvent.html) | `event` | Signal current and future waits until explicitly reset. | +//! | | [`Latch`](https://docs.rs/asyncband/*/asyncband/latch/struct.Latch.html) | `latch` | Wait until a fixed one-way countdown reaches zero. | +//! | | [`WaitGroup`](https://docs.rs/asyncband/*/asyncband/waitgroup/struct.WaitGroup.html) | `waitgroup` | Wait until all cloned worker handles are dropped. | +//! | | [`Shutdown`](https://docs.rs/asyncband/*/asyncband/shutdown/struct.Shutdown.html) | `shutdown` | Request shutdown and wait until all completion guards are dropped. | +//! | Channels | [`oneshot`](https://docs.rs/asyncband/*/asyncband/oneshot/) | `oneshot` | Send one value from one sender to one receiver. | +//! | | [`mpsc`](https://docs.rs/asyncband/*/asyncband/mpsc/) | `mpsc` | Send each value from multiple producers to one receiver with bounded backpressure or an unbounded queue. | +//! | | [`broadcast`](https://docs.rs/asyncband/*/asyncband/broadcast/) | `broadcast` | Deliver every value to receivers active at send time; retain an unbounded backlog until each consumes or drops. | +//! | | [`watch`](https://docs.rs/asyncband/*/asyncband/watch/) | `watch` | Publish the latest state to independently tracked receivers and coalesce intermediate updates. | +//! | Resource reuse | [`pool`](https://docs.rs/asyncband/*/asyncband/pool/) | `pool` | Reuse objects through bounded or unbounded pool variants. | +//! | Concurrency limiting | [`Semaphore`](https://docs.rs/asyncband/*/asyncband/semaphore/struct.Semaphore.html) | `semaphore` | Limit concurrent work by acquiring permits. | +//! | Duplicate suppression | [`Group`](https://docs.rs/asyncband/*/asyncband/singleflight/struct.Group.html) | `singleflight` | Coalesce overlapping calls for the same key without caching completed results. | +//! | Sync interop | [`FutureExt`](https://docs.rs/asyncband/*/asyncband/blocking/trait.FutureExt.html) | `blocking` | Drive one runtime-agnostic future from a blocking thread. | //! //! # Scope and runtime model //! //! The project is not limited to small or stateless primitives. Stateful tools such as -//! [`singleflight::Group`] and the [`pool`] module fit when they provide reusable coordination and -//! remain independent of executor policy. +//! [`singleflight::Group`](https://docs.rs/asyncband/*/asyncband/singleflight/struct.Group.html) and +//! the [`pool`](https://docs.rs/asyncband/*/asyncband/pool/) module fit when they provide reusable +//! coordination and remain independent of executor policy. //! //! The async APIs do not start threads, spawn tasks, install timers, or require a runtime-specific //! reactor. Task placement, deadlines, retries, periodic maintenance, and lifecycle orchestration @@ -92,9 +93,10 @@ //! # Async first, blocking by adaptation //! //! Async and synchronous primitives have different optimization constraints. Asyncband designs its -//! primitives for async use and provides the optional [`blocking`] module as a boundary adapter -//! instead of duplicating synchronous methods across every type. Sync-first implementations can -//! exploit OS- or platform-specific facilities and remain the domain of dedicated libraries. +//! primitives for async use and provides the optional +//! [`blocking`](https://docs.rs/asyncband/*/asyncband/blocking/) module as a boundary adapter instead +//! of duplicating synchronous methods across every type. Sync-first implementations can exploit OS- +//! or platform-specific facilities and remain the domain of dedicated libraries. //! //! The adapter's single-future executor parks the calling thread and resumes it through the //! future's waker. It is not a general-purpose async runtime, and futures that depend on a diff --git a/asyncband/src/rwlock/mod.rs b/asyncband/src/rwlock/mod.rs index 36e97ca8..e58920c4 100644 --- a/asyncband/src/rwlock/mod.rs +++ b/asyncband/src/rwlock/mod.rs @@ -64,7 +64,7 @@ //! # } //! ``` //! -//! [`Mutex`]: crate::mutex::Mutex +//! [`Mutex`]: https://docs.rs/asyncband/*/asyncband/mutex/struct.Mutex.html //! [`Deref`]: std::ops::Deref //! [`DerefMut`]: std::ops::DerefMut //! [write-preferring]: https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock#Priority_policies From b61e99a0477e4a829960be1ebaa280bb75064418 Mon Sep 17 00:00:00 2001 From: tison Date: Tue, 1 Sep 2026 01:47:16 +0800 Subject: [PATCH 2/2] build: lint rustdoc for each public feature The all-features documentation build hides links that accidentally cross feature boundaries. Exercise the no-feature and every single-feature configurations so cargo x lint catches documentation that downstream users cannot build. Signed-off-by: tison --- xtask/src/main.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/xtask/src/main.rs b/xtask/src/main.rs index f84e1b63..823b3218 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -227,11 +227,17 @@ struct CommandLint { impl CommandLint { fn run(self) { + let features = asyncband_features(); + run_command(make_clippy_cmd(self.fix)); run_command(make_format_cmd(self.fix)); run_command(make_taplo_cmd(self.fix)); run_command(make_typos_cmd()); run_command(make_hawkeye_cmd(self.fix)); + run_command(make_asyncband_doc_cmd(&[])); + for feature in features.chunks(1) { + run_command(make_asyncband_doc_cmd(feature)); + } run_command(make_doc_cmd()); } } @@ -454,6 +460,23 @@ fn make_doc_cmd() -> StdCommand { cmd } +fn make_asyncband_doc_cmd(features: &[String]) -> StdCommand { + let mut cmd = find_command("cargo"); + cmd.env("RUSTDOCFLAGS", "-D warnings --cfg docsrs"); + cmd.args([ + "+nightly", + "doc", + "--package", + PACKAGE_NAME, + "--no-default-features", + "--no-deps", + ]); + for feature in features { + cmd.args(["--features", feature]); + } + cmd +} + fn make_semver_check_cmd( baseline_version: &Version, release_type: SemverReleaseType,