Props, reconciler fixes, demo fixes
This commit is contained in:
parent
47163c64f9
commit
290b57d336
17 changed files with 284 additions and 190 deletions
|
|
@ -22,9 +22,10 @@ mod parser;
|
|||
mod span;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::{TokenStream as TokenStream2, Literal};
|
||||
use proc_macro2::{Ident, TokenStream as TokenStream2, Literal, Span};
|
||||
use proc_macro_hack::proc_macro_hack;
|
||||
use quote::quote;
|
||||
use syn::{DeriveInput, parse_macro_input};
|
||||
|
||||
use alchemy_styles::cssparser::{Parser, ParserInput, RuleListParser};
|
||||
use alchemy_styles::styles_parser::{Rule, RuleParser};
|
||||
|
|
@ -77,3 +78,30 @@ pub fn styles(input: TokenStream) -> TokenStream {
|
|||
styles
|
||||
})).into()
|
||||
}
|
||||
|
||||
/// Implements a derive macro for automating props setting and conversion.
|
||||
#[proc_macro_derive(Props)]
|
||||
pub fn writable_props_derive(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let name = &input.ident;
|
||||
let name_props = Ident::new(&format!("{}Props", name), Span::call_site());
|
||||
let generics = input.generics;
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
TokenStream::from(quote! {
|
||||
impl #impl_generics #name #ty_generics #where_clause {
|
||||
fn default_props() -> #name_props {
|
||||
#name_props::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics alchemy::ComponentProps for #name #ty_generics #where_clause {
|
||||
fn set_props(&mut self, new_props: &mut Any) {
|
||||
match new_props.downcast_ref::<#name_props>() {
|
||||
Some(props) => { },
|
||||
None => { panic!("Woah there, somehow the wrong props were being passed!"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,8 +125,7 @@ impl Element {
|
|||
let name = key.to_string();
|
||||
let token = TokenTree::Ident(ident::new_raw(&name, key.span()));
|
||||
(name, token, value)
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
let mut attributes = TokenStream::new();
|
||||
let mut styles = TokenStream::new();
|
||||
|
|
@ -159,29 +158,29 @@ impl Element {
|
|||
eprintln_msg += "\nERROR: rebuild with nightly to print source location";
|
||||
}
|
||||
|
||||
//body.extend(quote!(
|
||||
/*element.attrs.#key = Some(#lit.parse().unwrap_or_else(|err| {
|
||||
attributes.extend(quote!(
|
||||
props.#key = #lit.parse().unwrap_or_else(|err| {
|
||||
eprintln!(#eprintln_msg, err);
|
||||
panic!("failed to parse string literal");
|
||||
}));*/
|
||||
//));
|
||||
panic!("Failed to parse string literal");
|
||||
});
|
||||
));
|
||||
},
|
||||
|
||||
value => {
|
||||
let key = key.to_string();
|
||||
let prop = key.to_string();
|
||||
let value = process_value(value);
|
||||
|
||||
if key == "r#styles" {
|
||||
if prop == "r#styles" {
|
||||
styles = quote!(std::convert::Into::into(#value));
|
||||
continue;
|
||||
}
|
||||
|
||||
if key == "r#key" {
|
||||
if prop == "r#key" {
|
||||
continue;
|
||||
}
|
||||
|
||||
attributes.extend(quote!(
|
||||
attributes.insert(#key, std::convert::Into::into(#value));
|
||||
props.#key = std::convert::Into::into(#value);
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -219,19 +218,19 @@ impl Element {
|
|||
|
||||
let component_name = Literal::string(&typename.to_string());
|
||||
|
||||
Ok(quote!(
|
||||
alchemy::RSX::node(#component_name, |key| {
|
||||
Box::new(#typename::constructor(key))
|
||||
}, alchemy::Props::new("".into(), #styles, {
|
||||
let mut attributes = std::collections::HashMap::new();
|
||||
Ok(quote! {
|
||||
alchemy::RSX::node(#component_name, #styles, |key| {
|
||||
Box::new(<#typename as alchemy::Component>::new(key))
|
||||
}, {
|
||||
let props = #typename::default_props();
|
||||
#attributes
|
||||
attributes
|
||||
Box::new(props)
|
||||
}, {
|
||||
let mut children = vec![];
|
||||
#children
|
||||
children
|
||||
}))
|
||||
))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Reference in a new issue