Skip to content

v0.4.1 — Stop::may_stop() and impl Stop for Option<T>

Choose a tag to compare

@lilith lilith released this 23 Mar 18:24
· 36 commits to main since this release

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

  • enough 0.4.1
  • almost-enough 0.4.1
  • enough-ffi 0.4.0 (compatible, gains may_stop() via dep update)
  • enough-tokio 0.5.0 (compatible, gains may_stop() via dep update)