add component support
This commit is contained in:
1 parent
07da854455
commit
a0c7e4d78a
8 files changed
+62
-14
No files matched your search
+18
-1
@@ -21,7 +21,24 @@ fn app(cx: Scope) -> Element {
|
|||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
h1 {
|
h1 {
|
||||||
width: format!("{}px", count),
|
width: format!("{}px", count),
|
||||||
"High-Five counter: {count}"
|
"High-Five counter: {count}",
|
||||||
|
Comp{
|
||||||
|
color: "#083289"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Props)]
|
||||||
|
struct CompProps {
|
||||||
|
color: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn Comp(cx: Scope<CompProps>) -> Element {
|
||||||
|
cx.render(rsx! {
|
||||||
|
h1 {
|
||||||
|
color: cx.props.color,
|
||||||
|
"Hello, from a component!"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -202,11 +202,11 @@ pub fn rsx(s: TokenStream) -> TokenStream {
|
|||||||
#rsx_text.to_string(),
|
#rsx_text.to_string(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
LazyNodes::new(move |factory|{
|
LazyNodes::new(move |__cx|{
|
||||||
let read = rsx_text_index.read();
|
let read = rsx_text_index.read();
|
||||||
if let Some(text) = read.get(&line_num){
|
if let Some(text) = read.get(&line_num){
|
||||||
interpert_rsx(
|
interpert_rsx(
|
||||||
factory,
|
__cx,
|
||||||
&text,
|
&text,
|
||||||
#captured
|
#captured
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ use syn::{
|
|||||||
token, Expr, Ident, LitStr, Result, Token,
|
token, Expr, Ident, LitStr, Result, Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
pub struct Component {
|
pub struct Component {
|
||||||
pub name: syn::Path,
|
pub name: syn::Path,
|
||||||
pub body: Vec<ComponentField>,
|
pub body: Vec<ComponentField>,
|
||||||
@@ -149,11 +150,13 @@ impl ToTokens for Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the struct's fields info
|
// the struct's fields info
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
pub struct ComponentField {
|
pub struct ComponentField {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub content: ContentField,
|
pub content: ContentField,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
pub enum ContentField {
|
pub enum ContentField {
|
||||||
ManExpr(Expr),
|
ManExpr(Expr),
|
||||||
Formatted(LitStr),
|
Formatted(LitStr),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use syn::{
|
|||||||
// =======================================
|
// =======================================
|
||||||
// Parse the VNode::Element type
|
// Parse the VNode::Element type
|
||||||
// =======================================
|
// =======================================
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
pub struct Element {
|
pub struct Element {
|
||||||
pub name: Ident,
|
pub name: Ident,
|
||||||
pub key: Option<LitStr>,
|
pub key: Option<LitStr>,
|
||||||
@@ -189,6 +190,7 @@ impl ToTokens for Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
pub enum ElementAttr {
|
pub enum ElementAttr {
|
||||||
/// attribute: "valuee {}"
|
/// attribute: "valuee {}"
|
||||||
AttrText {
|
AttrText {
|
||||||
@@ -225,6 +227,7 @@ pub enum ElementAttr {
|
|||||||
Meta(String),
|
Meta(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
pub struct ElementAttrNamed {
|
pub struct ElementAttrNamed {
|
||||||
pub el_name: Ident,
|
pub el_name: Ident,
|
||||||
pub attr: ElementAttr,
|
pub attr: ElementAttr,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ Parse
|
|||||||
-> "text {with_args}"
|
-> "text {with_args}"
|
||||||
-> (0..10).map(|f| rsx!("asd")), // <--- notice the comma - must be a complete expr
|
-> (0..10).map(|f| rsx!("asd")), // <--- notice the comma - must be a complete expr
|
||||||
*/
|
*/
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
pub enum BodyNode {
|
pub enum BodyNode {
|
||||||
Element(Element),
|
Element(Element),
|
||||||
Component(Component),
|
Component(Component),
|
||||||
|
|||||||
@@ -83,6 +83,13 @@ impl ToTokens for CapturedContextBuilder {
|
|||||||
iterators,
|
iterators,
|
||||||
captured_expressions,
|
captured_expressions,
|
||||||
} = self;
|
} = self;
|
||||||
|
let compontents_str = components
|
||||||
|
.iter()
|
||||||
|
.map(|comp| comp.to_token_stream().to_string());
|
||||||
|
let components = components.iter().map(|comp| comp);
|
||||||
|
let iterators_str = iterators
|
||||||
|
.iter()
|
||||||
|
.map(|expr| expr.to_token_stream().to_string());
|
||||||
let captured: Vec<_> = attributes
|
let captured: Vec<_> = attributes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, fmt)| fmt.named_args.iter())
|
.map(|(_, fmt)| fmt.named_args.iter())
|
||||||
@@ -99,8 +106,8 @@ impl ToTokens for CapturedContextBuilder {
|
|||||||
captured: IfmtArgs{
|
captured: IfmtArgs{
|
||||||
named_args: vec![#((#captured_names, #captured_expr.to_string())),*]
|
named_args: vec![#((#captured_names, #captured_expr.to_string())),*]
|
||||||
},
|
},
|
||||||
components: vec![#(#components),*],
|
components: vec![#((#compontents_str, #components)),*],
|
||||||
iterators: vec![#(#iterators),*],
|
iterators: vec![#((#iterators_str, #iterators)),*],
|
||||||
expressions: vec![#((#captured_attr_expressions_text, #captured_expressions.to_string())),*],
|
expressions: vec![#((#captured_attr_expressions_text, #captured_expressions.to_string())),*],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -113,9 +120,9 @@ pub struct CapturedContext<'a> {
|
|||||||
// // map of the attribute name and element path to the formated value
|
// // map of the attribute name and element path to the formated value
|
||||||
// pub captured_attribute_values: IfmtArgs,
|
// pub captured_attribute_values: IfmtArgs,
|
||||||
// the only thing we can update in component is the children
|
// the only thing we can update in component is the children
|
||||||
pub components: Vec<VNode<'a>>,
|
pub components: Vec<(&'static str, VNode<'a>)>,
|
||||||
// we can't reasonably interpert iterators, so they are staticly inserted
|
// we can't reasonably interpert iterators, so they are staticly inserted
|
||||||
pub iterators: Vec<VNode<'a>>,
|
pub iterators: Vec<(&'static str, VNode<'a>)>,
|
||||||
// map expression to the value resulting from the expression
|
// map expression to the value resulting from the expression
|
||||||
pub expressions: Vec<(&'static str, String)>,
|
pub expressions: Vec<(&'static str, String)>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use dioxus_core::{Attribute, NodeFactory, VNode};
|
use dioxus_core::{Attribute, NodeFactory, VNode};
|
||||||
use dioxus_rsx::{BodyNode, CallBody, ElementAttr};
|
use dioxus_rsx::{BodyNode, CallBody, Component, ElementAttr};
|
||||||
|
use quote::ToTokens;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use syn::{parse_str, Expr};
|
use syn::{parse2, parse_str, Expr};
|
||||||
|
|
||||||
use crate::attributes::attrbute_to_static_str;
|
use crate::attributes::attrbute_to_static_str;
|
||||||
use crate::captuered_context::{CapturedContext, IfmtArgs};
|
use crate::captuered_context::{CapturedContext, IfmtArgs};
|
||||||
@@ -83,17 +84,21 @@ impl FromStr for InterperedIfmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build<'a>(rsx: CallBody, ctx: CapturedContext, factory: &NodeFactory<'a>) -> VNode<'a> {
|
pub fn build<'a>(
|
||||||
|
rsx: CallBody,
|
||||||
|
mut ctx: CapturedContext<'a>,
|
||||||
|
factory: &NodeFactory<'a>,
|
||||||
|
) -> VNode<'a> {
|
||||||
let children_built = factory.bump().alloc(Vec::new());
|
let children_built = factory.bump().alloc(Vec::new());
|
||||||
for (i, child) in rsx.roots.into_iter().enumerate() {
|
for (i, child) in rsx.roots.into_iter().enumerate() {
|
||||||
children_built.push(build_node(child, &ctx, factory, i.to_string().as_str()));
|
children_built.push(build_node(child, &mut ctx, factory, i.to_string().as_str()));
|
||||||
}
|
}
|
||||||
factory.fragment_from_iter(children_built.iter())
|
factory.fragment_from_iter(children_built.iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_node<'a>(
|
fn build_node<'a>(
|
||||||
node: BodyNode,
|
node: BodyNode,
|
||||||
ctx: &CapturedContext,
|
ctx: &mut CapturedContext<'a>,
|
||||||
factory: &NodeFactory<'a>,
|
factory: &NodeFactory<'a>,
|
||||||
key: &str,
|
key: &str,
|
||||||
) -> Option<VNode<'a>> {
|
) -> Option<VNode<'a>> {
|
||||||
@@ -190,7 +195,19 @@ fn build_node<'a>(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BodyNode::Component(_) => todo!(),
|
BodyNode::Component(comp) => {
|
||||||
|
let expr: Expr = parse2(comp.to_token_stream()).unwrap();
|
||||||
|
if let Some(idx) = ctx
|
||||||
|
.components
|
||||||
|
.iter()
|
||||||
|
.position(|(code, _)| parse_str::<Expr>(*code).unwrap() == expr)
|
||||||
|
{
|
||||||
|
let (_, vnode) = ctx.components.remove(idx);
|
||||||
|
Some(vnode)
|
||||||
|
} else {
|
||||||
|
panic!("could not resolve component {:?}", comp.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
BodyNode::RawExpr(_) => todo!(),
|
BodyNode::RawExpr(_) => todo!(),
|
||||||
BodyNode::Meta(_) => todo!(),
|
BodyNode::Meta(_) => todo!(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ pub fn with_hot_reload(cx: Scope<Component>) -> Element {
|
|||||||
pub fn interpert_rsx<'a, 'b>(
|
pub fn interpert_rsx<'a, 'b>(
|
||||||
factory: dioxus_core::NodeFactory<'a>,
|
factory: dioxus_core::NodeFactory<'a>,
|
||||||
text: &str,
|
text: &str,
|
||||||
context: captuered_context::CapturedContext,
|
context: captuered_context::CapturedContext<'a>,
|
||||||
) -> VNode<'a> {
|
) -> VNode<'a> {
|
||||||
build(parse_str(text).unwrap(), context, &factory)
|
build(parse_str(text).unwrap(), context, &factory)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user