make fullstack hello world compile

This commit is contained in:
Evan Almloff committed 2024-01-17 16:58:03 -06:00
1 parent 499e81fa82
commit ae3e167cfe
19 files changed
+288 -155

No files matched your search

+39 -16
View File
@@ -5,28 +5,16 @@ pub(crate) type BoxedAnyProps = Box<dyn AnyProps>;
/// A trait for a component that can be rendered.
pub trait AnyProps: 'static {
/// Render the component with the internal props.
fn render(&self) -> RenderReturn;
/// Check if the props are the same as the type erased props of another component.
fn memoize(&self, other: &dyn Any) -> bool;
/// Get the props as a type erased `dyn Any`.
fn props(&self) -> &dyn Any;
/// Duplicate this component into a new boxed component.
fn duplicate(&self) -> BoxedAnyProps;
}
/// Create a new boxed props object.
pub(crate) fn new_any_props<F: ComponentFunction<P, M>, P: Clone + 'static, M: 'static>(
render_fn: F,
memo: fn(&P, &P) -> bool,
props: P,
name: &'static str,
) -> VProps<F, P, M> {
VProps {
render_fn,
memo,
props,
name,
phantom: std::marker::PhantomData,
}
}
/// A component along with the props the component uses to render.
pub struct VProps<F: ComponentFunction<P, M>, P, M> {
render_fn: F,
@@ -36,6 +24,41 @@ pub struct VProps<F: ComponentFunction<P, M>, P, M> {
phantom: std::marker::PhantomData<M>,
}
impl<F: ComponentFunction<P, M>, P: Clone, M> Clone for VProps<F, P, M> {
fn clone(&self) -> Self {
Self {
render_fn: self.render_fn.clone(),
memo: self.memo,
props: self.props.clone(),
name: self.name,
phantom: std::marker::PhantomData,
}
}
}
impl<F: ComponentFunction<P, M> + Clone, P: Clone + 'static, M: 'static> VProps<F, P, M> {
/// Create a [`VProps`] object.
pub fn new(
render_fn: F,
memo: fn(&P, &P) -> bool,
props: P,
name: &'static str,
) -> VProps<F, P, M> {
VProps {
render_fn,
memo,
props,
name,
phantom: std::marker::PhantomData,
}
}
/// Get the current props of the VProps object
pub fn props(&self) -> &P {
&self.props
}
}
impl<F: ComponentFunction<P, M> + Clone, P: Clone + 'static, M: 'static> AnyProps
for VProps<F, P, M>
{
+2 -5
View File
@@ -1,7 +1,4 @@
use crate::{
any_props::{new_any_props, BoxedAnyProps},
innerlude::ScopeState,
};
use crate::{any_props::BoxedAnyProps, innerlude::ScopeState, VProps};
use crate::{arena::ElementId, Element, Event};
use crate::{
innerlude::{ElementRef, EventHandler, MountId},
@@ -529,7 +526,7 @@ impl VComponent {
P: Properties + 'static,
{
let render_fn = component.id();
let props = Box::new(new_any_props(
let props = Box::new(VProps::new(
component,
<P as Properties>::memoize,
props,
+21 -22
View File
@@ -1,7 +1,7 @@
use std::any::Any;
use crate::{
any_props::{new_any_props, AnyProps, VProps},
any_props::{AnyProps, VProps},
properties::ComponentFunction,
VirtualDom,
};
@@ -44,38 +44,37 @@ impl<T: Any + Clone> ClonableAny for T {
}
/// The platform-independent part of the config needed to launch an application.
#[derive(Clone)]
pub struct CrossPlatformConfig<P: AnyProps> {
/// The root component function.
component: P,
/// The contexts to provide to the root component.
root_contexts: Vec<BoxedContext>,
props: P,
// /// The contexts to provide to the root component.
// root_contexts: Vec<BoxedContext>,
}
impl<F: ComponentFunction<Props, M>, Props: Clone + 'static, M: 'static>
CrossPlatformConfig<VProps<F, Props, M>>
{
/// Create a new cross-platform config.
pub fn new(component: F, props: Props, root_contexts: Vec<BoxedContext>) -> Self {
CrossPlatformConfig {
component: new_any_props(component, |_, _| true, props, "root"),
root_contexts,
}
}
}
impl<P: AnyProps> CrossPlatformConfig<P> {}
impl<P: AnyProps> CrossPlatformConfig<P> {
/// Push a new context into the root component's context.
pub fn push_context<T: Any + Clone + 'static>(&mut self, context: T) {
self.root_contexts.push(BoxedContext::new(context));
/// Create a new cross-platform config.
pub fn new(props: P) -> Self {
CrossPlatformConfig {
props,
// root_contexts,
}
}
// /// Push a new context into the root component's context.
// pub fn push_context<T: Any + Clone + 'static>(&mut self, context: T) {
// self.root_contexts.push(BoxedContext::new(context));
// }
/// Build a virtual dom from the config.
pub fn build_vdom(self) -> VirtualDom {
let mut vdom = VirtualDom::new_with_component(self.component);
let mut vdom = VirtualDom::new_with_component(self.props);
for context in self.root_contexts {
vdom.insert_boxed_root_context(context);
}
// for context in self.root_contexts {
// vdom.insert_boxed_root_context(context);
// }
vdom
}
+3 -3
View File
@@ -3,7 +3,7 @@
//! This module provides the primary mechanics to create a hook-based, concurrent VDOM for Rust.
use crate::{
any_props::{new_any_props, AnyProps},
any_props::AnyProps,
arena::ElementId,
innerlude::{
DirtyScope, ElementRef, ErrorBoundary, NoOpMutations, SchedulerMsg, ScopeState, VNodeMount,
@@ -13,7 +13,7 @@ use crate::{
nodes::{Template, TemplateId},
runtime::{Runtime, RuntimeGuard},
scopes::ScopeId,
AttributeValue, BoxedContext, ComponentFunction, Element, Event, Mutations, Task,
AttributeValue, BoxedContext, ComponentFunction, Element, Event, Mutations, Task, VProps,
};
use futures_util::{pin_mut, StreamExt};
use rustc_hash::{FxHashMap, FxHashSet};
@@ -263,7 +263,7 @@ impl VirtualDom {
root: impl ComponentFunction<P, M>,
root_props: P,
) -> Self {
Self::new_with_component(new_any_props(root, |_, _| true, root_props, "root"))
Self::new_with_component(VProps::new(root, |_, _| true, root_props, "root"))
}
/// Create a new virtualdom and build it immediately