use std::{
io,
rc::Rc,
};
use qubit_function::{
BoxCallable,
BoxCallableWith,
BoxRunnable,
BoxRunnableWith,
Callable,
CallableWith,
LocalBoxCallable,
LocalBoxCallableWith,
LocalBoxRunnable,
LocalBoxRunnableWith,
Runnable,
RunnableWith,
};
#[cfg(feature = "once")]
use qubit_function::{
BoxCallableOnce,
BoxRunnableOnce,
CallableOnce,
LocalBoxCallableOnce,
LocalBoxRunnableOnce,
RunnableOnce,
};
fn require_send<T: Send>(value: T) -> T {
value
}
#[test]
fn test_task_box_compositions_remain_send() {
let mut callable = require_send(
BoxCallable::new(|| Ok::<i32, io::Error>(20))
.map(|value| value + 1)
.and_then(|value| Ok(value * 2)),
);
assert_eq!(callable.call().expect("callable should succeed"), 42);
let mut runnable = require_send(
BoxRunnable::new(|| Ok::<(), io::Error>(()))
.and_then(|| Ok::<(), io::Error>(())),
);
runnable.run().expect("runnable should succeed");
}
#[test]
fn test_task_box_with_compositions_remain_send() {
let mut callable = require_send(
BoxCallableWith::new(|value: &mut i32| {
*value += 1;
Ok::<i32, io::Error>(*value)
})
.map(|value| value * 2)
.and_then(|value, input| {
*input += 1;
Ok(value + *input)
}),
);
let mut input = 20;
assert_eq!(
callable
.call_with(&mut input)
.expect("callable-with should succeed"),
64
);
let mut runnable = require_send(
BoxRunnableWith::new(|value: &mut i32| {
*value += 1;
Ok::<(), io::Error>(())
})
.and_then(|value: &mut i32| {
*value *= 2;
Ok::<(), io::Error>(())
}),
);
let mut input = 20;
runnable
.run_with(&mut input)
.expect("runnable-with should succeed");
assert_eq!(input, 42);
}
#[cfg(feature = "once")]
#[test]
fn test_task_box_once_compositions_remain_send() {
let callable = require_send(
BoxCallableOnce::new(|| Ok::<i32, io::Error>(20))
.map(|value| value + 1)
.and_then(|value| Ok(value * 2)),
);
assert_eq!(
callable.call_once().expect("callable-once should succeed"),
42,
);
let runnable = require_send(
BoxRunnableOnce::new(|| Ok::<(), io::Error>(()))
.and_then(|| Ok::<(), io::Error>(())),
);
runnable.run_once().expect("runnable-once should succeed");
}
#[test]
fn test_local_task_box_compositions_accept_rc_captures() {
let suffix = Rc::new(String::from("-local"));
let callable_suffix = Rc::clone(&suffix);
let mut callable = LocalBoxCallable::new(|| {
Ok::<String, io::Error>(String::from("callable"))
})
.map(move |value| format!("{value}{callable_suffix}"));
assert_eq!(
callable.call().expect("local callable should succeed"),
"callable-local"
);
let runnable_suffix = Rc::clone(&suffix);
let mut runnable = LocalBoxRunnable::new(move || {
assert_eq!(runnable_suffix.as_str(), "-local");
Ok::<(), io::Error>(())
})
.and_then(|| Ok::<(), io::Error>(()));
runnable.run().expect("local runnable should succeed");
}
#[test]
fn test_local_task_box_with_compositions_accept_rc_captures() {
let offset = Rc::new(1);
let callable_offset = Rc::clone(&offset);
let mut callable = LocalBoxCallableWith::new(move |value: &mut i32| {
*value += *callable_offset;
Ok::<i32, io::Error>(*value)
})
.map(|value| value * 2);
let mut input = 20;
assert_eq!(
callable
.call_with(&mut input)
.expect("local callable-with should succeed"),
42
);
let runnable_offset = Rc::clone(&offset);
let mut runnable = LocalBoxRunnableWith::new(move |value: &mut i32| {
*value += *runnable_offset;
Ok::<(), io::Error>(())
})
.and_then(|value: &mut i32| {
*value *= 2;
Ok::<(), io::Error>(())
});
let mut input = 20;
runnable
.run_with(&mut input)
.expect("local runnable-with should succeed");
assert_eq!(input, 42);
}
#[cfg(feature = "once")]
#[test]
fn test_local_task_box_once_compositions_accept_rc_captures() {
let suffix = Rc::new(String::from("-local"));
let callable_suffix = Rc::clone(&suffix);
let callable = LocalBoxCallableOnce::new(|| {
Ok::<String, io::Error>(String::from("callable"))
})
.map(move |value| format!("{value}{callable_suffix}"));
assert_eq!(
callable
.call_once()
.expect("local callable-once should succeed"),
"callable-local"
);
let runnable_suffix = Rc::clone(&suffix);
let runnable = LocalBoxRunnableOnce::new(move || {
assert_eq!(runnable_suffix.as_str(), "-local");
Ok::<(), io::Error>(())
})
.and_then(|| Ok::<(), io::Error>(()));
runnable
.run_once()
.expect("local runnable-once should succeed");
}