22//!
33//! VNodes represent lazily-constructed VDom trees that support diffing and event handlers. These VNodes should be *very*
44//! cheap and *very* fast to construct - building a full tree should be quick.
5-
65use crate :: {
76 innerlude:: { AttributeValue , ComponentPtr , Element , Properties , Scope , ScopeId , ScopeState } ,
87 lazynodes:: LazyNodes ,
@@ -375,7 +374,6 @@ pub struct Listener<'bump> {
375374
376375pub type InternalHandler < ' bump > = & ' bump RefCell < Option < InternalListenerCallback < ' bump > > > ;
377376type InternalListenerCallback < ' bump > = BumpBox < ' bump , dyn FnMut ( AnyEvent ) + ' bump > ;
378-
379377type ExternalListenerCallback < ' bump , T > = BumpBox < ' bump , dyn FnMut ( T ) + ' bump > ;
380378
381379/// The callback type generated by the `rsx!` macro when an `on` field is specified for components.
@@ -706,43 +704,11 @@ impl<'a> NodeFactory<'a> {
706704 }
707705
708706 /// Create a new [`VNode::Fragment`] from any iterator
709- pub fn fragment_from_iter < ' b , ' c > (
707+ pub fn fragment_from_iter < ' c , I , J > (
710708 self ,
711- node_iter : impl IntoIterator < Item = impl IntoVNode < ' a > + ' c > + ' b ,
709+ node_iter : impl IntoVNode < ' a , I , J > + ' c ,
712710 ) -> VNode < ' a > {
713- let mut nodes = bumpalo:: collections:: Vec :: new_in ( self . bump ) ;
714-
715- for node in node_iter {
716- nodes. push ( node. into_vnode ( self ) ) ;
717- }
718-
719- if nodes. is_empty ( ) {
720- VNode :: Placeholder ( self . bump . alloc ( VPlaceholder { id : empty_cell ( ) } ) )
721- } else {
722- let children = nodes. into_bump_slice ( ) ;
723-
724- if cfg ! ( debug_assertions)
725- && children. len ( ) > 1
726- && children. last ( ) . unwrap ( ) . key ( ) . is_none ( )
727- {
728- // todo: make the backtrace prettier or remove it altogether
729- log:: error!(
730- r#"
731- Warning: Each child in an array or iterator should have a unique "key" prop.
732- Not providing a key will lead to poor performance with lists.
733- See docs.rs/dioxus for more information.
734- -------------
735- {:?}
736- "# ,
737- backtrace:: Backtrace :: new( )
738- ) ;
739- }
740-
741- VNode :: Fragment ( self . bump . alloc ( VFragment {
742- children,
743- key : None ,
744- } ) )
745- }
711+ node_iter. into_vnode ( self )
746712 }
747713
748714 /// Create a new [`VNode`] from any iterator of children
@@ -800,20 +766,11 @@ impl Debug for NodeFactory<'_> {
800766///
801767/// As such, all node creation must go through the factory, which is only available in the component context.
802768/// These strict requirements make it possible to manage lifetimes and state.
803- pub trait IntoVNode < ' a > {
769+ pub trait IntoVNode < ' a , I = ( ) , J = ( ) > {
804770 /// Convert this into a [`VNode`], using the [`NodeFactory`] as a source of allocation
805771 fn into_vnode ( self , cx : NodeFactory < ' a > ) -> VNode < ' a > ;
806772}
807773
808- // For the case where a rendered VNode is passed into the rsx! macro through curly braces
809- impl < ' a > IntoIterator for VNode < ' a > {
810- type Item = VNode < ' a > ;
811- type IntoIter = std:: iter:: Once < Self :: Item > ;
812- fn into_iter ( self ) -> Self :: IntoIter {
813- std:: iter:: once ( self )
814- }
815- }
816-
817774// TODO: do we even need this? It almost seems better not to
818775// // For the case where a rendered VNode is passed into the rsx! macro through curly braces
819776impl < ' a > IntoVNode < ' a > for VNode < ' a > {
@@ -825,37 +782,7 @@ impl<'a> IntoVNode<'a> for VNode<'a> {
825782// Conveniently, we also support "null" (nothing) passed in
826783impl IntoVNode < ' _ > for ( ) {
827784 fn into_vnode ( self , cx : NodeFactory ) -> VNode {
828- cx. fragment_from_iter ( None as Option < VNode > )
829- }
830- }
831-
832- // Conveniently, we also support "None"
833- impl IntoVNode < ' _ > for Option < ( ) > {
834- fn into_vnode ( self , cx : NodeFactory ) -> VNode {
835- cx. fragment_from_iter ( None as Option < VNode > )
836- }
837- }
838-
839- impl < ' a > IntoVNode < ' a > for Option < VNode < ' a > > {
840- fn into_vnode ( self , cx : NodeFactory < ' a > ) -> VNode < ' a > {
841- self . unwrap_or_else ( || cx. fragment_from_iter ( None as Option < VNode > ) )
842- }
843- }
844-
845- impl < ' a > IntoVNode < ' a > for Option < LazyNodes < ' a , ' _ > > {
846- fn into_vnode ( self , cx : NodeFactory < ' a > ) -> VNode < ' a > {
847- match self {
848- Some ( lazy) => lazy. call ( cx) ,
849- None => VNode :: Placeholder ( cx. bump . alloc ( VPlaceholder { id : empty_cell ( ) } ) ) ,
850- }
851- }
852- }
853-
854- impl < ' a , ' b > IntoIterator for LazyNodes < ' a , ' b > {
855- type Item = LazyNodes < ' a , ' b > ;
856- type IntoIter = std:: iter:: Once < Self :: Item > ;
857- fn into_iter ( self ) -> Self :: IntoIter {
858- std:: iter:: once ( self )
785+ VNode :: Placeholder ( cx. bump . alloc ( VPlaceholder { id : empty_cell ( ) } ) )
859786 }
860787}
861788
@@ -883,17 +810,53 @@ impl IntoVNode<'_> for Arguments<'_> {
883810 }
884811}
885812
886- impl < ' a > IntoVNode < ' a > for & Option < VNode < ' a > > {
887- fn into_vnode ( self , cx : NodeFactory < ' a > ) -> VNode < ' a > {
888- self . as_ref ( )
889- . map ( |f| f. into_vnode ( cx) )
890- . unwrap_or_else ( || cx. fragment_from_iter ( None as Option < VNode > ) )
891- }
892- }
893-
894813impl < ' a > IntoVNode < ' a > for & VNode < ' a > {
895814 fn into_vnode ( self , _cx : NodeFactory < ' a > ) -> VNode < ' a > {
896815 // borrowed nodes are strange
897816 self . decouple ( )
898817 }
899818}
819+
820+ // Note that we're using the E as a generic but this is never crafted anyways.
821+ pub struct FromNodeIterator ;
822+ impl < ' a , T , I , E > IntoVNode < ' a , FromNodeIterator , E > for T
823+ where
824+ T : IntoIterator < Item = I > ,
825+ I : IntoVNode < ' a , E > ,
826+ {
827+ fn into_vnode ( self , cx : NodeFactory < ' a > ) -> VNode < ' a > {
828+ let mut nodes = bumpalo:: collections:: Vec :: new_in ( cx. bump ) ;
829+
830+ for node in self {
831+ nodes. push ( node. into_vnode ( cx) ) ;
832+ }
833+
834+ if nodes. is_empty ( ) {
835+ VNode :: Placeholder ( cx. bump . alloc ( VPlaceholder { id : empty_cell ( ) } ) )
836+ } else {
837+ let children = nodes. into_bump_slice ( ) ;
838+
839+ if cfg ! ( debug_assertions)
840+ && children. len ( ) > 1
841+ && children. last ( ) . unwrap ( ) . key ( ) . is_none ( )
842+ {
843+ // todo: make the backtrace prettier or remove it altogether
844+ log:: error!(
845+ r#"
846+ Warning: Each child in an array or iterator should have a unique "key" prop.
847+ Not providing a key will lead to poor performance with lists.
848+ See docs.rs/dioxus for more information.
849+ -------------
850+ {:?}
851+ "# ,
852+ backtrace:: Backtrace :: new( )
853+ ) ;
854+ }
855+
856+ VNode :: Fragment ( cx. bump . alloc ( VFragment {
857+ children,
858+ key : None ,
859+ } ) )
860+ }
861+ }
862+ }
0 commit comments