fix: use annotation method from rust/58052 to fix closure lifetimes

This commit is contained in:
Jonathan Kelley committed 2021-10-30 18:23:28 -04:00
1 parent 9ee2bfb010
commit 27d891934a
15 files changed
+333 -180

No files matched your search

+3 -12
View File
@@ -49,7 +49,7 @@ impl ToTokens for CallBody {
match &self.custom_context { match &self.custom_context {
// The `in cx` pattern allows directly rendering // The `in cx` pattern allows directly rendering
Some(ident) => out_tokens.append_all(quote! { Some(ident) => out_tokens.append_all(quote! {
#ident.render(dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{ #ident.render(dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory| -> VNode {
use dioxus_elements::{GlobalAttributes, SvgAttributes}; use dioxus_elements::{GlobalAttributes, SvgAttributes};
#inner #inner
@@ -57,21 +57,12 @@ impl ToTokens for CallBody {
}), }),
// Otherwise we just build the LazyNode wrapper // Otherwise we just build the LazyNode wrapper
None => out_tokens.append_all(quote! { None => out_tokens.append_all(quote! {
{ {
NodeFactory::annotate_lazy(move |__cx: NodeFactory| -> VNode {
let ___p: Box<dyn FnOnce(NodeFactory) -> VNode + '_> = Box::new(move |__cx: NodeFactory|{
use dioxus_elements::{GlobalAttributes, SvgAttributes}; use dioxus_elements::{GlobalAttributes, SvgAttributes};
#inner #inner
}); })
Some(___p)
} }
// dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
// use dioxus_elements::{GlobalAttributes, SvgAttributes};
// #inner
// })
}), }),
}; };
} }
+11 -3
View File
@@ -1,4 +1,7 @@
use dioxus_core::prelude::*; use dioxus_core::prelude::*;
use dioxus_core_macro::format_args_f;
use dioxus_core_macro::rsx;
use dioxus_html as dioxus_elements;
fn main() { fn main() {
let mut dom = VirtualDom::new(EXAMPLE); let mut dom = VirtualDom::new(EXAMPLE);
@@ -7,9 +10,14 @@ fn main() {
} }
pub static EXAMPLE: FC<()> = |(cx, _)| { pub static EXAMPLE: FC<()> = |(cx, _)| {
let list = (0..10).map(|_f| LazyNodes::new(move |_f| todo!())); let list = (0..10).map(|_f| {
rsx! {
"{_f}"
}
});
// let list = (0..10).map(|_f| Some(Box::new(move |_f| todo!())));
cx.render(LazyNodes::new(move |cx| { cx.render(Some(Box::new(move |cx| {
cx.raw_element( cx.raw_element(
"div", "div",
None, None,
@@ -22,5 +30,5 @@ pub static EXAMPLE: FC<()> = |(cx, _)| {
], ],
None, None,
) )
})) })))
}; };
+24 -23
View File
@@ -23,28 +23,29 @@ struct ListItem {
fn app<'a>(cx: Context<'a>, props: &AppProps) -> Element<'a> { fn app<'a>(cx: Context<'a>, props: &AppProps) -> Element<'a> {
// let (val, set_val) = use_state_classic(cx, || 0); // let (val, set_val) = use_state_classic(cx, || 0);
cx.render(LazyNodes::new(move |_nodecx| { todo!()
todo!() // cx.render(LazyNodes::new(move |_nodecx| {
// builder::ElementBuilder::new(_nodecx, "div") // todo!()
// .iter_child({ // // builder::ElementBuilder::new(_nodecx, "div")
// cx.items.iter().map(|child| { // // .iter_child({
// builder::virtual_child( // // cx.items.iter().map(|child| {
// _nodecx, // // builder::virtual_child(
// ChildItem, // // _nodecx,
// ChildProps { // // ChildItem,
// item: child.clone(), // // ChildProps {
// item_handler: set_val.clone(), // // item: child.clone(),
// }, // // item_handler: set_val.clone(),
// None, // // },
// &[], // // None,
// ) // // &[],
// }) // // )
// }) // // })
// .iter_child([builder::ElementBuilder::new(_nodecx, "div") // // })
// .iter_child([builder::text3(_nodecx.bump(), format_args!("{}", val))]) // // .iter_child([builder::ElementBuilder::new(_nodecx, "div")
// .finish()]) // // .iter_child([builder::text3(_nodecx.bump(), format_args!("{}", val))])
// .finish() // // .finish()])
})) // // .finish()
// }))
} }
// props should derive a partialeq implementation automatically, but implement ptr compare for & fields // props should derive a partialeq implementation automatically, but implement ptr compare for & fields
@@ -57,7 +58,7 @@ struct ChildProps {
} }
fn ChildItem<'a>(cx: Context<'a>, props: &'a ChildProps) -> Element<'a> { fn ChildItem<'a>(cx: Context<'a>, props: &'a ChildProps) -> Element<'a> {
cx.render(LazyNodes::new(move |__cx| todo!())) todo!()
} }
impl PartialEq for ChildProps { impl PartialEq for ChildProps {
+38 -37
View File
@@ -3,43 +3,44 @@ use dioxus_core::prelude::*;
fn main() {} fn main() {}
fn app<'a>(cx: Context<'a>, props: &()) -> Element<'a> { fn app<'a>(cx: Context<'a>, props: &()) -> Element<'a> {
let vak = use_suspense( // let vak = use_suspense(
cx, // cx,
|| async {}, // || async {},
|c, _res| c.render(LazyNodes::new(move |f| f.text(format_args!("")))), // |c, _res| c.render(LazyNodes::new(move |f| f.text(format_args!("")))),
); // );
let d1 = cx.render(LazyNodes::new(move |f| { // let d1 = cx.render(to_lazy_nodes(move |f| {
f.raw_element( // f.raw_element(
"div", // "div",
None, // None,
[], // [],
[], // [],
[ // [
f.fragment_from_iter(vak), // // f.fragment_from_iter(vak),
f.text(format_args!("")), // f.text(format_args!("")),
f.text(format_args!("")), // f.text(format_args!("")),
f.text(format_args!("")), // f.text(format_args!("")),
f.text(format_args!("")), // f.text(format_args!("")),
], // ],
None, // None,
) // )
})); // }));
cx.render(LazyNodes::new(move |f| { todo!()
f.raw_element( // cx.render(LazyNodes::new(move |f| {
"div", // f.raw_element(
None, // "div",
[], // None,
[], // [],
[ // [],
f.text(format_args!("")), // [
f.text(format_args!("")), // f.text(format_args!("")),
f.text(format_args!("")), // f.text(format_args!("")),
f.text(format_args!("")), // f.text(format_args!("")),
d1.unwrap(), // f.text(format_args!("")),
], // d1.unwrap(),
None, // ],
) // None,
})) // )
// }))
} }
+2 -7
View File
@@ -2,7 +2,7 @@ use std::marker::PhantomData;
use dioxus::component::Scope; use dioxus::component::Scope;
use dioxus::events::on::MouseEvent; use dioxus::events::on::MouseEvent;
use dioxus::nodes::{IntoVNode, IntoVNodeList}; use dioxus::nodes::IntoVNode;
use dioxus_core as dioxus; use dioxus_core as dioxus;
use dioxus_core::prelude::*; use dioxus_core::prelude::*;
use dioxus_core_macro::*; use dioxus_core_macro::*;
@@ -28,7 +28,7 @@ fn html_usage() {
.filter(|f| f.starts_with('b')) .filter(|f| f.starts_with('b'))
.map(|f| rsx!("hello {f}")); .map(|f| rsx!("hello {f}"));
let p = rsx!(div { {f} }); // let p = rsx!(div { {f} });
} }
static App2: FC<()> = |(cx, _)| cx.render(rsx!("hello world!")); static App2: FC<()> = |(cx, _)| cx.render(rsx!("hello world!"));
@@ -98,11 +98,6 @@ impl<'a> Children<'a> {
} }
} }
} }
// impl<'a> IntoVNodeList<'a> for &Children<'a> {
// fn into_vnode_list(self, cx: NodeFactory<'a>) -> &'a [VNode<'a>] {
// todo!()
// }
// }
static Bapp: FC<()> = |(cx, props)| { static Bapp: FC<()> = |(cx, props)| {
let name = cx.use_state(|| 0); let name = cx.use_state(|| 0);
+169 -11
View File
@@ -2,7 +2,7 @@ use std::marker::PhantomData;
use dioxus::component::Scope; use dioxus::component::Scope;
use dioxus::events::on::MouseEvent; use dioxus::events::on::MouseEvent;
use dioxus::nodes::{IntoVNode, IntoVNodeList}; use dioxus::nodes::{annotate_lazy, IntoVNode};
use dioxus_core as dioxus; use dioxus_core as dioxus;
use dioxus_core::prelude::*; use dioxus_core::prelude::*;
use dioxus_core_macro::*; use dioxus_core_macro::*;
@@ -29,10 +29,16 @@ fn t() {
}; };
} }
fn App((cx, props): Scope<()>) -> Element { #[derive(PartialEq, Props)]
struct OurProps {
foo: String,
}
fn App<'a>((cx, props): Scope<'a, OurProps>) -> Element<'a> {
let a = rsx! { let a = rsx! {
div { div {
"asd" "asd"
"{props.foo}"
} }
}; };
@@ -45,8 +51,12 @@ fn App((cx, props): Scope<()>) -> Element {
}); });
let g = match "text" { let g = match "text" {
"a" => rsx!("asd"), "a" => {
b => rsx!("asd"), rsx!("asd")
}
_ => {
rsx!("asd")
}
}; };
let items = ["bob", "bill", "jack"]; let items = ["bob", "bill", "jack"];
@@ -56,16 +66,164 @@ fn App((cx, props): Scope<()>) -> Element {
.filter(|f| f.starts_with('b')) .filter(|f| f.starts_with('b'))
.map(|f| rsx!("hello {f}")); .map(|f| rsx!("hello {f}"));
// use dioxus_hooks;
// let g = use_state(|| "hello".to_string());
let s: &'a mut String = cx.use_hook(|_| String::new(), |f| f, |_| {});
/*
the final closure is allowed to borrow anything provided it
*/
// cx.render({
// let p: Option<Box<dyn FnOnce(_) -> _>> = Some(Box::new(move |__cx: NodeFactory| {
// use dioxus_elements::{GlobalAttributes, SvgAttributes};
// let props = Child2Props { foo: s };
// let ch: VNode = __cx.component(Child2, props, None, []);
// __cx.element(
// dioxus_elements::div,
// [],
// [],
// [ch],
// // [__cx.component(Child2, fc_to_builder(Child2).foo(s).build(), None, [])],
// None,
// )
// }));
// p
// // let ___p: Box<dyn FnOnce(NodeFactory) -> VNode> = Box::new(move |__cx| {
// // use dioxus_elements::{GlobalAttributes, SvgAttributes};
// // let props = Child2Props { foo: s };
// // let ch: VNode = __cx.component(Child2, props, None, []);
// // __cx.element(
// // dioxus_elements::div,
// // [],
// // [],
// // [ch],
// // // [__cx.component(Child2, fc_to_builder(Child2).foo(s).build(), None, [])],
// // None,
// // )
// // });
// // Some(___p)
// })
let a = annotate_lazy(move |f| {
//
todo!()
});
let b = annotate_lazy(move |f| {
//
f.text(format_args!("{}", props.foo))
});
let c = annotate_lazy(move |f| {
//
f.component(
Child,
OurProps {
//
foo: "hello".to_string(),
},
None,
[],
)
});
let st: &'a String = cx.use_hook(|_| "hello".to_string(), |f| f, |_| {});
let d = annotate_lazy(move |f| {
//
f.component(
Child2,
Child2Props {
//
foo: st,
},
None,
[],
)
});
let e = match "asd" {
b => {
//
annotate_lazy(move |f| {
//
f.text(format_args!("{}", props.foo))
})
}
a => {
//
annotate_lazy(move |f| {
//
f.text(format_args!("{}", props.foo))
})
}
};
cx.render(annotate_lazy(move |f| {
//
f.raw_element(
"div",
None,
[],
[],
[
//
f.fragment_from_iter(a),
f.fragment_from_iter(b),
f.fragment_from_iter(c),
f.fragment_from_iter(e),
],
None,
)
// todo!()
}))
// cx.render(rsx! {
// div {
// div {
// {a}
// // {p}
// // {g}
// // {f}
// }
// // div {
// // "asd"
// // div {
// // "asd"
// // }
// // }
// // Child {
// // foo: "asd".to_string(),
// // }
// Child2 {
// foo: s,
// }
// }
// })
}
fn Child((cx, props): Scope<OurProps>) -> Element {
cx.render(rsx! { cx.render(rsx! {
div { div {
div { div {}
{a}
{p}
{g}
{f}
}
} }
}) })
} }
// std::boxed::Box<dyn for<'r> std::ops::FnOnce(dioxus_core::NodeFactory<'r>) -> dioxus_core::VNode<'_>> #[derive(Props)]
struct Child2Props<'a> {
foo: &'a String,
}
fn Child2<'a>((cx, props): Scope<'a, Child2Props>) -> Element<'a> {
cx.render(rsx! {
div {
// div {}
}
})
}
+2 -1
View File
@@ -4,7 +4,8 @@ use dioxus_core::prelude::*;
#[async_std::main] #[async_std::main]
async fn main() { async fn main() {
static App: FC<()> = |(cx, props)| cx.render(LazyNodes::new(|f| f.text(format_args!("hello")))); static App: FC<()> =
|(cx, props)| cx.render(Some(Box::new(move |f| f.text(format_args!("hello")))));
let mut dom = VirtualDom::new(App); let mut dom = VirtualDom::new(App);
+1 -1
View File
@@ -6,7 +6,7 @@
//! that ensures compile-time required and optional fields on cx. //! that ensures compile-time required and optional fields on cx.
use crate::{ use crate::{
innerlude::{Context, Element, LazyNodes, FC}, innerlude::{Context, Element, FC},
NodeFactory, VNode, NodeFactory, VNode,
}; };
+2 -1
View File
@@ -139,7 +139,8 @@ impl<'src> Context<'src> {
///``` ///```
pub fn render( pub fn render(
self, self,
lazy_nodes: Option<LazyNodes<'_>>, lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'src>) -> VNode<'src> + '_>>,
// lazy_nodes: Option<Box<dyn FnOnce(NodeFactory) -> VNode + '_>>,
// lazy_nodes: Box<dyn FnOnce(NodeFactory<'src>) -> VNode<'src> + '_>, // lazy_nodes: Box<dyn FnOnce(NodeFactory<'src>) -> VNode<'src> + '_>,
) -> Option<VNode<'src>> { ) -> Option<VNode<'src>> {
// pub fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>( // pub fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>(
+10 -10
View File
@@ -180,17 +180,17 @@ pub struct SuspendedContext<'a> {
} }
impl<'src> SuspendedContext<'src> { impl<'src> SuspendedContext<'src> {
// // pub fn render(
// pub fn render( // pub fn render(
pub fn render( // // pub fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>(
// pub fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>( // self,
self, // lazy_nodes: LazyNodes<'_>,
lazy_nodes: LazyNodes<'_>, // // lazy_nodes: LazyNodes<'src, '_>,
// lazy_nodes: LazyNodes<'src, '_>, // ) -> Element<'src> {
) -> Element<'src> { // let bump = &self.inner.scope.frames.wip_frame().bump;
let bump = &self.inner.scope.frames.wip_frame().bump; // todo!("suspense")
todo!("suspense") // // Some(lazy_nodes.into_vnode(NodeFactory { bump }))
// Some(lazy_nodes.into_vnode(NodeFactory { bump })) // }
}
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
+7 -1
View File
@@ -32,7 +32,13 @@ use crate::innerlude::{IntoVNode, NodeFactory, VNode};
// // inner: StackNodeStorage<'a>, // // inner: StackNodeStorage<'a>,
// // inner: StackNodeStorage<'a>, // // inner: StackNodeStorage<'a>,
// } // }
pub type LazyNodes<'b> = Box<dyn for<'a> FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>; // pub type LazyNodes<'b> = Box<dyn for<'a> FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>;
// pub fn to_lazy_nodes<'b>(
// f: impl for<'a> FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b,
// ) -> Option<LazyNodes<'b>> {
// Some(Box::new(f))
// }
type StackHeapSize = [usize; 12]; type StackHeapSize = [usize; 12];
+4 -5
View File
@@ -46,7 +46,6 @@ pub(crate) mod innerlude {
pub use crate::heuristics::*; pub use crate::heuristics::*;
pub(crate) use crate::hooklist::*; pub(crate) use crate::hooklist::*;
pub use crate::hooks::*; pub use crate::hooks::*;
pub use crate::lazynodes::LazyNodes;
pub use crate::mutations::*; pub use crate::mutations::*;
pub use crate::nodes::*; pub use crate::nodes::*;
pub(crate) use crate::resources::*; pub(crate) use crate::resources::*;
@@ -63,16 +62,16 @@ pub(crate) mod innerlude {
} }
pub use crate::innerlude::{ pub use crate::innerlude::{
Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, LazyNodes, MountType, Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, MountType, Mutations,
Mutations, NodeFactory, Properties, SchedulerMsg, ScopeId, SuspendedContext, TaskHandle, NodeFactory, Properties, SchedulerMsg, ScopeId, SuspendedContext, TaskHandle, TestDom,
TestDom, ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC, ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC,
}; };
pub mod prelude { pub mod prelude {
pub use crate::component::{fc_to_builder, Fragment, Properties, Scope}; pub use crate::component::{fc_to_builder, Fragment, Properties, Scope};
pub use crate::context::Context; pub use crate::context::Context;
pub use crate::hooks::*; pub use crate::hooks::*;
pub use crate::innerlude::{DioxusElement, Element, LazyNodes, Mutations, NodeFactory, FC}; pub use crate::innerlude::{DioxusElement, Element, Mutations, NodeFactory, FC};
pub use crate::nodes::VNode; pub use crate::nodes::VNode;
pub use crate::VirtualDom; pub use crate::VirtualDom;
} }
+46 -54
View File
@@ -4,8 +4,7 @@
//! cheap and *very* fast to construct - building a full tree should be quick. //! cheap and *very* fast to construct - building a full tree should be quick.
use crate::innerlude::{ use crate::innerlude::{
empty_cell, Context, Element, ElementId, LazyNodes, Properties, ScopeId, ScopeInner, empty_cell, Context, Element, ElementId, Properties, ScopeId, ScopeInner, SuspendedContext, FC,
SuspendedContext, FC,
}; };
use bumpalo::{boxed::Box as BumpBox, Bump}; use bumpalo::{boxed::Box as BumpBox, Bump};
use std::{ use std::{
@@ -329,21 +328,6 @@ impl<'a> NodeFactory<'a> {
self.bump self.bump
} }
pub fn render_directly(&self, lazy_nodes: LazyNodes<'_>) -> Element<'a>
// pub fn render_directly(&self, lazy_nodes: LazyNodes<'a, '_>) -> Element<'a>
// where
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
{
// pub fn render_directly<F>(&self, lazy_nodes: LazyNodes<'a, F>) -> Element<'a>
// where
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
// {
// pub fn render_directly<F>(&self, lazy_nodes: LazyNodes<'a>) -> Option<VNode<'a>> {
// Some(lazy_nodes.into_vnode(NodeFactory { bump: self.bump }))
todo!()
}
pub fn unstable_place_holder() -> VNode<'static> { pub fn unstable_place_holder() -> VNode<'static> {
VNode::Text(VText { VNode::Text(VText {
text: "", text: "",
@@ -474,7 +458,8 @@ impl<'a> NodeFactory<'a> {
) -> VNode<'a> ) -> VNode<'a>
where where
P: Properties + 'a, P: Properties + 'a,
V: 'a + AsRef<[VNode<'a>]>, V: AsRef<[VNode<'a>]> + 'a,
// V: 'a + AsRef<[VNode<'a>]>,
{ {
let bump = self.bump(); let bump = self.bump();
let children: &'a V = bump.alloc(children); let children: &'a V = bump.alloc(children);
@@ -559,8 +544,24 @@ impl<'a> NodeFactory<'a> {
})) }))
} }
pub fn fragment_from_iter(self, node_iter: impl IntoVNodeList) -> VNode<'a> { pub fn fragment_from_iter(
let children = node_iter.into_vnode_list(self); self,
node_iter: impl IntoIterator<Item = impl IntoVNode<'a>>,
) -> VNode<'a> {
let bump = self.bump();
let mut nodes = bumpalo::collections::Vec::new_in(bump);
for node in node_iter {
nodes.push(node.into_vnode(self));
}
if nodes.is_empty() {
nodes.push(VNode::Anchor(VAnchor {
dom_id: empty_cell(),
}));
}
let children = nodes.into_bump_slice();
// TODO // TODO
// We need a dedicated path in the rsx! macro that will trigger the "you need keys" warning // We need a dedicated path in the rsx! macro that will trigger the "you need keys" warning
@@ -587,6 +588,15 @@ impl<'a> NodeFactory<'a> {
is_static: false, is_static: false,
}) })
} }
pub fn annotate_lazy<'z, 'b, F>(
f: F,
) -> Option<Box<dyn FnOnce(NodeFactory<'z>) -> VNode<'z> + 'b>>
where
F: FnOnce(NodeFactory<'z>) -> VNode<'z> + 'b,
{
Some(Box::new(f))
}
} }
/// Trait implementations for use in the rsx! and html! macros. /// Trait implementations for use in the rsx! and html! macros.
@@ -604,34 +614,8 @@ impl<'a> NodeFactory<'a> {
/// ///
/// As such, all node creation must go through the factory, which is only available in the component context. /// As such, all node creation must go through the factory, which is only available in the component context.
/// These strict requirements make it possible to manage lifetimes and state. /// These strict requirements make it possible to manage lifetimes and state.
pub trait IntoVNode { pub trait IntoVNode<'a> {
fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a>; fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a>;
}
pub trait IntoVNodeList {
fn into_vnode_list<'a>(self, cx: NodeFactory<'a>) -> &'a [VNode<'a>];
}
impl<T, V> IntoVNodeList for T
where
T: IntoIterator<Item = V>,
V: IntoVNode,
{
fn into_vnode_list<'a>(self, cx: NodeFactory<'a>) -> &'a [VNode<'a>] {
let mut nodes = bumpalo::collections::Vec::new_in(cx.bump());
for node in self.into_iter() {
nodes.push(node.into_vnode(cx));
}
if nodes.is_empty() {
nodes.push(VNode::Anchor(VAnchor {
dom_id: empty_cell(),
}));
}
nodes.into_bump_slice()
}
} }
/// Child nodes of the parent component. /// Child nodes of the parent component.
@@ -684,6 +668,7 @@ impl<'a> IntoIterator for VNode<'a> {
} }
} }
// TODO: do we even need this? It almost seems better not to
// // For the case where a rendered VNode is passed into the rsx! macro through curly braces // // For the case where a rendered VNode is passed into the rsx! macro through curly braces
// impl IntoVNode for VNode<'_> { // impl IntoVNode for VNode<'_> {
// fn into_vnode<'a>(self, _: NodeFactory<'a>) -> VNode<'a> { // fn into_vnode<'a>(self, _: NodeFactory<'a>) -> VNode<'a> {
@@ -714,8 +699,15 @@ impl<'a> IntoIterator for VNode<'a> {
// } // }
// } // }
impl IntoVNode for Option<Box<dyn for<'r> FnOnce(NodeFactory<'r>) -> VNode<'_> + '_>> { pub fn annotate_lazy<'a, 'b, F>(f: F) -> Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>>
fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> { where
F: FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b,
{
Some(Box::new(f))
}
impl<'a> IntoVNode<'a> for Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>> {
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
match self { match self {
Some(n) => { Some(n) => {
// //
@@ -731,8 +723,8 @@ impl IntoVNode for Option<Box<dyn for<'r> FnOnce(NodeFactory<'r>) -> VNode<'_> +
} }
} }
impl IntoVNode for Box<dyn for<'r> FnOnce(NodeFactory<'r>) -> VNode<'_> + '_> { impl<'a> IntoVNode<'a> for Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_> {
fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> { fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
self(cx) self(cx)
} }
} }
@@ -746,12 +738,12 @@ impl IntoVNode for Box<dyn for<'r> FnOnce(NodeFactory<'r>) -> VNode<'_> + '_> {
// } // }
// } // }
impl IntoVNode for &'static str { impl IntoVNode<'_> for &'static str {
fn into_vnode(self, cx: NodeFactory) -> VNode { fn into_vnode(self, cx: NodeFactory) -> VNode {
cx.static_text(self) cx.static_text(self)
} }
} }
impl IntoVNode for Arguments<'_> { impl IntoVNode<'_> for Arguments<'_> {
fn into_vnode(self, cx: NodeFactory) -> VNode { fn into_vnode(self, cx: NodeFactory) -> VNode {
cx.text(self) cx.text(self)
} }
+6 -6
View File
@@ -13,14 +13,14 @@ fn test_borrowed_state() {
fn Parent((cx, _): Scope<()>) -> Element { fn Parent((cx, _): Scope<()>) -> Element {
let value = cx.use_hook(|_| String::new(), |f| &*f, |_| {}); let value = cx.use_hook(|_| String::new(), |f| &*f, |_| {});
rsx! { cx.render(rsx! {
div { div {
Child { name: value } Child { name: value }
Child { name: value } Child { name: value }
Child { name: value } Child { name: value }
Child { name: value } Child { name: value }
} }
} })
} }
#[derive(Props)] #[derive(Props)]
@@ -29,12 +29,12 @@ struct ChildProps<'a> {
} }
fn Child<'a>((cx, props): Scope<'a, ChildProps>) -> Element<'a> { fn Child<'a>((cx, props): Scope<'a, ChildProps>) -> Element<'a> {
rsx! { cx.render(rsx! {
div { div {
h1 { "it's nested" } h1 { "it's nested" }
Child2 { name: props.name } Child2 { name: props.name }
} }
} })
} }
#[derive(Props)] #[derive(Props)]
@@ -43,7 +43,7 @@ struct Grandchild<'a> {
} }
fn Child2<'a>((cx, props): Scope<'a, Grandchild>) -> Element<'a> { fn Child2<'a>((cx, props): Scope<'a, Grandchild>) -> Element<'a> {
rsx! { cx.render(rsx! {
div { "Hello {props.name}!" } div { "Hello {props.name}!" }
} })
} }
+8 -8
View File
@@ -14,23 +14,23 @@ mod test_logging;
#[test] #[test]
fn please_work() { fn please_work() {
static App: FC<()> = |(cx, props)| { static App: FC<()> = |(cx, props)| {
rsx! { cx.render(rsx! {
div { div {
hidden: "true" hidden: "true"
"hello" "hello"
div { "hello" } div { "hello" }
Child {} // Child {}
Child {} // Child {}
Child {} // Child {}
} }
div { "hello" } // div { "hello" }
} })
}; };
static Child: FC<()> = |(cx, props)| { static Child: FC<()> = |(cx, props)| {
rsx! { cx.render(rsx! {
div { "child" } div { "child" }
} })
}; };
let mut dom = VirtualDom::new(App); let mut dom = VirtualDom::new(App);