dewit

Crates.iodewit
lib.rsdewit
version0.0.1
created_at2025-11-02 05:55:44.783389+00
updated_at2025-11-02 05:55:44.783389+00
descriptionDefine scheduling and execution of code separately from data flow
homepage
repository
max_upload_size
id1912709
size52,096
Ashlynn Levenick (lynlevenick)

documentation

https://docs.rs/dewit/

README

dewit is a library that allows the caller to control how code is scheduled and executed separately from how data flows through it.

dewit is #![no_std], no alloc, and #![forbid(unsafe_code)] by default.

Notes

Most of this is... at best semi-functional. I'm writing it on a private git forge. You should probably not use this. Hopefully a future version will be more fleshed out and less actively in flux. This is pretty heavily inspired by chumsky's approach to... everything. They do it much better.

Motivating example

dewit makes it possible to define code as a Task with defined inputs and outputs, then request a specific execution mode.

use dewit::prelude::*;
use std::{fs::File, io, path::Path};

fn recursively_count_files<'a>() -> impl Task<'a, &'a Path, io::Result<usize>> {
    // TODO: actually write this example :)
    io(async move |path: &Path| {
        tokio::time::sleep(std::time::Duration::from_secs(1)).await;
        Ok(path.as_os_str().len())
    })
}

#[tokio::main]
async fn main() -> io::Result<()> {
    let (combinator_count, mode_count) =
        // TODO: try_join
        join(
            recursively_count_files(),
            recursively_count_files(),
        )
        .run_async((Path::new("./src/combinators"), Path::new("./src/mode")))
        .await;
    assert_eq!(combinator_count?, 17);
    assert_eq!(mode_count?, 10);
    Ok(())
}

Code which embeds a requirement to use a dependency, e.g. rayon as part of its execution "leaks" the usage of rayon into its environment, when the motivation of the author may just be to execute more quickly. That can cause headaches when a consumer doesn't want to potentially use all of their CPU. Similarly, when writing code that consumes an async API, it can be a headache to write an API for both the async and non-async versions of the function when all the author wants is to block until the result is available.

Anti-motivation

An effort is made to be relatively efficient, but a hand-written implementation that uses the underlying concurrency primitives in a well-reasoned and careful way will likely be faster and use fewer resources.

Recommendations

Library dependents should avoid depending on any Mode providing features unless strictly necessary, to avoid pulling in unnecessary dependencies in client code.

Feature flags

  • alloc: Support for combinators which require allocation.

  • std: Support for standard library features in combinators and modes.

  • async (enables alloc): Provides an implementation of an async Mode, Async.

  • blocking (enables alloc, std): Provides an implementation of a blocking Mode, Blocking.

  • rayon (enables alloc, std): Provides implementations of work-stealing, ScopedRayon and Rayon. When blocking is enabled, additional blocking versions of these will be available.

Commit count: 0

cargo fmt