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,
|
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 ()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>;
|
||||||
|
|||||||
@@ -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) };
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in new issue
Block a user