use core::{ cell::Cell, pin::{pin, Pin}, task::{Context, Poll}, }; use event_iterator::EventIterator; /// An event iterator, for printing to stdout #[derive(Default)] pub struct Stdout { buffer: Cell>, } impl EventIterator for Stdout { type Event<'me> = Buffer<'me>; fn poll_next( self: Pin<&Self>, _cx: &mut Context<'_>, ) -> Poll>> { let this = self.get_ref(); // Print last buffer contents if set, set if unset this.buffer.set(if let Some(buffer) = this.buffer.take() { // This could be an asynchronous operation // Left synchronous for example simplicity println!("{buffer}"); // Reuse buffer Some(buffer) } else { Some(String::new()) }); Poll::Ready(Some(Buffer(&this.buffer))) } } pub struct Buffer<'a>(&'a Cell>); impl Buffer<'_> { pub fn write(&self, text: &str) { self.0.set(self.0.take().map(|mut buf| { buf.replace_range(.., text); buf })); } } #[async_main::async_main] async fn main(_spawner: async_main::LocalSpawner) { let stdout = Stdout::default(); // Overwrite buffer with text to print stdout.next_unpinned().await.unwrap().write("Hello, world!"); stdout.next_unpinned().await.unwrap().write("Hello, again!"); // Once more, to use the previous buffer contents let flush = pin!(stdout); flush.as_ref().next().await.unwrap(); }