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,
}
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 ()
}
+43 -9
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);