Browse Source

wip: figure out async syntax

Jonathan Kelley 2 years ago
parent
commit
51aeb29d1a

+ 6 - 6
packages/core/src/any_props.rs

@@ -18,8 +18,8 @@ pub(crate) struct VComponentProps<'a, P, F: Future<Output = Element<'a>> = 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<P> VComponentProps<'_, P> {
+impl<'a, P, F: Future<Output = Element<'a>>> VComponentProps<'a, P, F> {
     pub(crate) fn new(
-        render_fn: Component<P>,
+        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<Output = Element<'a>>> AnyProps<'a> for VComponentProps<'a, P, F> {
     fn as_ptr(&self) -> *const () {
         &self.props as *const _ as *const ()
     }

+ 42 - 8
packages/core/src/component.rs

@@ -8,7 +8,7 @@ use futures_util::Future;
 
 use crate::{scopes::Scope, Element};
 
-pub type Component<T = ()> = fn(Scope<T>) -> Element;
+pub type Component<'a, T = ()> = fn(Scope<'a, T>) -> Element<'a>;
 
 pub enum ComponentFn<'a, T, F: Future<Output = Element<'a>> = Dummy<'a>> {
     Sync(fn(Scope<'a, T>) -> Element),
@@ -19,21 +19,55 @@ pub trait IntoComponent<'a, T, F: Future<Output = Element<'a>> = Dummy<'a>, A =
     fn into_component(self) -> ComponentFn<'a, T, F>;
 }
 
-impl<'a, T> IntoComponent<'a, T, Dummy<'a>> for fn(Scope<T>) -> 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<Output = Element<'a>>> 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<F> AsComponent for for<'r> fn(Scope<'r>) ->
+// where
+//     F: Future<Output = Element<'r>>,
+// {
+//     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<Output = Element<'a>>> 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>;

+ 6 - 4
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<Output = Element<'a>>>(
         &'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) };
 

+ 2 - 1
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);
 

+ 16 - 6
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);