dewit 0.0.1

Define scheduling and execution of code separately from data flow
Documentation
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`](crate::task::Task)
with defined inputs and outputs, then request a specific execution mode.

```rust
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`](https://crates.io/crates/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`](crate::mode::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`]crate::mode::Mode, [`Async`]crate::mode::runtime::Async.
* `blocking` (enables `alloc`, `std`): Provides an implementation of a blocking
  [`Mode`]crate::mode::Mode, [`Blocking`]crate::mode::runtime::Blocking.
* `rayon` (enables `alloc`, `std`): Provides implementations of work-stealing,
  [`ScopedRayon`]crate::mode::runtime::ScopedRayon and
  [`Rayon`]crate::mode::runtime::Rayon. When `blocking` is enabled, additional
  blocking versions of these will be available.