How to solve the life cycle problem caused by using asynchronous and referential parameters in closures

use once_cell::sync::OnceCell;
use std::sync::RwLock;
use futures::Future;

static CONFIG: OnceCell<RwLock<Option<Config>>> = OnceCell::new();
#[derive(Default, Debug)]
struct Config {
    id: u64,
}

fn load() -> &'static RwLock<Option<Config>> {
    CONFIG.get_or_init(|| {
        RwLock::new(Some(Config::default()))
    })
}

fn with_config<T, F>(f: F) -> T
where
    F: FnOnce(Option<&Config>) -> T,
{
    f(load().read().unwrap().as_ref())
}
// how to support async F 
// TODO
fn async_with_config<T, F, Fut>(f: F) -> Fut
where
    F: FnOnce(Option<&Config>) -> Fut,
    Fut: Future<Output = T>,
{
    f(load().read().unwrap().as_ref())
}
    

#[tokio::main]
async fn main() {
    with_config(|c| println!("config: {:?}", c));
    // TODO
    async_with_config(|c| async move {
        print_config(c).await;
    });
    
}

async fn print_config(c: Option<&Config>) {
    println!("config: {:?}", c)
}

Rust Playground

   Compiling playground v0.0.1 (/playground)
error: lifetime may not live long enough
  --> src/main.rs:39:23
   |
39 |     async_with_config(async move |c| {
   |                       ^^^^^^^^^^^^--
   |                       |           ||
   |                       |           |return type of closure `[async closure body@src/main.rs:39:38: 41:6]` contains a lifetime `'2`
   |                       |           has type `Option<&'1 Config>`
   |                       returning this value requires that `'1` must outlive `'2`

error: could not compile `playground` due to previous error
Standard Output

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.