v0.4.1 — Stop::may_stop() and impl Stop for Option<T>
What's New
Stop::may_stop() — runtime no-op detection
New default method on the Stop trait. Returns true for real stop sources, false for Unstoppable. Lets callers behind dyn Stop skip check overhead in hot loops.
impl Stop for Option<T: Stop>
None is a no-op (check() always returns Ok(())), Some(inner) delegates. Combined with may_stop(), this enables:
fn process(stop: &dyn Stop) -> Result<(), StopReason> {
let stop = stop.may_stop().then_some(stop); // Option<&dyn Stop>
for chunk in data.chunks(1024) {
stop.check()?; // None → Ok(()), Some → one vtable dispatch
}
Ok(())
}BoxedStop::active_stop() — indirection collapsing
New inherent method returns Option<&dyn Stop> pointing directly at the concrete type inside the box, bypassing the BoxedStop wrapper. Eliminates one vtable dispatch per check() in hot loops.
OrStop composition
OrStop::may_stop() returns false only when both halves are no-ops (e.g., OrStop<Unstoppable, Unstoppable>).
Compatibility
All changes are additive with default implementations. Fully semver-compatible — no downstream code changes required.
Crates
enough0.4.1almost-enough0.4.1enough-ffi0.4.0 (compatible, gainsmay_stop()via dep update)enough-tokio0.5.0 (compatible, gainsmay_stop()via dep update)