wip: figure out async syntax
This commit is contained in:
1 parent
591674f701
commit
51aeb29d1a
5 files changed
+73
-26
No files matched your search
@@ -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 ()
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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) };
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user