wip: figure out async syntax

This commit is contained in:
Jonathan Kelley committed 2022-11-03 02:37:41 -07:00
1 parent 591674f701
commit 51aeb29d1a
5 files changed
+73 -26

No files matched your search

+6 -6
View File
@@ -18,8 +18,8 @@ pub(crate) struct VComponentProps<'a, P, F: Future<Output = Element<'a>> = Dummy
pub props: *const P, pub props: *const P,
} }
impl VComponentProps<'_, ()> { impl<'a> VComponentProps<'a, ()> {
pub fn new_empty(render_fn: Component<()>) -> Self { pub fn new_empty(render_fn: Component<'a, ()>) -> Self {
Self { Self {
render_fn: render_fn.into_component(), render_fn: render_fn.into_component(),
memo: <() as PartialEq>::eq, 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( pub(crate) fn new(
render_fn: Component<P>, render_fn: ComponentFn<'a, P, F>,
memo: unsafe fn(&P, &P) -> bool, memo: unsafe fn(&P, &P) -> bool,
props: *const P, props: *const P,
) -> Self { ) -> Self {
Self { Self {
render_fn: render_fn.into_component(), render_fn,
memo, memo,
props, 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 () { fn as_ptr(&self) -> *const () {
&self.props as *const _ as *const () &self.props as *const _ as *const ()
} }
+43 -9
View File
@@ -8,7 +8,7 @@ use futures_util::Future;
use crate::{scopes::Scope, Element}; 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>> { pub enum ComponentFn<'a, T, F: Future<Output = Element<'a>> = Dummy<'a>> {
Sync(fn(Scope<'a, T>) -> Element), 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>; 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> { fn into_component(self) -> ComponentFn<'a, T> {
ComponentFn::Sync(self) ComponentFn::Sync(self)
} }
} }
pub struct AsyncMarker; enum ComponentFn2 {
impl<'a, T, F: Future<Output = Element<'a>>> IntoComponent<'a, T, F, AsyncMarker> Sync(fn(Scope) -> Element),
for fn(Scope<'a, T>) -> F
{
fn into_component(self) -> ComponentFn<'a, T, F> {
ComponentFn::Async(self)
}
} }
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 ()>); pub struct Dummy<'a>(PhantomData<&'a ()>);
impl<'a> Future for Dummy<'a> { impl<'a> Future for Dummy<'a> {
type Output = Element<'a>; type Output = Element<'a>;
+6 -4
View File
@@ -1,10 +1,12 @@
use std::{cell::Cell, fmt::Arguments}; use std::{cell::Cell, fmt::Arguments};
use bumpalo::Bump; use bumpalo::Bump;
use futures_util::Future;
use crate::{ use crate::{
any_props::{AnyProps, VComponentProps}, any_props::{AnyProps, VComponentProps},
arena::ElementId, arena::ElementId,
component::IntoComponent,
innerlude::DynamicNode, innerlude::DynamicNode,
Attribute, AttributeValue, Element, LazyNodes, Properties, Scope, ScopeState, VNode, Attribute, AttributeValue, Element, LazyNodes, Properties, Scope, ScopeState, VNode,
}; };
@@ -68,9 +70,9 @@ impl ScopeState {
} }
/// Create a new [`VNode::Component`] /// Create a new [`VNode::Component`]
pub fn component<'a, P>( pub fn component<'a, P, F: Future<Output = Element<'a>>>(
&'a self, &'a self,
component: fn(Scope<'a, P>) -> Element, component: impl IntoComponent<'a, P, F>,
props: P, props: P,
fn_name: &'static str, fn_name: &'static str,
) -> DynamicNode<'a> ) -> DynamicNode<'a>
@@ -78,8 +80,8 @@ impl ScopeState {
P: Properties + 'a, P: Properties + 'a,
{ {
let props = self.bump().alloc(props); let props = self.bump().alloc(props);
let detached = unsafe { std::mem::transmute(component) }; let as_component = component.into_component();
let vcomp = VComponentProps::new(detached, P::memoize, props); let vcomp = VComponentProps::new(as_component, P::memoize, props);
let as_dyn = self.bump().alloc(vcomp) as &mut dyn AnyProps; let as_dyn = self.bump().alloc(vcomp) as &mut dyn AnyProps;
let detached_dyn: *mut dyn AnyProps = unsafe { std::mem::transmute(as_dyn) }; let detached_dyn: *mut dyn AnyProps = unsafe { std::mem::transmute(as_dyn) };
+2 -1
View File
@@ -27,7 +27,7 @@ pub struct VirtualDom {
} }
impl 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 (sender, receiver) = futures_channel::mpsc::unbounded();
let mut res = Self { let mut res = Self {
@@ -43,6 +43,7 @@ impl VirtualDom {
}; };
let props = Box::into_raw(Box::new(VComponentProps::new_empty(app))); 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); let root = res.new_scope(props);
+16 -6
View File
@@ -25,12 +25,16 @@ fn basic_syntax_is_a_template(cx: Scope) -> Element {
fn basic_template(cx: Scope) -> Element { fn basic_template(cx: Scope) -> Element {
let val = 123; let val = 123;
cx.render(rsx! {
div { class: "{val}", class: "{val}", class: "{val}", class: "{val}", cx.component(basic_child, (), "fn_name");
(0..2).map(|i| rsx! { div { "asd {i}" } })
basic_child { } 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 /// A beautiful component
@@ -38,6 +42,12 @@ fn basic_child(cx: Scope) -> Element {
todo!() todo!()
} }
async fn async_component(cx: Scope<'_>) -> Element {
cx.render(rsx! {
div { class: "asd" }
})
}
#[test] #[test]
fn basic_prints() { fn basic_prints() {
let mut dom = VirtualDom::new(basic_template); let mut dom = VirtualDom::new(basic_template);