I've seen a few different help threads on storing a Box<Pin<...>>
closure on a struct and I have a solution which works, however I'd like to make it work in no_std environments which is not something I've come across. no_std
naturally means I lose the ability to have Box
. Here's my code that works only in std
environments which is a pretty standard affair:
use core::future::Future;
use core::pin::Pin;
struct Item;
// Why is Sync bound required?
type ReturnType<'any> = Pin<Box<dyn Future<Output = Result<(), ()>> + Sync + Send + 'any>>;
struct ItemCollection {
items: Vec<Item>,
// Why is Sync bound required?
foo: Pin<Box<dyn for<'any> Fn(&'any Item) -> ReturnType<'any> + Sync + Send>>,
}
#[tokio::main]
async fn main() {
let collection = ItemCollection {
items: vec![Item, Item],
foo: Box::pin(|_| {
Box::pin(async {
println!("Noice");
Ok(())
})
}),
};
tokio::spawn(async move {
let item: &Item = collection.items.get(0).unwrap();
(collection.foo)(item).await.ok();
})
.await
.ok();
}
My two questions:
- How do I remove
Box
fromItemCollection::foo
andReturnType
so it works in no_std? and - I never want
collection
to be able to be shared across threads, so why do I need+ Sync
in a couple of places I noted above?
The stored closure could even be fn
- I don't need to capture any other variables, but it must be possible to run this closure multiple times.
I can add more generics to ItemCollection
if necessary, but it already has quite a large type signature so it would be good if I could avoid adding more.