Skip to content

Instantly share code, notes, and snippets.

@ithinuel
Created July 20, 2020 22:33
Show Gist options
  • Save ithinuel/5d6c9974bda40ad2053b519f0ad1ec4f to your computer and use it in GitHub Desktop.
Save ithinuel/5d6c9974bda40ad2053b519f0ad1ec4f to your computer and use it in GitHub Desktop.
fiddling with async parser and streams
use futures::future::{ FutureExt}; // 0.3.5
use futures::stream::{self, Stream, StreamExt}; // 0.3.5
use futures::executor::block_on;
use pin_project::pin_project; // 0.4.22
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
#[pin_project]
struct PendOnce {
v: char,
polled_before: bool,
}
impl Future for PendOnce {
type Output = char;
fn poll(self: Pin<&mut Self>, c: &mut Context) -> Poll<Self::Output> {
let this = self.project();
if *this.polled_before || !"aeiouy".contains(*this.v) {
Poll::Ready(*this.v)
} else {
*this.polled_before = true;
c.waker().wake_by_ref();
Poll::Pending
}
}
}
#[derive(Debug)]
#[allow(dead_code)]
enum Foo {
Foo,
Bar,
}
#[derive(Debug)]
#[allow(dead_code)]
enum Bar {
Foob,
Barf,
}
async fn parse_next<S>(mut input: Pin<&mut S>) -> Result<char, Bar>
where
S: stream::Stream<Item = char>,
{
loop {
let c = input.next().await.ok_or(Bar::Foob)?;
println!("{:?}", c);
if !"aeiouy".contains(c) {
break if !c.is_ascii_uppercase() {
Ok(c)
} else {
Ok('_')
};
}
}
}
#[pin_project]
struct Parser<S> {
#[pin]
input: S,
}
impl<S> Stream for Parser<S>
where
S: stream::Stream<Item = char> + std::marker::Send,
{
type Item = Result<char, Bar>;
fn poll_next(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let this = self.project();
Future::poll(parse_next(this.input).boxed().as_mut(), ctx).map(|v| Some(v))
}
}
fn main() {
let strm = stream::iter("Helplo".chars());
let the = strm.then(|v| {
PendOnce {
v,
polled_before: false,
}
});
let mut a = Parser { input: the };
println!("1 {:?}", block_on(a.next()));
println!("2 {:?}", block_on(a.next()));
println!("3 {:?}", block_on(a.next()));
println!("4 {:?}", block_on(a.next()));
println!("5 {:?}", block_on(a.next()));
println!("6 {:?}", block_on(a.next()));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment