diff --git a/crates/egui_inbox/src/lib.rs b/crates/egui_inbox/src/lib.rs index 2b769c8..f752cc9 100644 --- a/crates/egui_inbox/src/lib.rs +++ b/crates/egui_inbox/src/lib.rs @@ -309,13 +309,14 @@ impl UiInbox { #[cfg(feature = "async")] mod async_impl { - use std::pin::pin; + use std::pin::{pin, Pin}; + use std::task::{Context, Poll}; - use futures::{select, FutureExt}; + use futures::{select, FutureExt, Sink, SinkExt, StreamExt}; use hello_egui_utils::spawn; - use crate::{UiInbox, UiInboxSender}; + use crate::{SendError, UiInbox, UiInboxSender}; impl UiInbox { /// Spawns a future that will automatically be cancelled when the inbox is dropped. @@ -352,6 +353,47 @@ mod async_impl { spawn(future); } } + + impl UiInboxSender { + /// Send each item of a stream to the inbox, as they come in. + pub async fn send_stream( + &mut self, + stream: impl futures::Stream + Send + 'static, + ) -> Result<(), SendError> { + let stream = stream.map(|i| Ok(i)); + let mut stream = pin!(stream); + self.send_all(&mut stream).await + } + } + + impl Sink for UiInboxSender { + type Error = SendError; + + fn poll_ready( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + + fn start_send(self: Pin<&mut Self>, item: T) -> Result<(), Self::Error> { + UiInboxSender::send(&self, item) + } + + fn poll_flush( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_close( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } + } } impl UiInboxSender {