logo

Crate pasts

source · []
Expand description

Minimal and simpler alternative to the futures crate.

Optional Features

The std feature is enabled by default, disable it to use on no-std.

The web feature is disabled by default, enable it to use pasts within the javascript DOM.

Getting Started

Add the following to your ./Cargo.toml:

autobins = false

[[bin]]
name = "app"
path = "app/main.rs"

[dependencies]
pasts = "0.11"
# This example uses async-std for a sleep future, but async-std is *not*
# required to use pasts.
async-std = "1.11"

# Use web feature when compiling to wasm32-unknown-unknown
[target.'cfg(all(target_arch="wasm32",target_os="unknown"))'.dependencies]
pasts = { version = "0.11", features = ["web"] }
wasm-bindgen = "0.2"

Create ./app/main.rs:

// Shim for providing async main and handling platform-specific API differences
extern crate alloc;

#[allow(unused_imports)]
use self::main::*;

mod main {
    include!("../src/main.rs");

    #[allow(clippy::module_inception)]
    pub(super) mod main {
        pub(in super::super) async fn main(executor: pasts::Executor) {
            super::main(&executor).await
        }
    }
}

#[cfg_attr(
    all(target_arch = "wasm32", target_os = "none"),
    wasm_bindgen(start)
)]
pub fn main() {
    let executor = pasts::Executor::default();
    executor.spawn(Box::pin(self::main::main::main(executor.clone())));
}

Multi-Tasking On Multiple Iterators of Futures

This example runs two timers in parallel using the async-std crate counting from 0 to 6. The “one” task will always be run for count 6 and stop the program, although which task will run for count 5 may be either “one” or “two” because they trigger at the same time.

use core::time::Duration;

use async_std::task::sleep;
use pasts::{prelude::*, Join, Loop};

// Exit type for State.
struct Exit;

// Shared state between tasks on the thread.
struct State<'a> {
    counter: usize,
    one: &'a mut (dyn Notifier<Event = ()> + Unpin),
    two: &'a mut (dyn Notifier<Event = ()> + Unpin),
}

impl State<'_> {
    fn one(&mut self, _: ()) -> Poll<Exit> {
        println!("One {}", self.counter);
        self.counter += 1;

        if self.counter > 6 { Ready(Exit) } else { Pending }
    }

    fn two(&mut self, _: ()) -> Poll<Exit> {
        println!("Two {}", self.counter);
        self.counter += 1;

        Pending
    }
}

async fn main(_executor: &Executor) {
    let sleep = |seconds| sleep(Duration::from_secs_f64(seconds));
    let one = &mut Loop::pin(|| sleep(1.0));
    let two = &mut Loop::pin(|| sleep(2.0));
    let counter = 0;
    let mut state = State { counter, one, two };

    Join::new(&mut state)
        .on(|s| s.one, State::one)
        .on(|s| s.two, State::two)
        .await;
}

Modules

Items that are almost always needed.

Structs

An executor.

Composable asynchronous event loop.

A Notifier created from a function returning Futures.

A Notifier created from a function returning Poll.

Traits

Trait for “fusing” a Future (conversion to a Notifier).

Trait for asynchronous event notification.

The implementation of sleeping for an Executor.

Type Definitions

Task without the Send requirement.

An owned dynamically typed Notifier for use in cases where you can’t statically type your result or need to add some indirection.