Add methods to Future to peek its data

How to put a Future that borrows &mut Data and an owned value of Data in the same struct?

struct Data(u8);
struct FutureWrapper<F, D>(F, D);
fn main() {
    let data = Data(1);
    let data_mut = data.borrow_mut();
    let f = async { 
        data_mut += 1; 
        // a bunch of other async stuff
        // ...
        // ...
        data.mut += 100; 
     };
    
    let wrapper = FutureWrapper(f, data);
}

I figured they live and die in the same object. Maybe the order in which they are dropped matters? Maybe because either field can be mutated and invalidated? What concessions do I need to allow this?

Maybe there is a better way, so here is why I am doing this.

trait Controlled: Future {
    fn continue_or_not(self: Box<Self>) -> Option<Box<dyn Controlled<Output = Self::Output>>>;
}

impl<F: Future + Unpin, D: Unpin> Future for FutureWrapper<F, D> {
    type Output = F::Output;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        self.0.poll_unpin(cx)
    }
}

impl<F: Future + Unpin> Task for FutureWrapper<F, Data> 
where 
    FutureWrapper<F, Data>: Future
{
    fn continue_or_not(self: Box<Self>) -> Option<Box<dyn Controlled<Output = Self::Output>>> {
        if self.1.0 > 0 {
            Some(self)
        } else {
            None
        }
    }
}

So I want a Future that when it is in-between .await calls, I can call continue_or_not on it or some other flavor of intermediate method to either cancel & drop the Future or produce another one (that also impls Controlled) or continue with the same one.

fn foo<F: Future>(f: FutureWrapper<F, Data>) {
    let x = select! {
        _ = sleep(Duration::from_millis(1000)) => None,
        x = (&mut f).await => Some(x),
     };

     if let None = x {
         let new_f = f.continue_or_not();
         // etc etc
     }
}

I guess this comes down to creating a struct with fields that reference each other.

struct Struct<T>(&T, T);

fn foo() {
    let t = u8;
    Struct(&t, t); // error
}

This is called a self-referential type, and you can't do this in safe Rust. You should break up your type into owning and borrowing parts instead.

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.