Converting an async function into a trait object

Hi there Rustaceans!
Ive been attempting to implement a basic async ECS using Rust as a toy project to help me understand the subject better.
My idea is that i want to accept both simple (async) functions and complex structs as systems.
I thought this wouldnt be a problem, since i run the systems using trait objects (dynamic dispatch) anyway.
These are the basic trait definitions i have so far:

#[async_trait]
pub trait System: Send + Sync {
    type Data: SystemData;
    async fn run(&mut self, data: Self::Data);
}

#[async_trait]
impl<D: SystemData, O> System for fn(D) -> O
where O: Future<Output = ()> + Send
{
    type Data = D;
    async fn run(&mut self, data: Self::Data) {
        self(data).await
    }
}

pub trait IntoDynSystem {
    fn into_dyn_system(self) -> Box<dyn DynSystem>;
}

impl<D: SystemData + 'static, O: Future<Output = ()> + Send + 'static> IntoDynSystem for fn(D) -> O {
    fn into_dyn_system(self) -> Box<dyn DynSystem> {
        Box::new(self)
    }
}

#[async_trait]
pub trait DynSystem {
    async fn dyn_run(&mut self, world: &World);
}

#[async_trait]
impl<S: System> DynSystem for S {
    async fn dyn_run(&mut self, world: &World) {
        self.run(S::Data::fetch(world).await).await
    }
}

System itself is intended for defining the systems, while a trait object of DynSystem will be used to actually run them. However, during this basic test:

async fn run_basic_system<S: IntoDynSystem>(sys: S) {
    let system_box: Box<dyn DynSystem> = sys.into_dyn_system();
}

async fn basic_system(_args: ()) {
    println!("Basic system!");
}

#[async_std::test]
async fn test_basic_system() {
    run_basic_system(basic_system).await
}

I get a type mismatch error like this:

the trait bound `fn(()) -> impl std::future::Future<Output = ()> {basic_system}: messy_ecs::system::IntoDynSystem` is not satisfied
the following implementations were found:
  <fn(D) -> O as messy_ecs::system::IntoDynSystem>

What am i missing and/or fundamentally misunderstanding in my approach here?
Any help would be greatly appreciated. I would assume impl Future<Output = ()> would be caught by the trait constraints.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.