How to wrap async fn in loop?

Hi, I have a file call cache.rs, to wrap Redis method, I don't want Redis method everywhere:

 pub async fn get<T>(&self, key: &str) -> Result<T>
    where
        T: FromRedisValue,
    {
        let val: T = self.get_conn().await?.get(key).await?;
        Ok(val)
    }

So I can call cache.get(key), no need to import redis again. And I write an scan method like this:

 pub async fn scan_match<T, F>(&self, pattern: &str, mut func: F) -> Result<()>
    where
        T: FromRedisValue,
        F: FnMut(T),
    {
        let mut conn = self.get_conn().await?;
        let mut it = conn.scan_match::<&str, T>(pattern).await?;
        while let Some(val) = it.next_item().await {
            func(val);
        }
        Ok(())
    }

this works , I can read the val by passing an closure.

But if I need async/await , so I can save the val to db, some thing like this:

 // this can not run:
    pub async fn scan_match_async<'a, T, F>(
        &self,
        pattern: &str,
        mut func: fn(T) -> dyn Future<Output = ()>,
    ) -> Result<()>
    where
        T: FromRedisValue,
        F: FnMut(T),
    {
        let mut conn = self.get_conn().await?;
        let mut it = conn.scan_match::<&str, T>(pattern).await?;
        while let Some(val) = it.next_item().await {
            func(val).await;
        }
        Ok(())
    }

is there any good idea? Thank you!

Try something like

pub async fn scan_match_async<'a, T, F, Fut>(
    &self,
    pattern: &str,
    mut func: F,
) -> Result<()>
where
    T: FromRedisValue,
    F: FnMut(T) -> Fut,
    Fut: Future<Output = ()>,
{
    let mut conn = self.get_conn().await?;
    let mut it = conn.scan_match::<&str, T>(pattern).await?;
    while let Some(val) = it.next_item().await {
        func(val).await;
    }
    Ok(())
}

(untested)

1 Like

Thank you! this works! And I found that the 'a can be remove.

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.