У меня есть следующая структура
struct Test;
impl Test {
async fn function(&mut self) {}
}
Я хочу реализовать std::future::Future
(ну, на самом деле futures::Stream
, но это в основном то же самое) на Test
, который будет опрашивать function
. Моя первая попытка выглядела примерно так
impl Future for Test {
type Output = ();
fn poll(self: Pin<&mut self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.function() {
Poll::Pending => Poll::Pending,
Poll::Ready(_) => Poll::Ready(()),
}
}
}
Очевидно, это не сработало. Я понял, что function
должен быть вызван один раз, возвращенный Future
должен быть сохранен где-то в структуре, а затем сохраненное будущее должно быть опрошено. Итак, я попробовал это
struct Test(Option<Box<Pin<dyn Future<Output = ()>>>);
impl Test {
async fn function(&mut self) {}
fn new() -> Self {
let mut s = Self(None);
s.0 = Some(Box::pin(s.function()));
s
}
}
И, ну, не случайно это тоже не сработало
Проблема в том, что после того, как я позвонил function()
- я взял &mut
ссылка на Test
, из-за этого я не могу изменить переменную Test
, и поэтому - не могу сохранить возвращенные Future
внутри Test
.
Обновление 1:
Я пришел к самому проклятому и небезопасному решению, о котором я могу подумать (вдохновленный this )
struct Test<'a>(Option<BoxFuture<'a, ()>>);
impl Test<'_> {
async fn function(&mut self) {
println!("I'm alive!");
}
fn new() -> Self {
let mut s = Self(None);
// fuck the police
s.0 = Some(unsafe { &mut *(&mut s as *mut Self) }.function().boxed());
s
}
}
impl Future for Test<'_> {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.0.as_mut().unwrap().poll_unpin(cx)
}
}
Я ДЕЙСТВИТЕЛЬНО надеюсь, что есть другой способ