I'm trying to pass a function pointer as a callback function in a parameter, here's a stripped example from my code so far:
use std::{
fs::File,
io::{self, BufRead, BufReader},
path::Path,
};
use futures::{executor, Future}; // 0.3.8
type DigestCallback<R> = fn(&[u8]) -> R;
async fn consume<T>(
path: T,
chunk_size: usize,
digest: DigestCallback<impl Future<Output = ()>>,
) -> io::Result<()>
where
T: AsRef<Path>,
{
let file = File::open(path)?;
let mut reader = BufReader::with_capacity(chunk_size, file);
loop {
let buffer = reader.fill_buf()?;
let length = buffer.len();
if length == 0 {
break;
}
digest(buffer).await;
reader.consume(length);
}
Ok(())
}
async fn digest_callback(chunk: &[u8]) -> () {
()
}
fn main() {
executor::block_on(consume("my_file.bin", 64, digest_callback));
}
and I'm getting this error
error[E0308]: mismatched types
--> src/main.rs:41:51
|
36 | async fn digest_callback(chunk: &[u8]) -> () {
| -- the `Output` of this `async fn`'s found opaque type
...
41 | executor::block_on(consume("my_file.bin", 64, digest_callback));
| ^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected fn pointer `for<'r> fn(&'r [u8]) -> impl futures::Future`
found fn pointer `for<'_> fn(&[u8]) -> impl futures::Future`
It works when I make it into a Vec<u8>
but I'm worried about performance issues since I'm processing potentially huge files. Can someone help me understand what I'm doing wrong? How am I supposed to do this in Rust? Is there a better way of achieving this?
Update:
If I remove Future
and async functions, and change the function type to type DigestCallback = for<'a> fn(&'a [u8]) -> ();
It seems to work. Don't know how to make it work with asynchronous functions yet though
use std::{
fs::File,
io::{self, BufRead, BufReader},
path::Path,
};
type DigestCallback = for<'a> fn(&'a [u8]) -> ();
fn consume<T>(
path: T,
chunk_size: usize,
digest: DigestCallback,
) -> io::Result<()>
where
T: AsRef<Path>,
{
let file = File::open(path)?;
let mut reader = BufReader::with_capacity(chunk_size, file);
loop {
let buffer = reader.fill_buf()?;
let length = buffer.len();
if length == 0 {
break;
}
digest(buffer);
reader.consume(length);
}
Ok(())
}
fn digest_callback(_chunk: &[u8]) -> () {()}
fn main() {
let _ = consume("my_file.bin", 64, digest_callback);
}