wip: extract to rsx module

This commit is contained in:
Jonathan Kelley committed 2022-01-17 23:02:36 -05:00
1 parent abfac0d59b
commit 174d287062
13 files changed
+3 -302

No files matched your search

+2 -2
View File
@@ -14,7 +14,7 @@ keywords = ["dom", "ui", "gui", "react", "wasm"]
dioxus-core = { path = "./packages/core", version = "^0.1.7" }
dioxus-html = { path = "./packages/html", version = "^0.1.4", optional = true }
dioxus-core-macro = { path = "./packages/core-macro", version = "^0.1.6", optional = true }
dioxus-macro-inner = { path = "./packages/macro-inner", optional = true }
dioxus-macro-inner = { path = "./packages/rsx", optional = true }
dioxus-hooks = { path = "./packages/hooks", version = "^0.1.6", optional = true }
dioxus-web = { path = "./packages/web", version = "^0.0.4", optional = true }
@@ -48,7 +48,7 @@ router = ["dioxus-router"]
members = [
"packages/core",
"packages/core-macro",
"packages/macro-inner",
"packages/rsx",
"packages/html",
"packages/hooks",
"packages/web",
File renamed without changes.
File renamed without changes.
-214
View File
@@ -1,214 +0,0 @@
#![allow(dead_code)]
use proc_macro2::TokenStream;
use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{Data, DeriveInput, Fields, Ident, LitStr, Variant};
const AT_ATTR_IDENT: &str = "at";
const NOT_FOUND_ATTR_IDENT: &str = "not_found";
pub struct Routable {
ident: Ident,
ats: Vec<LitStr>,
variants: Punctuated<Variant, syn::token::Comma>,
not_found_route: Option<Ident>,
}
impl Parse for Routable {
fn parse(input: ParseStream) -> syn::Result<Self> {
let DeriveInput { ident, data, .. } = input.parse()?;
let data = match data {
Data::Enum(data) => data,
Data::Struct(s) => {
return Err(syn::Error::new(
s.struct_token.span(),
"expected enum, found struct",
))
}
Data::Union(u) => {
return Err(syn::Error::new(
u.union_token.span(),
"expected enum, found union",
))
}
};
let (not_found_route, ats) = parse_variants_attributes(&data.variants)?;
Ok(Self {
ident,
variants: data.variants,
ats,
not_found_route,
})
}
}
fn parse_variants_attributes(
variants: &Punctuated<Variant, syn::token::Comma>,
) -> syn::Result<(Option<Ident>, Vec<LitStr>)> {
let mut not_founds = vec![];
let mut ats: Vec<LitStr> = vec![];
let mut not_found_attrs = vec![];
for variant in variants.iter() {
if let Fields::Unnamed(ref field) = variant.fields {
return Err(syn::Error::new(
field.span(),
"only named fields are supported",
));
}
let attrs = &variant.attrs;
let at_attrs = attrs
.iter()
.filter(|attr| attr.path.is_ident(AT_ATTR_IDENT))
.collect::<Vec<_>>();
let attr = match at_attrs.len() {
1 => *at_attrs.first().unwrap(),
0 => {
return Err(syn::Error::new(
variant.span(),
format!(
"{} attribute must be present on every variant",
AT_ATTR_IDENT
),
))
}
_ => {
return Err(syn::Error::new_spanned(
quote! { #(#at_attrs)* },
format!("only one {} attribute must be present", AT_ATTR_IDENT),
))
}
};
let lit = attr.parse_args::<LitStr>()?;
ats.push(lit);
for attr in attrs.iter() {
if attr.path.is_ident(NOT_FOUND_ATTR_IDENT) {
not_found_attrs.push(attr);
not_founds.push(variant.ident.clone())
}
}
}
if not_founds.len() > 1 {
return Err(syn::Error::new_spanned(
quote! { #(#not_found_attrs)* },
format!("there can only be one {}", NOT_FOUND_ATTR_IDENT),
));
}
Ok((not_founds.into_iter().next(), ats))
}
impl Routable {
// fn build_from_path(&self) -> TokenStream {
// let from_path_matches = self.variants.iter().enumerate().map(|(i, variant)| {
// let ident = &variant.ident;
// let right = match &variant.fields {
// Fields::Unit => quote! { Self::#ident },
// Fields::Named(field) => {
// let fields = field.named.iter().map(|it| {
// //named fields have idents
// it.ident.as_ref().unwrap()
// });
// quote! { Self::#ident { #(#fields: params.get(stringify!(#fields))?.parse().ok()?,)* } }
// }
// Fields::Unnamed(_) => unreachable!(), // already checked
// };
// let left = self.ats.get(i).unwrap();
// quote! {
// #left => ::std::option::Option::Some(#right)
// }
// });
// quote! {
// fn from_path(path: &str, params: &::std::collections::HashMap<&str, &str>) -> ::std::option::Option<Self> {
// match path {
// #(#from_path_matches),*,
// _ => ::std::option::Option::None,
// }
// }
// }
// }
// fn build_to_path(&self) -> TokenStream {
// let to_path_matches = self.variants.iter().enumerate().map(|(i, variant)| {
// let ident = &variant.ident;
// let mut right = self.ats.get(i).unwrap().value();
// match &variant.fields {
// Fields::Unit => quote! { Self::#ident => ::std::string::ToString::to_string(#right) },
// Fields::Named(field) => {
// let fields = field
// .named
// .iter()
// .map(|it| it.ident.as_ref().unwrap())
// .collect::<Vec<_>>();
// for field in fields.iter() {
// // :param -> {param}
// // so we can pass it to `format!("...", param)`
// right = right.replace(&format!(":{}", field), &format!("{{{}}}", field))
// }
// quote! {
// Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = #fields),*)
// }
// }
// Fields::Unnamed(_) => unreachable!(), // already checked
// }
// });
// quote! {
// fn to_path(&self) -> ::std::string::String {
// match self {
// #(#to_path_matches),*,
// }
// }
// }
// }
}
pub fn routable_derive_impl(input: Routable) -> TokenStream {
let Routable {
// ats,
// not_found_route,
// ident,
..
} = &input;
// let from_path = input.build_from_path();
// let to_path = input.build_to_path();
quote! {
// #[automatically_derived]
// impl ::dioxus::router::Routable for #ident {
// fn recognize(pathname: &str) -> ::std::option::Option<Self> {
// todo!()
// // ::std::thread_local! {
// // static ROUTER: ::dioxus::router::__macro::Router = ::dioxus::router::__macro::build_router::<#ident>();
// // }
// // let route = ROUTER.with(|router| ::dioxus::router::__macro::recognize_with_router(router, pathname));
// // {
// // let route = ::std::clone::Clone::clone(&route);
// // #cache_thread_local_ident.with(move |val| {
// // *val.borrow_mut() = route;
// // });
// // }
// // route
// }
// }
}
}
-84
View File
@@ -1,84 +0,0 @@
use crate::{rsx::RsxBody, util::is_valid_svg_tag};
use {
proc_macro::TokenStream,
proc_macro2::{Span, TokenStream as TokenStream2},
quote::{quote, ToTokens, TokenStreamExt},
syn::{
ext::IdentExt,
parse::{Parse, ParseStream},
token, Error, Expr, ExprClosure, Ident, LitBool, LitStr, Path, Result, Token,
},
};
// ==============================================
// Parse any stream coming from the html! macro
// ==============================================
pub struct RsxTemplate {
inner: RsxBody,
}
impl Parse for RsxTemplate {
fn parse(s: ParseStream) -> Result<Self> {
if s.peek(LitStr) {
use std::str::FromStr;
let lit = s.parse::<LitStr>()?;
let g = lit.span();
let mut value = lit.value();
if value.ends_with('\n') {
value.pop();
if value.ends_with('\r') {
value.pop();
}
}
let lit = LitStr::new(&value, lit.span());
// panic!("{:#?}", lit);
match lit.parse::<crate::rsx::RsxBody>() {
Ok(r) => Ok(Self { inner: r }),
Err(e) => Err(e),
}
} else {
panic!("Not a str lit")
}
// let t = s.parse::<LitStr>()?;
// let new_stream = TokenStream::from(t.to_s)
// let cx: Ident = s.parse()?;
// s.parse::<Token![,]>()?;
// if elements are in an array, return a bumpalo::collections::Vec rather than a Node.
// let kind = if s.peek(token::Bracket) {
// let nodes_toks;
// syn::bracketed!(nodes_toks in s);
// let mut nodes: Vec<MaybeExpr<Node>> = vec![nodes_toks.parse()?];
// while nodes_toks.peek(Token![,]) {
// nodes_toks.parse::<Token![,]>()?;
// nodes.push(nodes_toks.parse()?);
// }
// NodeOrList::List(NodeList(nodes))
// } else {
// NodeOrList::Node(s.parse()?)
// };
// Ok(HtmlRender { kind })
}
}
impl ToTokens for RsxTemplate {
fn to_tokens(&self, out_tokens: &mut TokenStream2) {
self.inner.to_tokens(out_tokens);
// let new_toks = ToToksCtx::new(&self.kind).to_token_stream();
// // create a lazy tree that accepts a bump allocator
// let final_tokens = quote! {
// dioxus::prelude::LazyNodes::new(move |cx| {
// let bump = &cx.bump();
// #new_toks
// })
// };
// final_tokens.to_tokens(out_tokens);
}
}
@@ -1,5 +1,5 @@
[package]
name = "dioxus-macro-inner"
name = "dioxus-rsx"
version = "0.0.0"
edition = "2018"
File renamed without changes.
@@ -1,5 +1,4 @@
pub mod ifmt;
pub mod inlineprops;
pub mod props;
pub mod router;
pub mod rsx;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.