Crate almost_enough

Crate almost_enough 

Source
Expand description

§almost-enough

Batteries-included ergonomic extensions for the enough cooperative cancellation crate.

This crate provides all the concrete implementations and helpers for working with stop tokens. It re-exports everything from enough for convenience.

§Quick Start

use almost_enough::{Stopper, Stop};

let stop = Stopper::new();
let stop2 = stop.clone();  // Clone to share

// Pass to operations
assert!(!stop2.should_stop());

// Any clone can cancel
stop.cancel();
assert!(stop2.should_stop());

§Type Overview

TypeFeatureUse Case
NevercoreZero-cost “never stop”
StopSource / StopRefcoreStack-based, borrowed, zero-alloc
FnStopcoreWrap any closure
OrStopcoreCombine multiple stops
StopperallocDefault choice - Arc-based, clone to share
SyncStopperallocLike Stopper with Acquire/Release ordering
ChildStopperallocHierarchical parent-child cancellation
BoxedStopallocType-erased dynamic dispatch
WithTimeoutstdAdd deadline to any Stop

§StopExt Extension Trait

The StopExt trait adds combinator methods to any Stop implementation:

use almost_enough::{StopSource, Stop, StopExt};

let timeout = StopSource::new();
let cancel = StopSource::new();

// Combine: stop if either stops
let combined = timeout.as_ref().or(cancel.as_ref());
assert!(!combined.should_stop());

cancel.cancel();
assert!(combined.should_stop());

§Type Erasure with into_boxed()

Prevent monomorphization explosion at API boundaries:

use almost_enough::{Stopper, BoxedStop, Stop, StopExt};

fn outer(stop: impl Stop + 'static) {
    // Erase the concrete type to avoid monomorphizing inner()
    inner(stop.into_boxed());
}

fn inner(stop: BoxedStop) {
    // Only one version of this function exists
    while !stop.should_stop() {
        break;
    }
}

let stop = Stopper::new();
outer(stop);

§Hierarchical Cancellation with .child()

Create child stops that inherit cancellation from their parent:

use almost_enough::{Stopper, Stop, StopExt};

let parent = Stopper::new();
let child = parent.child();

// Child cancellation doesn't affect parent
child.cancel();
assert!(!parent.should_stop());

// But parent cancellation propagates to children
let child2 = parent.child();
parent.cancel();
assert!(child2.should_stop());

§Stop Guards (RAII Cancellation)

Automatically stop on scope exit unless explicitly disarmed:

use almost_enough::{Stopper, StopDropRoll};

fn do_work(source: &Stopper) -> Result<(), &'static str> {
    let guard = source.stop_on_drop();

    // If we return early or panic, source is stopped
    risky_operation()?;

    // Success! Don't stop.
    guard.disarm();
    Ok(())
}

fn risky_operation() -> Result<(), &'static str> {
    Ok(())
}

let source = Stopper::new();
do_work(&source).unwrap();

§Feature Flags

  • std (default) - Full functionality including timeouts
  • alloc - Arc-based types, into_boxed(), child(), StopDropRoll
  • None - Core trait and stack-based types only

Re-exports§

pub use time::TimeoutExt;
pub use time::WithTimeout;

Modules§

time
Timeout support for cancellation.

Structs§

BoxedStop
A heap-allocated Stop implementation.
CancelGuard
A guard that cancels a source when dropped, unless disarmed.
ChildStopper
A cancellation primitive with tree-structured parent-child relationships.
FnStop
A Stop implementation backed by a closure.
Never
A Stop implementation that never stops.
OrStop
Combines two Stop implementations.
StopRef
A borrowed reference to a StopSource.
StopSource
A stack-based cancellation source.
Stopper
A cancellation primitive with unified clone semantics.
SyncStopper
A cancellation primitive with Release/Acquire memory ordering.

Enums§

StopReason
Why an operation was stopped.

Traits§

Cancellable
Trait for types that can be stopped/cancelled.
Stop
Cooperative cancellation check.
StopDropRoll
Extension trait for creating CancelGuards.
StopExt
Extension trait providing ergonomic combinators for Stop implementations.