#![no_std]
pub mod executor;
pub mod helpers;
pub mod task;
pub(crate) mod sbox;
#[cfg(test)]
mod test {
use super::executor::Executor;
use super::task::Task;
use core::future::Future;
use core::iter::zip;
use core::pin::Pin;
use core::task::{Context, Poll};
const TASK_ARRAY_SIZE: usize = 256;
struct MyTestFuture(bool);
impl MyTestFuture {
const fn default() -> Self {
Self(false)
}
}
impl Future for MyTestFuture {
type Output = u8;
fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
self.get_mut().0 = true;
Poll::Ready(42u8)
}
}
#[test]
fn test_one_future() {
let mut executor = Executor::<TASK_ARRAY_SIZE>::new();
let mut task = Task::new("my_test_task", MyTestFuture::default());
let mut handle = task.create_handle();
let result = executor.spawn(&mut task, &mut handle);
assert!(result.is_ok());
executor.run();
assert!(handle.value.is_some_and(|v| v == 42u8));
}
#[test]
fn test_multiple_futures() {
let mut task_array =
[const { Task::new_nameless(MyTestFuture::default()) }; TASK_ARRAY_SIZE];
let mut handles = [(); TASK_ARRAY_SIZE].map(|()| task_array[0].create_handle());
let mut executor = Executor::<TASK_ARRAY_SIZE>::new();
for (task, handle) in zip(&mut task_array, &mut handles) {
let result = executor.spawn(task, handle);
assert!(result.is_ok(), "Failed to spawn task");
}
executor.run();
for handle in &handles {
assert!(
handle.value.is_some_and(|v| v == 42),
"Task did not complete with expected value"
);
}
}
#[test]
fn test_schedule_too_many_tasks() {
let mut task_array =
[const { Task::new_nameless(MyTestFuture::default()) }; TASK_ARRAY_SIZE + 1];
let mut handles = [(); TASK_ARRAY_SIZE].map(|()| task_array[0].create_handle());
let mut executor = Executor::<TASK_ARRAY_SIZE>::new();
for (i, (task, handle)) in zip(&mut task_array, &mut handles).enumerate() {
let result = executor.spawn(task, handle);
if i < TASK_ARRAY_SIZE {
assert!(result.is_ok());
} else {
assert!(result.is_err());
}
}
}
#[test]
fn test_different_return_type_tasks() {
let mut task1 = Task::new("task1", async { 1u32 });
let mut handle1 = task1.create_handle();
let mut task2 = Task::new("task1", async {
if false {
return Err(());
}
Ok(2u32)
});
let mut handle2 = task2.create_handle();
let mut executor = Executor::<TASK_ARRAY_SIZE>::new();
let result = executor.spawn(&mut task1, &mut handle1);
assert!(result.is_ok());
let result = executor.spawn(&mut task2, &mut handle2);
assert!(result.is_ok());
executor.run();
assert_eq!(handle1.value, Some(1u32));
assert_eq!(handle2.value, Some(Ok(2u32)));
}
}