diff --git a/packages/core/src/any_props.rs b/packages/core/src/any_props.rs index 543d05d31..01645e6c8 100644 --- a/packages/core/src/any_props.rs +++ b/packages/core/src/any_props.rs @@ -18,8 +18,8 @@ pub(crate) struct VComponentProps<'a, P, F: Future> = Dummy pub props: *const P, } -impl VComponentProps<'_, ()> { - pub fn new_empty(render_fn: Component<()>) -> Self { +impl<'a> VComponentProps<'a, ()> { + pub fn new_empty(render_fn: Component<'a, ()>) -> Self { Self { render_fn: render_fn.into_component(), memo: <() as PartialEq>::eq, @@ -28,21 +28,21 @@ impl VComponentProps<'_, ()> { } } -impl

VComponentProps<'_, P> { +impl<'a, P, F: Future>> VComponentProps<'a, P, F> { pub(crate) fn new( - render_fn: Component

, + render_fn: ComponentFn<'a, P, F>, memo: unsafe fn(&P, &P) -> bool, props: *const P, ) -> Self { Self { - render_fn: render_fn.into_component(), + render_fn, memo, props, } } } -impl<'a, P> AnyProps<'a> for VComponentProps<'a, P> { +impl<'a, P, F: Future>> AnyProps<'a> for VComponentProps<'a, P, F> { fn as_ptr(&self) -> *const () { &self.props as *const _ as *const () } diff --git a/packages/core/src/component.rs b/packages/core/src/component.rs index 145b4ca6c..be1837c41 100644 --- a/packages/core/src/component.rs +++ b/packages/core/src/component.rs @@ -8,7 +8,7 @@ use futures_util::Future; use crate::{scopes::Scope, Element}; -pub type Component = fn(Scope) -> Element; +pub type Component<'a, T = ()> = fn(Scope<'a, T>) -> Element<'a>; pub enum ComponentFn<'a, T, F: Future> = Dummy<'a>> { Sync(fn(Scope<'a, T>) -> Element), @@ -19,21 +19,55 @@ pub trait IntoComponent<'a, T, F: Future> = Dummy<'a>, A = fn into_component(self) -> ComponentFn<'a, T, F>; } -impl<'a, T> IntoComponent<'a, T, Dummy<'a>> for fn(Scope) -> Element { +impl<'a, T> IntoComponent<'a, T, Dummy<'a>> for fn(Scope<'a, T>) -> Element<'a> { fn into_component(self) -> ComponentFn<'a, T> { ComponentFn::Sync(self) } } -pub struct AsyncMarker; -impl<'a, T, F: Future>> IntoComponent<'a, T, F, AsyncMarker> - for fn(Scope<'a, T>) -> F -{ - fn into_component(self) -> ComponentFn<'a, T, F> { - ComponentFn::Async(self) - } +enum ComponentFn2 { + Sync(fn(Scope) -> Element), } +trait AsComponent { + fn as_component(self) -> ComponentFn2; +} + +// impl AsComponent for fn(Scope) -> Element { +// fn as_component(self) -> ComponentFn2 { +// ComponentFn2::Sync(self) +// } +// } + +// impl AsComponent for for<'r> fn(Scope<'r>) -> +// where +// F: Future>, +// { +// fn as_component(self) -> ComponentFn2 { +// ComponentFn2::Sync(self) +// } +// } + +fn takes_f(f: impl AsComponent) {} + +#[test] +fn example() { + fn app(cx: Scope) -> Element { + todo!() + } + + // takes_f(app as fn(Scope) -> Element); +} + +// pub struct AsyncMarker; +// impl<'a, T, F: Future>> IntoComponent<'a, T, F, AsyncMarker> +// for fn(Scope<'a, T>) -> F +// { +// fn into_component(self) -> ComponentFn<'a, T, F> { +// ComponentFn::Async(self) +// } +// } + pub struct Dummy<'a>(PhantomData<&'a ()>); impl<'a> Future for Dummy<'a> { type Output = Element<'a>; diff --git a/packages/core/src/factory.rs b/packages/core/src/factory.rs index 2a078c36d..badd7a220 100644 --- a/packages/core/src/factory.rs +++ b/packages/core/src/factory.rs @@ -1,10 +1,12 @@ use std::{cell::Cell, fmt::Arguments}; use bumpalo::Bump; +use futures_util::Future; use crate::{ any_props::{AnyProps, VComponentProps}, arena::ElementId, + component::IntoComponent, innerlude::DynamicNode, Attribute, AttributeValue, Element, LazyNodes, Properties, Scope, ScopeState, VNode, }; @@ -68,9 +70,9 @@ impl ScopeState { } /// Create a new [`VNode::Component`] - pub fn component<'a, P>( + pub fn component<'a, P, F: Future>>( &'a self, - component: fn(Scope<'a, P>) -> Element, + component: impl IntoComponent<'a, P, F>, props: P, fn_name: &'static str, ) -> DynamicNode<'a> @@ -78,8 +80,8 @@ impl ScopeState { P: Properties + 'a, { let props = self.bump().alloc(props); - let detached = unsafe { std::mem::transmute(component) }; - let vcomp = VComponentProps::new(detached, P::memoize, props); + let as_component = component.into_component(); + let vcomp = VComponentProps::new(as_component, P::memoize, props); let as_dyn = self.bump().alloc(vcomp) as &mut dyn AnyProps; let detached_dyn: *mut dyn AnyProps = unsafe { std::mem::transmute(as_dyn) }; diff --git a/packages/core/src/virtualdom.rs b/packages/core/src/virtualdom.rs index b393d2b26..6b9f3fe4d 100644 --- a/packages/core/src/virtualdom.rs +++ b/packages/core/src/virtualdom.rs @@ -27,7 +27,7 @@ pub struct VirtualDom { } impl VirtualDom { - pub fn new(app: Component<()>) -> Self { + pub fn new<'a>(app: Component<'a, ()>) -> Self { let (sender, receiver) = futures_channel::mpsc::unbounded(); let mut res = Self { @@ -43,6 +43,7 @@ impl VirtualDom { }; let props = Box::into_raw(Box::new(VComponentProps::new_empty(app))); + let props: *mut VComponentProps<()> = unsafe { std::mem::transmute(props) }; let root = res.new_scope(props); diff --git a/packages/dioxus/tests/rsx_syntax.rs b/packages/dioxus/tests/rsx_syntax.rs index 37711ee38..8f0846df9 100644 --- a/packages/dioxus/tests/rsx_syntax.rs +++ b/packages/dioxus/tests/rsx_syntax.rs @@ -25,12 +25,16 @@ fn basic_syntax_is_a_template(cx: Scope) -> Element { fn basic_template(cx: Scope) -> Element { let val = 123; - cx.render(rsx! { - div { class: "{val}", class: "{val}", class: "{val}", class: "{val}", - (0..2).map(|i| rsx! { div { "asd {i}" } }) - basic_child { } - } - }) + + cx.component(basic_child, (), "fn_name"); + + todo!() + // cx.render(rsx! { + // div { class: "{val}", class: "{val}", class: "{val}", class: "{val}", + // (0..2).map(|i| rsx! { div { "asd {i}" } }) + // basic_child { } + // } + // }) } /// A beautiful component @@ -38,6 +42,12 @@ fn basic_child(cx: Scope) -> Element { todo!() } +async fn async_component(cx: Scope<'_>) -> Element { + cx.render(rsx! { + div { class: "asd" } + }) +} + #[test] fn basic_prints() { let mut dom = VirtualDom::new(basic_template);