Crate almost_enough

Crate almost_enough 

Source
Expand description

§almost-enough

Cooperative cancellation for Rust. Cancel long-running operations from another thread.

§Which Crate?

  • Application code: Use almost-enough (this crate) - has all implementations
  • Library code: Depend on enough (minimal) and accept impl Stop

§Complete Example

use almost_enough::{Stopper, Stop};
use std::thread;
use std::time::Duration;

// 1. Create a stopper
let stop = Stopper::new();

// 2. Clone and pass to worker thread
let worker_stop = stop.clone();
let handle = thread::spawn(move || {
    for i in 0..1000 {
        // 3. Check periodically - exit early if cancelled
        if worker_stop.should_stop() {
            return Err("cancelled");
        }
        // ... do work ...
    }
    Ok("completed")
});

// 4. Cancel from main thread (or signal handler, timeout, etc.)
thread::sleep(Duration::from_millis(1));
stop.cancel();

// Worker exits early
let result = handle.join().unwrap();
// result is either Ok("completed") or Err("cancelled")

§Quick Reference

let stop = Stopper::new();
stop.cancel();              // Trigger cancellation
stop.should_stop();         // Returns true if cancelled
stop.check()?;              // Returns Err(StopReason) if cancelled

§Type Overview

TypeFeatureUse Case
UnstoppablecoreZero-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.
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.
Unstoppable
A Stop implementation that never stops (no cooperative cancellation).

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.

Type Aliases§

NeverDeprecated
Type alias for backwards compatibility.