From 38cdd741e088154d00f22e3c0c67a67f76ddade5 Mon Sep 17 00:00:00 2001 From: laizy Date: Sun, 17 Apr 2022 11:26:45 +0800 Subject: [PATCH 1/4] add send_stream method for Scope --- packages/yew/Cargo.toml | 1 + packages/yew/src/html/component/scope.rs | 34 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/packages/yew/Cargo.toml b/packages/yew/Cargo.toml index dddf528acbc..a0e0cd4d16b 100644 --- a/packages/yew/Cargo.toml +++ b/packages/yew/Cargo.toml @@ -92,6 +92,7 @@ hydration = ["csr"] trace_hydration = ["hydration"] doc_test = ["csr", "hydration", "ssr"] wasm_test = ["csr", "hydration", "ssr"] +nightly = ["futures"] default = [] [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] diff --git a/packages/yew/src/html/component/scope.rs b/packages/yew/src/html/component/scope.rs index b83a6a2d052..40c8308fa75 100644 --- a/packages/yew/src/html/component/scope.rs +++ b/packages/yew/src/html/component/scope.rs @@ -592,6 +592,40 @@ mod feat_hydration { #[cfg(feature = "csr")] pub(crate) use feat_csr::*; +#[cfg_attr( + documenting, + doc(cfg(all(feature = "nightly", any(target_arch = "wasm32", feature = "tokio")))) +)] +#[cfg(all(feature = "nightly", any(target_arch = "wasm32", feature = "tokio")))] +mod feat_nightly { + use super::*; + use crate::io_coop::spawn_local; + use futures::{Stream, StreamExt}; + + impl Scope { + /// This method asynchronously awaits a [Stream] that returns a series of messages and sends + /// them to the linked component. + /// + /// # Panics + /// If the stream panics, then the promise will not resolve, and will leak. + pub fn send_stream(&self, stream: S) + where + M: Into, + S: Stream + 'static, + { + let link = self.clone(); + let js_future = async move { + futures::pin_mut!(stream); + while let Some(msg) = stream.next().await { + let message: COMP::Message = msg.into(); + link.send_message(message); + } + }; + spawn_local(js_future); + } + } +} + #[cfg_attr(documenting, doc(cfg(any(target_arch = "wasm32", feature = "tokio"))))] #[cfg(any(target_arch = "wasm32", feature = "tokio"))] mod feat_io { From 7a6dc5b7d7c98b25141994f32903a9ffc445fedf Mon Sep 17 00:00:00 2001 From: laizy Date: Sun, 17 Apr 2022 23:56:59 +0800 Subject: [PATCH 2/4] add eof stream note --- packages/yew/src/html/component/scope.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/yew/src/html/component/scope.rs b/packages/yew/src/html/component/scope.rs index 40c8308fa75..0925d5af55a 100644 --- a/packages/yew/src/html/component/scope.rs +++ b/packages/yew/src/html/component/scope.rs @@ -608,6 +608,15 @@ mod feat_nightly { /// /// # Panics /// If the stream panics, then the promise will not resolve, and will leak. + /// + /// # Note + /// + /// This method will not notify the component when the stream has been fully exhausted. If + /// you want this feature, you can add an EOF message variant for your component and use + /// [`StreamExt::chain`] and [`stream::once`] to chain an EOF message to the original stream. + /// + /// [`StreamExt::chain`]: https://docs.rs/futures/latest/futures/stream/trait.StreamExt.html#method.chain + /// [`stream::once`]: https://docs.rs/futures/latest/futures/stream/fn.once.html pub fn send_stream(&self, stream: S) where M: Into, From 0de9e5549e345acdc77b4362392c0003d4047ae6 Mon Sep 17 00:00:00 2001 From: laizy Date: Mon, 18 Apr 2022 00:08:32 +0800 Subject: [PATCH 3/4] map stream item type --- packages/yew/src/html/component/scope.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/yew/src/html/component/scope.rs b/packages/yew/src/html/component/scope.rs index 0925d5af55a..619cb8b2b6e 100644 --- a/packages/yew/src/html/component/scope.rs +++ b/packages/yew/src/html/component/scope.rs @@ -614,9 +614,12 @@ mod feat_nightly { /// This method will not notify the component when the stream has been fully exhausted. If /// you want this feature, you can add an EOF message variant for your component and use /// [`StreamExt::chain`] and [`stream::once`] to chain an EOF message to the original stream. + /// If your stream is produced by another crate, you can use [`StreamExt::map`] to transform + /// the stream's item type to the component message type. /// /// [`StreamExt::chain`]: https://docs.rs/futures/latest/futures/stream/trait.StreamExt.html#method.chain /// [`stream::once`]: https://docs.rs/futures/latest/futures/stream/fn.once.html + /// [`StreamExt::map`]: https://docs.rs/futures/latest/futures/stream/trait.StreamExt.html#method.map pub fn send_stream(&self, stream: S) where M: Into, From 7239dd63731a2625e476d359c562411be72cd0ea Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Sun, 28 Aug 2022 22:42:03 +0500 Subject: [PATCH 4/4] No need for nightly, fmt, updates --- packages/yew/src/html/component/scope.rs | 73 ++++++++++-------------- 1 file changed, 31 insertions(+), 42 deletions(-) diff --git a/packages/yew/src/html/component/scope.rs b/packages/yew/src/html/component/scope.rs index e2c56104fa6..89645698e28 100644 --- a/packages/yew/src/html/component/scope.rs +++ b/packages/yew/src/html/component/scope.rs @@ -7,6 +7,8 @@ use std::ops::Deref; use std::rc::Rc; use std::{fmt, iter}; +use futures::{Stream, StreamExt}; + #[cfg(any(feature = "csr", feature = "ssr"))] use super::lifecycle::ComponentState; use super::BaseComponent; @@ -236,6 +238,35 @@ impl Scope { spawn_local(js_future); } + /// This method asynchronously awaits a [`Stream`] that returns a series of messages and sends + /// them to the linked component. + /// + /// # Panics + /// If the stream panics, then the promise will not resolve, and will leak. + /// + /// # Note + /// + /// This method will not notify the component when the stream has been fully exhausted. If + /// you want this feature, you can add an EOF message variant for your component and use + /// [`StreamExt::chain`] and [`stream::once`] to chain an EOF message to the original stream. + /// If your stream is produced by another crate, you can use [`StreamExt::map`] to transform + /// the stream's item type to the component message type. + pub fn send_stream(&self, stream: S) + where + M: Into, + S: Stream + 'static, + { + let link = self.clone(); + let js_future = async move { + futures::pin_mut!(stream); + while let Some(msg) = stream.next().await { + let message: COMP::Message = msg.into(); + link.send_message(message); + } + }; + spawn_local(js_future); + } + /// Returns the linked component if available pub fn get_component(&self) -> Option + '_> { self.arch_get_component() @@ -699,48 +730,6 @@ mod feat_hydration { } } -#[cfg(all(nightly_yew, any(target_arch = "wasm32", feature = "tokio")))] -mod feat_nightly { - use super::*; - use crate::platform::spawn_local; - use futures::{Stream, StreamExt}; - - impl Scope { - /// This method asynchronously awaits a [Stream] that returns a series of messages and sends - /// them to the linked component. - /// - /// # Panics - /// If the stream panics, then the promise will not resolve, and will leak. - /// - /// # Note - /// - /// This method will not notify the component when the stream has been fully exhausted. If - /// you want this feature, you can add an EOF message variant for your component and use - /// [`StreamExt::chain`] and [`stream::once`] to chain an EOF message to the original stream. - /// If your stream is produced by another crate, you can use [`StreamExt::map`] to transform - /// the stream's item type to the component message type. - /// - /// [`StreamExt::chain`]: https://docs.rs/futures/latest/futures/stream/trait.StreamExt.html#method.chain - /// [`stream::once`]: https://docs.rs/futures/latest/futures/stream/fn.once.html - /// [`StreamExt::map`]: https://docs.rs/futures/latest/futures/stream/trait.StreamExt.html#method.map - pub fn send_stream(&self, stream: S) - where - M: Into, - S: Stream + 'static, - { - let link = self.clone(); - let js_future = async move { - futures::pin_mut!(stream); - while let Some(msg) = stream.next().await { - let message: COMP::Message = msg.into(); - link.send_message(message); - } - }; - spawn_local(js_future); - } - } -} - /// Defines a message type that can be sent to a component. /// Used for the return value of closure given to /// [Scope::batch_callback](struct.Scope.html#method.batch_callback).