I have an async function save
that has a Save
struct as argument which optionally contains an async function (validator
). The problem is that the following code only works when Some(..)
is specified, with None
the compiler throws an error.
use std::future::Future;
trait SomeTrait {}
enum SomeError {}
#[derive(Debug)]
struct User {}
impl SomeTrait for User {}
struct Save<T, F>
where
T: SomeTrait,
F: Future<Output = Result<(), SomeError>>,
{
pub validator: Option<Box<dyn Fn(&T) -> F>>,
}
async fn save<T, F>(obj: &T, args: Save<T, F>) -> Result<(), SomeError>
where
T: SomeTrait,
F: Future<Output = Result<(), SomeError>>,
{
if let Some(v) = args.validator {
(*v)(obj).await?;
}
Ok(())
}
#[tokio::test]
async fn test_func() {
let user = User {};
save(&user, Save { validator: None }).await;
save(
&user,
Save {
validator: Some(Box::new(|obj| async {
println!("input: {:?}", obj);
Ok(())
})),
},
)
.await;
}
The error:
error[E0698]: type inside `async` block must be known in this context
--> test_utils/src/testin.rs:35:17
|
35 | save(&user, Save { validator: None }).await;
| ^^^^ cannot infer type for type parameter `F` declared on the struct `Save`
|
note: the type is part of the `async` block because of this `await`
--> test_utils/src/testin.rs:35:5
|
35 | save(&user, Save { validator: None }).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
How can I make the above code work? Is there an alternative implementation without the use of the F
generic parameter in the Save
struct? I can work with it for now, but might become unwieldy when there are multiple functions in the Save
struct.