Last active
May 9, 2020 15:55
-
-
Save cchudant/c5ce721966d2bc1847a0df466d2e4391 to your computer and use it in GitHub Desktop.
Async await desugar (kind of)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async fn unicorn(arg: i32) { | |
println!("Hi!"); | |
do_things().await; | |
println!("Hi x2!"); | |
for i in arg..5 { | |
let num = do_other_things().await; | |
println!("Future {} returned {}!", i, num); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::task::{Poll, Context}; | |
use std::pin::Pin; | |
use std::future::Future; | |
use std::ops::Range; | |
enum UnicornFuture { | |
Begin { arg: i32 }, | |
YieldPoint1 { arg: i32, doThingFuture: DoThingFuture }, | |
YieldPoint2 { i: i32, range: Range<i32>, doOtherFuture: DoOtherFuture }, | |
Completed | |
} | |
impl Future for UnicornFuture { | |
type Output = (); | |
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> { | |
let unpinned = Pin::into_inner(self); | |
loop { | |
return match unpinned { | |
UnicornFuture::Begin { arg } => { | |
println!("Hi!"); | |
*unpinned = UnicornFuture::YieldPoint1 { | |
arg: *arg, | |
doThingFuture: do_things(), | |
}; | |
Poll::Pending | |
}, | |
UnicornFuture::YieldPoint1 { arg, doThingFuture } => { | |
match Pin::new(doThingFuture).poll(cx) { | |
Poll::Pending => Poll::Pending, | |
Poll::Ready(_) => { | |
println!("Hi x2!"); | |
let range = (*arg)..5; | |
match range.next() { | |
Some(n) => { | |
*unpinned = UnicornFuture::YieldPoint2 { | |
i: n, | |
range, | |
doOtherFuture: do_other_things(), | |
}; | |
continue; | |
}, | |
None => { | |
*unpinned = UnicornFuture::Completed; | |
Poll::Ready(()) | |
}, | |
} | |
}, | |
} | |
}, | |
UnicornFuture::YieldPoint2 { i, range, doOtherFuture } => { | |
match Pin::new(doOtherFuture).poll(cx) { | |
Poll::Pending => Poll::Pending, | |
Poll::Ready(num) => { | |
println!("Future {} returned {}!", i, num); | |
match range.next() { | |
Some(n) => { | |
*unpinned = UnicornFuture::YieldPoint2 { | |
i: n, | |
range: *range, | |
doOtherFuture: do_other_things(), | |
}; | |
continue; | |
}, | |
None => { | |
*unpinned = UnicornFuture::Completed; | |
Poll::Ready(()); | |
}, | |
} | |
} | |
} | |
}, | |
UnicornFuture::Completed => panic!("Poll after ready!") | |
} | |
} | |
} | |
} | |
fn unicorn(arg: i32) -> impl Future<Output=()> { | |
UnicornFuture::Begin { arg } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn unicorn(arg: i32) -> impl Generator<&mut Context, Yield=(), Return=()> { | |
|mut cx: &mut Context| { | |
println!("Hi!"); | |
let doThingsFuture = do_things(); | |
loop { | |
match Pin::new(doThingsFuture).poll(cx) { | |
// or `match Pin::new(doThingsFuture).resume(cx)` | |
Poll::Pending => cx = yield, | |
Poll::Ready(_) => break, | |
} | |
} | |
println!("Hi x2!"); | |
for i in arg..5 { | |
let doOtherFuture = do_other_things(); | |
let num = loop { | |
match Pin::new(doOtherFuture).poll(cx) { | |
// or `match Pin::new(doOtherFuture).resume(cx)` | |
Poll::Pending => cx = yield, | |
Poll::Ready(num) => break num, | |
} | |
}; | |
println!("Future {} returned {}!", i, num); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment