Store async callback

Hello :slight_smile: ,

How would i store these functions if bar and lorem were async?

struct Foo {
    one: Box<dyn Fn() -> i64>,
    two: Box<dyn Fn() -> i32>,
}

fn bar() -> i64 {
    666 as i64
}

fn lorem() -> i32 {
    777 as i32
}

fn main() {
    let foo = Foo {
        one: Box::new(bar),
        two: Box::new(lorem),
    };
    
    println!("{}", (foo.one)());
    println!("{}", (foo.two)());
}

I imagine something like this but unfortunately it doesn't work

async fn bar() -> i64 {
    666 as i64
}

async fn lorem() -> i32 {
    777 as i32
}

struct Foo {
    one: Box<dyn Fn() -> dyn Future<Output = i64>>,
    two: Box<dyn Fn() -> dyn Future<Output = i32>>,
}

#[tokio::main]
async fn main() {    
    let foo = Foo {
        one: Box::new(bar),
        two: Box::new(lorem),
    };
    
    println!("{}", (foo.one)().await);
    println!("{}", (foo.two)().await);
}

Thank you :slight_smile:

For the same reason you need to Box the Fn() -> ..., you also need to Box the Future<...> as well.

as castings here are unnecessary. The Rust compiler can infer the type of the integer literal.

You wouldn't. This doesn't work for the same reason recursive async functions wouldn't work.

And you need to apply the same logic you apply when dealing with these these: wrap async block in the sync glue code.

use futures::future::BoxFuture;

async fn bar() -> i64 {
    666 as i64
}

async fn lorem() -> i32 {
    777 as i32
}

struct Foo {
    one: Box<dyn Fn() -> BoxFuture<'static, i64>>,
    two: Box<dyn Fn() -> BoxFuture<'static, i32>>,
}

#[tokio::main]
async fn main() {    
    let foo = Foo {
        one: Box::new(|| Box::pin(bar())),
        two: Box::new(|| Box::pin(lorem())),
    };
    
    println!("{}", (foo.one)().await);
    println!("{}", (foo.two)().await);
}
3 Likes

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.