wip: serious refactor with const generics

This commit is contained in:
Jonathan Kelley committed 2021-07-21 22:55:04 -04:00
1 parent 308414f5ef
commit 160d86abbe
16 files changed
+492 -286

No files matched your search

+5 -89
View File
@@ -12,6 +12,7 @@
//! Any errors in using rsx! will likely occur when people start using it, so the first errors must be really helpful.
mod ambiguous;
mod body;
mod component;
mod element;
mod fragment;
@@ -19,97 +20,12 @@ mod node;
// Re-export the namespaces into each other
pub use ambiguous::*;
pub use body::*;
pub use component::*;
pub use element::*;
pub use fragment::*;
pub use node::*;
use crate::util::is_valid_tag;
use proc_macro2::TokenStream as TokenStream2;
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{
parse::{Parse, ParseStream},
Error, Ident, LitStr, Result, Token,
};
pub struct RsxBody {
custom_context: Option<Ident>,
roots: Vec<BodyNode>,
}
impl Parse for RsxBody {
fn parse(input: ParseStream) -> Result<Self> {
// if input.peek(LitStr) {
// return input.parse::<LitStr>()?.parse::<RsxRender>();
// }
// try to parse the first ident and comma
let custom_context =
if input.peek(Token![in]) && input.peek2(Ident) && input.peek3(Token![,]) {
let _ = input.parse::<Token![in]>()?;
let name = input.parse::<Ident>()?;
if is_valid_tag(&name.to_string()) {
return Err(Error::new(
input.span(),
"Custom context cannot be an html element name",
));
} else {
input.parse::<Token![,]>().unwrap();
Some(name)
}
} else {
None
};
let mut body = Vec::new();
let mut children = Vec::new();
let mut manual_props = None;
parse_component_body(
input,
&BodyParseConfig {
allow_children: true,
allow_fields: false,
allow_manual_props: false,
},
&mut body,
&mut children,
&mut manual_props,
)?;
Ok(Self {
roots: children,
custom_context,
})
}
}
impl ToTokens for RsxBody {
fn to_tokens(&self, out_tokens: &mut TokenStream2) {
let inner = if self.roots.len() == 1 {
let inner = &self.roots[0];
quote! {#inner}
} else {
let childs = &self.roots;
quote! { __cx.fragment_from_iter([ #(#childs),* ]) }
};
match &self.custom_context {
// The `in cx` pattern allows directly rendering
Some(ident) => out_tokens.append_all(quote! {
#ident.render(dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
use dioxus_elements::GlobalAttributes;
#inner
}))
}),
// Otherwise we just build the LazyNode wrapper
None => out_tokens.append_all(quote! {
dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
use dioxus_elements::GlobalAttributes;
#inner
})
}),
};
}
}
pub type HTML_OR_RSX = bool;
pub const AS_HTML: bool = true;
pub const AS_RSX: bool = false;