Created
July 20, 2020 22:33
-
-
Save ithinuel/5d6c9974bda40ad2053b519f0ad1ec4f to your computer and use it in GitHub Desktop.
fiddling with async parser and streams
This file contains 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 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