Hello,
Here is my code:
use std::{
future::Future,
pin::Pin,
sync::{Arc, Mutex},
};
use async_trait::async_trait;
fn main() {}
pub fn main_sync(
ob: &impl ObImpl,
path: String,
value: Arc<Value>,
) -> Arc<Mutex<dyn FnMut(&dyn ObImpl, String, Arc<Value>) + Send + Sync>> {
Arc::new(Mutex::new(
move |ob: &dyn ObImpl, path: String, value: Arc<Value>| {},
))
}
pub async fn main_async(
ob: &impl ObImplAsync,
path: String,
value: Arc<Value>,
) -> Arc<
Mutex<
Box<
dyn FnOnce(
&'static dyn ObImplAsync,
String,
Arc<Value>,
) -> Pin<Box<dyn Future<Output = ()>>>
+ Send
+ Sync,
>,
>,
> {
Arc::new(Mutex::new(Box::new(
move |ob: &'static dyn ObImplAsync, path: String, value: Arc<Value>| {
Box::pin(async move {}) as Pin<Box<dyn Future<Output = ()>>>
},
)))
}
pub trait ObImpl {
fn syncfn(&self, path: String, value: Arc<Value>) -> Option<Arc<Value>>;
}
#[async_trait]
pub trait ObImplAsync {
async fn asyncfn(&self, path: String, value: Arc<Value>) -> Option<Arc<Value>>;
}
pub struct Value {
a: i32,
}
pub struct Ob {
fn_sync:
Arc<Mutex<Option<Arc<Mutex<dyn FnMut(&dyn ObImpl, String, Arc<Value>) + Send + Sync>>>>>,
fn_async: Arc<
Mutex<
Option<
Arc<
Mutex<
Box<
dyn FnOnce(
&'static dyn ObImplAsync,
String,
Arc<Value>,
)
-> Pin<Box<dyn Future<Output = ()>>>,
>,
>,
>,
>,
>,
>,
}
impl ObImplAsync for Ob {
#[must_use]
#[allow(
elided_named_lifetimes,
clippy::type_complexity,
clippy::type_repetition_in_bounds
)]
fn asyncfn<'life0, 'async_trait>(
&'life0 self,
path: String,
value: Arc<Value>,
) -> ::core::pin::Pin<
Box<
dyn ::core::future::Future<Output = Option<Arc<Value>>>
+ ::core::marker::Send
+ 'async_trait,
>,
>
where
'life0: 'async_trait,
Self: 'async_trait,
{
todo!()
}
}
impl Ob {
fn fn_async<'life0>(
&'static self,
path: String,
value: Arc<Value>,
) -> Pin<Box<dyn Future<Output = Option<Arc<Value>>> + Send>>
where
'life0: 'life0,
Self: 'static,
{
let fn_async = self.fn_async.clone();
let a = fn_async.as_ref().lock().unwrap();
let b = a.as_ref().take().unwrap();
let c = b.lock();
let d = c.unwrap();
let e = d.as_ref();
let f = e(self, path, value); // error there
Box::pin(async { None })
}
}
I am trying to convert my sync code to async.
While the compiler helps by automagically transform dynamic sync function, it doesn't seem to be clever enough (for now) to manage dyn trait when switching to async.
The error is : cannot move out of *e
which is behind a shared reference
move occurs because *e
has type dyn std::ops::FnOnce(&dyn ObImplAsync, std::string::String, std::sync::Arc<Value>) -> std::pin::Pin<std::boxed::Box<dyn std::future::Future<Output = ()>>>
, which does not implement the Copy
trait
How can I do to convert the same sync function to async and be able to store it in my struct ?
Thank you in advance for your help.