From 28bbeb7a9aaca3984be8e500ebdd3c2a5f2b956a Mon Sep 17 00:00:00 2001 From: Johan Smits Date: Fri, 3 Sep 2021 13:51:36 +0200 Subject: [PATCH] Format code --- atomic_hooks/macro/src/lib.rs | 322 ++-- seed_hooks/src/ev_handlers.rs | 93 +- seed_hooks/src/lib.rs | 13 +- seed_hooks/src/reactive_enhancements.rs | 156 +- seed_hooks/src/seed_bind.rs | 35 +- seed_hooks/src/update_el.rs | 2 +- seed_hooks/src/utils.rs | 2 +- seed_styles/seed_style_macros/src/lib.rs | 1377 +++++++++-------- .../seed_style_macros/tests/progress.rs | 2 +- seed_styles/src/lib.rs | 28 +- seed_styles/src/style.rs | 40 +- seed_styles/src/style/composition.rs | 1 - seed_styles/src/style/css_values.rs | 122 +- seed_styles/src/style/from_traits.rs | 20 +- seed_styles/src/style/layout.rs | 10 +- seed_styles/src/style/measures.rs | 38 +- seed_styles/src/style/row_col_layout.rs | 481 ++++-- seed_styles/src/style/theme.rs | 48 +- 18 files changed, 1517 insertions(+), 1273 deletions(-) diff --git a/atomic_hooks/macro/src/lib.rs b/atomic_hooks/macro/src/lib.rs index ca54b5a..95caaef 100644 --- a/atomic_hooks/macro/src/lib.rs +++ b/atomic_hooks/macro/src/lib.rs @@ -1,16 +1,14 @@ - extern crate darling; extern crate proc_macro; -use darling::FromMeta; use self::proc_macro::TokenStream; +use darling::FromMeta; use quote::{format_ident, quote}; // use syn::parse::{Parse, ParseStream, Result}; // use syn::{parse_macro_input, DeriveInput, Expr, ExprArray}; - use syn::{FnArg, ItemFn, Pat}; +use syn::{FnArg, ItemFn, Pat}; // use syn::{Lit, Meta, MetaNameValue}; -use syn::{AttributeArgs}; - +use syn::AttributeArgs; #[derive(Debug, FromMeta)] struct MacroArgs { @@ -23,126 +21,117 @@ struct ReactionMacroArgs { #[darling(default)] existing_state: bool, #[darling(default)] - suspended:bool, + suspended: bool, } - #[proc_macro_attribute] pub fn atom(args: TokenStream, input: TokenStream) -> TokenStream { - let attr_args = syn::parse_macro_input!(args as AttributeArgs); + let attr_args = syn::parse_macro_input!(args as AttributeArgs); let input_fn: ItemFn = syn::parse_macro_input!(input); let vis = input_fn.vis.clone(); - - - - let args = match MacroArgs::from_list(&attr_args){ + let args = match MacroArgs::from_list(&attr_args) { Ok(v) => v, - Err(e) => panic!("{}",e), + Err(e) => panic!("{}", e), }; - - let atom_fn_ident = if args.reversible { format_ident!("atom_reverse") - } else { + } else { format_ident!("atom") }; - + let sig = input_fn.sig.clone(); - let the_outer_type = match input_fn.sig.output { syn::ReturnType::Default => panic!("Your atom MUST return a non-Unit value"), syn::ReturnType::Type(_, the_type) => the_type.clone(), }; - - let the_type = - if args.reversible { + let the_type = if args.reversible { match *the_outer_type { syn::Type::Path(p) => { - if let Some(atom_segment) = p.path.segments.first() { if atom_segment.ident.to_string() != "ReversibleAtom" { panic!("You really need to return an ReversibleAtom wrapped type"); } match &atom_segment.arguments { - syn::PathArguments::AngleBracketed(angle_brack_args) => { - let first_arg = angle_brack_args.args.first().expect("ReversibleAtom should have a first type"); - if let syn::GenericArgument::Type(a_type) = first_arg { - a_type.clone() - } else { - panic!("ReversibleAtom doest hold a type") - } - }, - _ => panic!("ReversibleAtom has no type???") + syn::PathArguments::AngleBracketed(angle_brack_args) => { + let first_arg = angle_brack_args + .args + .first() + .expect("ReversibleAtom should have a first type"); + if let syn::GenericArgument::Type(a_type) = first_arg { + a_type.clone() + } else { + panic!("ReversibleAtom doest hold a type") + } + } + _ => panic!("ReversibleAtom has no type???"), } - } else { + } else { panic!("You do need to return an ReversibleAtom wrapped type"); } - }, + } _ => panic!("You need to return an ReversibleAtom wrapped type"), } - } else { - match *the_outer_type { - syn::Type::Path(p) => { - - if let Some(atom_segment) = p.path.segments.first() { - if atom_segment.ident.to_string() != "Atom" { - panic!("You really need to return an atom wrapped type"); - } - match &atom_segment.arguments { + match *the_outer_type { + syn::Type::Path(p) => { + if let Some(atom_segment) = p.path.segments.first() { + if atom_segment.ident.to_string() != "Atom" { + panic!("You really need to return an atom wrapped type"); + } + match &atom_segment.arguments { syn::PathArguments::AngleBracketed(angle_brack_args) => { - let first_arg = angle_brack_args.args.first().expect("atom should have a first type"); + let first_arg = angle_brack_args + .args + .first() + .expect("atom should have a first type"); if let syn::GenericArgument::Type(a_type) = first_arg { a_type.clone() } else { panic!("atom doest hold a type") } - }, - _ => panic!("Atom has no type???") + } + _ => panic!("Atom has no type???"), + } + } else { + panic!("You do need to return an atom wrapped type"); } - } else { - panic!("You do need to return an atom wrapped type"); } - }, - _ => panic!("You need to return an atom wrapped type"), - } -}; + _ => panic!("You need to return an atom wrapped type"), + } + }; let body = input_fn.block.clone(); - let inputs_iter = &mut input_fn.sig.inputs.iter(); - let mut inputs_iter_3 = inputs_iter.clone(); + let mut inputs_iter_3 = inputs_iter.clone(); + + let inputs_iter_2 = inputs_iter.clone(); - let inputs_iter_2 = inputs_iter.clone(); - - let mut arg_quote; - if let Some(first_arg) = inputs_iter_3.next(){ - arg_quote = quote!(#first_arg,); + if let Some(first_arg) = inputs_iter_3.next() { + arg_quote = quote!(#first_arg,); for input in inputs_iter_3 { arg_quote = quote!(#arg_quote, #input,); } - } - + } + let mut template_quote = quote!(); let mut use_args_quote = quote!(); let mut first = true; for input in inputs_iter_2 { - let arg_name_ident = format_ident!("{}",get_arg_name(input)); - - + let arg_name_ident = format_ident!("{}", get_arg_name(input)); + if first { - template_quote = quote!(#arg_name_ident.clone(),); - use_args_quote = quote!(let #arg_name_ident = #arg_name_ident.clone();); - - first = false; + template_quote = quote!(#arg_name_ident.clone(),); + use_args_quote = quote!(let #arg_name_ident = #arg_name_ident.clone();); + + first = false; } else { template_quote = quote!(#template_quote #arg_name_ident.clone(),); use_args_quote = quote!(#use_args_quote let #arg_name_ident = #arg_name_ident.clone();); @@ -150,17 +139,13 @@ pub fn atom(args: TokenStream, input: TokenStream) -> TokenStream { } let hash_quote = quote!( (CallSite::here(), #template_quote) ); - - let set_inert_with_reverse = if args.reversible { quote!( set_inert_atom_reversible_state_with_id::<#the_type>(value,__id ); ) - } else { + } else { quote!( set_inert_atom_state_with_id::<#the_type>(value,__id );) - }; - + }; - quote!( #vis #sig{ @@ -170,52 +155,45 @@ pub fn atom(args: TokenStream, input: TokenStream) -> TokenStream { let func = move || { #use_args_quote - - - topo::root(||{ - + let context = ReactiveContext::new(__id ); illicit::Layer::new().offer(std::cell::RefCell::new(context) ).enter(|| { - let value = {#body}; #set_inert_with_reverse }) }) - + }; #atom_fn_ident::<#the_type,_>(__id ,func) - - } - ).into() + } + ).into() } - -fn get_arg_name(fnarg : &FnArg) -> String { +fn get_arg_name(fnarg: &FnArg) -> String { match fnarg { - FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), - FnArg::Typed(t) => { - match &*t.pat { - Pat::Ident(syn::PatIdent { ident, .. }) => ident.to_string(), //syn::parse_quote!(&#ident), - _ => unimplemented!("Cannot get arg name"), - } + FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), + FnArg::Typed(t) => { + match &*t.pat { + Pat::Ident(syn::PatIdent { ident, .. }) => ident.to_string(), //syn::parse_quote!(&#ident), + _ => unimplemented!("Cannot get arg name"), } + } } } - #[proc_macro_attribute] pub fn reaction(args: TokenStream, input: TokenStream) -> TokenStream { let attr_args = syn::parse_macro_input!(args as AttributeArgs); - let args = match ReactionMacroArgs::from_list(&attr_args){ + let args = match ReactionMacroArgs::from_list(&attr_args) { Ok(v) => v, - Err(e) => panic!("{}",e), + Err(e) => panic!("{}", e), }; let reaction_suspended_ident = if args.suspended { @@ -223,12 +201,9 @@ pub fn reaction(args: TokenStream, input: TokenStream) -> TokenStream { } else { format_ident!("reaction") }; - + let input_fn: ItemFn = syn::parse_macro_input!(input); - - - let sig = input_fn.sig.clone(); let vis = input_fn.vis.clone(); @@ -237,65 +212,60 @@ pub fn reaction(args: TokenStream, input: TokenStream) -> TokenStream { syn::ReturnType::Type(_, the_type) => the_type.clone(), }; - - let the_type = match *the_outer_type { syn::Type::Path(p) => { - if let Some(atom_segment) = p.path.segments.first() { if atom_segment.ident.to_string() != "Reaction" { panic!("You really need to return an Reaction wrapped type"); } match &atom_segment.arguments { - syn::PathArguments::AngleBracketed(angle_brack_args) => { - let first_arg = angle_brack_args.args.first().expect("Reaction should have a first type"); - if let syn::GenericArgument::Type(a_type) = first_arg { - a_type.clone() - } else { - panic!("Reaction doest hold a type") - } - }, - _ => panic!("Reaction has no type???") + syn::PathArguments::AngleBracketed(angle_brack_args) => { + let first_arg = angle_brack_args + .args + .first() + .expect("Reaction should have a first type"); + if let syn::GenericArgument::Type(a_type) = first_arg { + a_type.clone() + } else { + panic!("Reaction doest hold a type") + } + } + _ => panic!("Reaction has no type???"), } - } else { + } else { panic!("You do need to return an Reaction wrapped type"); } - }, + } _ => panic!("You need to return an Reaction wrapped type"), - }; - - let body = input_fn.block.clone(); let inputs_iter = &mut input_fn.sig.inputs.iter(); - let mut inputs_iter_3 = inputs_iter.clone(); + let mut inputs_iter_3 = inputs_iter.clone(); + + let inputs_iter_2 = inputs_iter.clone(); - let inputs_iter_2 = inputs_iter.clone(); - - let mut arg_quote; - if let Some(first_arg) = inputs_iter_3.next(){ - arg_quote = quote!(#first_arg); + if let Some(first_arg) = inputs_iter_3.next() { + arg_quote = quote!(#first_arg); for input in inputs_iter_3 { arg_quote = quote!(#arg_quote, #input); } - } - + } + let mut template_quote = quote!(); let mut use_args_quote = quote!(); let mut first = true; for input in inputs_iter_2 { - let arg_name_ident = format_ident!("{}",get_arg_name(input)); - - + let arg_name_ident = format_ident!("{}", get_arg_name(input)); + if first { - template_quote = quote!(#arg_name_ident.clone(),); - use_args_quote = quote!(let #arg_name_ident = #arg_name_ident.clone();); - - first = false; + template_quote = quote!(#arg_name_ident.clone(),); + use_args_quote = quote!(let #arg_name_ident = #arg_name_ident.clone();); + + first = false; } else { template_quote = quote!(#template_quote #arg_name_ident.clone(),); use_args_quote = quote!(#use_args_quote let #arg_name_ident = #arg_name_ident.clone();); @@ -312,60 +282,56 @@ pub fn reaction(args: TokenStream, input: TokenStream) -> TokenStream { quote!() }; - - let quote = - quote!( + let quote = quote!( + + #vis #sig{ - #vis #sig{ - - - let __id = return_key_for_type_and_insert_if_required(#hash_quote); - - - if !reactive_state_exists_for_id::<#the_type>(__id ){ - - let func = move || { - #use_args_quote - - - - - - topo::root(||{ - - let mut context = ReactiveContext::new(__id ); - { - - illicit::Layer::new().offer(std::cell::RefCell::new(context) ).enter(|| { - - - #use_existing_state - let value = {#body}; - set_inert_atom_state_with_id::<#the_type>(value,__id ); - // we need to remove dependencies that do nto exist anymore - unlink_dead_links(__id ); - }) - - } - }) - - - + let __id = return_key_for_type_and_insert_if_required(#hash_quote); - }; - - #reaction_suspended_ident::<#the_type,_>(__id ,func) - } else { - Reaction::<#the_type>::new(__id ) + if !reactive_state_exists_for_id::<#the_type>(__id ){ + + let func = move || { + #use_args_quote + + + + + + topo::root(||{ + + let mut context = ReactiveContext::new(__id ); + { + + illicit::Layer::new().offer(std::cell::RefCell::new(context) ).enter(|| { + + + #use_existing_state + let value = {#body}; + set_inert_atom_state_with_id::<#the_type>(value,__id ); + // we need to remove dependencies that do nto exist anymore + unlink_dead_links(__id ); + }) + } - - } - - ); - + }) + + + + + + }; + + + #reaction_suspended_ident::<#the_type,_>(__id ,func) + } else { + Reaction::<#the_type>::new(__id ) + } + + } + + ); quote.into() } - diff --git a/seed_hooks/src/ev_handlers.rs b/seed_hooks/src/ev_handlers.rs index 5c63897..3553b2b 100644 --- a/seed_hooks/src/ev_handlers.rs +++ b/seed_hooks/src/ev_handlers.rs @@ -1,52 +1,39 @@ - -use seed::prelude::*; use crate::state_access::StateAccess; use atomic_hooks::atom::Atom; - +use seed::prelude::*; pub trait StateAccessEventHandlers where T: 'static, { - fn input_ev () + 'static + Clone,Ms : 'static,>( + fn input_ev () + 'static + Clone, Ms: 'static>( &self, event: Ev, func: F, ) -> seed::EventHandler; - fn mouse_ev< - F: FnOnce(&mut T, web_sys::MouseEvent) -> () + 'static + Clone, - Ms : 'static, - >( + fn mouse_ev () + 'static + Clone, Ms: 'static>( &self, event: Ev, func: F, ) -> seed::EventHandler; - - fn on_click< - F: FnOnce(&mut T) -> () + 'static + Clone, - Ms : 'static, - >( + fn on_click () + 'static + Clone, Ms: 'static>( &self, func: F, ) -> seed::EventHandler; - fn on_input< - F: FnOnce(&mut T, String) -> () + 'static + Clone, - Ms : 'static, - >( + fn on_input () + 'static + Clone, Ms: 'static>( &self, func: F, ) -> seed::EventHandler; - } impl StateAccessEventHandlers for StateAccess where T: 'static, { - fn input_ev () + 'static + Clone ,Ms : 'static,>( + fn input_ev () + 'static + Clone, Ms: 'static>( &self, event: Ev, func: F, @@ -57,10 +44,7 @@ where }) } - fn mouse_ev< - F: FnOnce(&mut T, web_sys::MouseEvent) -> () + 'static + Clone, - Ms : 'static, - >( + fn mouse_ev () + 'static + Clone, Ms: 'static>( &self, event: Ev, func: F, @@ -68,44 +52,35 @@ where let accessor = *self; mouse_ev(event, move |m_ev| { accessor.update(|val| func(val, m_ev)); - }) } - fn on_click< - F: FnOnce(&mut T) -> () + 'static + Clone, - Ms : 'static, - >( + fn on_click () + 'static + Clone, Ms: 'static>( &self, func: F, ) -> seed::EventHandler { let accessor = *self; mouse_ev(Ev::Click, move |_| { accessor.update(|val| func(val)); - }) } - fn on_input () + 'static + Clone ,Ms : 'static,>( - &self, - func: F, - ) -> seed::EventHandler { - let accessor = *self; - input_ev(Ev::Input, move |text| { - accessor.update(|val| func(val, text)); - }) - } - - + fn on_input () + 'static + Clone, Ms: 'static>( + &self, + func: F, + ) -> seed::EventHandler { + let accessor = *self; + input_ev(Ev::Input, move |text| { + accessor.update(|val| func(val, text)); + }) + } } - - impl StateAccessEventHandlers for Atom where T: 'static, { - fn input_ev () + 'static + Clone ,Ms : 'static,>( + fn input_ev () + 'static + Clone, Ms: 'static>( &self, event: Ev, func: F, @@ -116,10 +91,7 @@ where }) } - fn mouse_ev< - F: FnOnce(&mut T, web_sys::MouseEvent) -> () + 'static + Clone, - Ms : 'static, - >( + fn mouse_ev () + 'static + Clone, Ms: 'static>( &self, event: Ev, func: F, @@ -127,33 +99,26 @@ where let accessor = *self; mouse_ev(event, move |m_ev| { accessor.update(|val| func(val, m_ev)); - }) } - fn on_click< - F: FnOnce(&mut T) -> () + 'static + Clone, - Ms : 'static, - >( + fn on_click () + 'static + Clone, Ms: 'static>( &self, func: F, ) -> seed::EventHandler { let accessor = *self; mouse_ev(Ev::Click, move |_| { accessor.update(|val| func(val)); - }) } - fn on_input () + 'static + Clone ,Ms : 'static,>( - &self, - func: F, - ) -> seed::EventHandler { - let accessor = *self; - input_ev(Ev::Input, move |text| { - accessor.update(|val| func(val, text)); - }) - } - - + fn on_input () + 'static + Clone, Ms: 'static>( + &self, + func: F, + ) -> seed::EventHandler { + let accessor = *self; + input_ev(Ev::Input, move |text| { + accessor.update(|val| func(val, text)); + }) + } } diff --git a/seed_hooks/src/lib.rs b/seed_hooks/src/lib.rs index 2e70447..e756735 100644 --- a/seed_hooks/src/lib.rs +++ b/seed_hooks/src/lib.rs @@ -1,18 +1,19 @@ mod ev_handlers; - +mod reactive_enhancements; mod seed_bind; mod update_el; mod utils; -mod reactive_enhancements; pub use ev_handlers::StateAccessEventHandlers; -pub use seed_bind::{UpdateElLocal, InputBind}; -pub use update_el::{StateAccessUpdateEl, LocalUpdateEl2}; +pub use reactive_enhancements::ReactiveEnhancements; +pub use seed_bind::{InputBind, UpdateElLocal}; +pub use update_el::{LocalUpdateEl2, StateAccessUpdateEl}; pub use utils::{ - after_render, after_render_once, get_html_element_by_id, //handle_unmount, + after_render, + after_render_once, + get_html_element_by_id, //handle_unmount, request_animation_frame, }; -pub use reactive_enhancements::ReactiveEnhancements; pub use atomic_hooks::*; diff --git a/seed_hooks/src/reactive_enhancements.rs b/seed_hooks/src/reactive_enhancements.rs index 8e9bb8b..36160a4 100644 --- a/seed_hooks/src/reactive_enhancements.rs +++ b/seed_hooks/src/reactive_enhancements.rs @@ -1,118 +1,118 @@ -use seed::{prelude::*,*}; -use atomic_hooks::*; use atomic_hooks::atom::Atom; -use atomic_hooks::state_access::{CloneState, StateAccess}; use atomic_hooks::reversible_atom::ReversibleAtom; +use atomic_hooks::state_access::{CloneState, StateAccess}; +use atomic_hooks::*; +use seed::{prelude::*, *}; pub trait ReactiveEnhancements { - fn debounce_update () + 'static,Ms, Mdl, INodes>(self, timeout: f64, app: Option>, func: F) where - INodes: IntoNodes + 'static,; - - fn throttle_update () + 'static>(self, timeout: f64, func: F) ; + fn debounce_update () + 'static, Ms, Mdl, INodes>( + self, + timeout: f64, + app: Option>, + func: F, + ) where + INodes: IntoNodes + 'static; + + fn throttle_update () + 'static>(self, timeout: f64, func: F); } impl ReactiveEnhancements for Atom where T: 'static, { - fn debounce_update () + 'static,Ms, Mdl, INodes>(self, timeout: f64, app: Option>, func: F)where - INodes: IntoNodes + 'static,{ - + fn debounce_update () + 'static, Ms, Mdl, INodes>( + self, + timeout: f64, + app: Option>, + func: F, + ) where + INodes: IntoNodes + 'static, + { let performance = window() .performance() .expect("performance should be available"); - - let cached_time_accessor = use_state(||{ performance.now()}); + let cached_time_accessor = use_state(|| performance.now()); cached_time_accessor.set(performance.now()); - - + let timeout = gloo_timers::callback::Timeout::new(timeout as u32, move || { if performance.now() - cached_time_accessor.get() > timeout { - self.update(func); - if let Some(app) = app {app.update_with_option(None)}; + if let Some(app) = app { + app.update_with_option(None) + }; } - }); - + timeout.forget(); } - fn throttle_update () + 'static>(self, timeout: f64, func: F){ - + fn throttle_update () + 'static>(self, timeout: f64, func: F) { let performance = window() .performance() .expect("performance should be available"); + let cached_time_accessor = use_state(|| None); - let cached_time_accessor = use_state(||None); - - if let Some(cached_time) = cached_time_accessor.get(){ - if performance.now() - cached_time > timeout { - cached_time_accessor.set(Some(performance.now())); - self.update(func); - } + if let Some(cached_time) = cached_time_accessor.get() { + if performance.now() - cached_time > timeout { + cached_time_accessor.set(Some(performance.now())); + self.update(func); + } } else { self.update(func); cached_time_accessor.set(Some(performance.now())); } - - - } } - impl ReactiveEnhancements for ReversibleAtom where T: 'static + Clone, { - fn debounce_update () + 'static,Ms, Mdl, INodes>(self, timeout: f64, app: Option>, func: F)where - INodes: IntoNodes + 'static,{ - + fn debounce_update () + 'static, Ms, Mdl, INodes>( + self, + timeout: f64, + app: Option>, + func: F, + ) where + INodes: IntoNodes + 'static, + { let performance = window() .performance() .expect("performance should be available"); - - let cached_time_accessor = use_state(||{ performance.now()}); + let cached_time_accessor = use_state(|| performance.now()); cached_time_accessor.set(performance.now()); - - + let timeout = gloo_timers::callback::Timeout::new(timeout as u32, move || { if performance.now() - cached_time_accessor.get() > timeout { - self.update(func); - if let Some(app) = app {app.update_with_option(None)}; + if let Some(app) = app { + app.update_with_option(None) + }; } - }); - + timeout.forget(); } - fn throttle_update () + 'static>(self, timeout: f64, func: F){ - + fn throttle_update () + 'static>(self, timeout: f64, func: F) { let performance = window() .performance() .expect("performance should be available"); + let cached_time_accessor = use_state(|| None); - let cached_time_accessor = use_state(||None); - - if let Some(cached_time) = cached_time_accessor.get(){ - if performance.now() - cached_time > timeout { - cached_time_accessor.set(Some(performance.now())); - self.update(func); - } + if let Some(cached_time) = cached_time_accessor.get() { + if performance.now() - cached_time > timeout { + cached_time_accessor.set(Some(performance.now())); + self.update(func); + } } else { self.update(func); cached_time_accessor.set(Some(performance.now())); } - - - } } @@ -120,54 +120,48 @@ impl ReactiveEnhancements for StateAccess where T: 'static, { - fn debounce_update () + 'static,Ms, Mdl, INodes>(self, timeout: f64, app: Option>, func: F)where - INodes: IntoNodes + 'static,{ - + fn debounce_update () + 'static, Ms, Mdl, INodes>( + self, + timeout: f64, + app: Option>, + func: F, + ) where + INodes: IntoNodes + 'static, + { let performance = window() .performance() .expect("performance should be available"); - let cached_time_accessor = use_state(||{ performance.now()}); + let cached_time_accessor = use_state(|| performance.now()); cached_time_accessor.set(performance.now()); - - + let timeout = gloo_timers::callback::Timeout::new(timeout as u32, move || { if performance.now() - cached_time_accessor.get() > timeout { - self.update(func); - if let Some(app) = app {app.update_with_option(None)}; + if let Some(app) = app { + app.update_with_option(None) + }; } - }); - + timeout.forget(); } - fn throttle_update () + 'static>(self, timeout: f64, func: F) { - + fn throttle_update () + 'static>(self, timeout: f64, func: F) { let performance = window() .performance() .expect("performance should be available"); + let cached_time_accessor = use_state(|| None); - let cached_time_accessor = use_state(||None); - - if let Some(cached_time) = cached_time_accessor.get(){ - if performance.now() - cached_time > timeout { - cached_time_accessor.set(Some(performance.now())); - self.update(func); - } + if let Some(cached_time) = cached_time_accessor.get() { + if performance.now() - cached_time > timeout { + cached_time_accessor.set(Some(performance.now())); + self.update(func); + } } else { self.update(func); cached_time_accessor.set(Some(performance.now())); } - - - } } - - - - - diff --git a/seed_hooks/src/seed_bind.rs b/seed_hooks/src/seed_bind.rs index 5f65dc9..31f02bd 100644 --- a/seed_hooks/src/seed_bind.rs +++ b/seed_hooks/src/seed_bind.rs @@ -1,7 +1,7 @@ +use atomic_hooks::atom::Atom; +use atomic_hooks::state_access::StateAccess; use atomic_hooks::Observable; use seed::{prelude::*, *}; -use atomic_hooks::state_access::StateAccess; -use atomic_hooks::atom::Atom; pub trait UpdateElLocal { fn update_el(self, el: &mut T); @@ -14,16 +14,22 @@ impl UpdateElLocal> for (seed::Attrs, seed::EventHandler) { } } - -pub trait InputBind where Ms: 'static, T: 'static+ std::str::FromStr + std::fmt::Display { - fn bind( self, attr: At) -> (seed::virtual_dom::attrs::Attrs, seed::EventHandler); +pub trait InputBind +where + Ms: 'static, + T: 'static + std::str::FromStr + std::fmt::Display, +{ + fn bind(self, attr: At) -> (seed::virtual_dom::attrs::Attrs, seed::EventHandler); } - -impl InputBind for StateAccess where Ms: 'static, T: 'static+ std::str::FromStr + std::fmt::Display { - fn bind( self, attr: At) -> (seed::virtual_dom::attrs::Attrs, seed::EventHandler){ +impl InputBind for StateAccess +where + Ms: 'static, + T: 'static + std::str::FromStr + std::fmt::Display, +{ + fn bind(self, attr: At) -> (seed::virtual_dom::attrs::Attrs, seed::EventHandler) { let val_disp = self.observe_with(|v| format!("{}", v)); - ( + ( attrs!(attr => val_disp), input_ev(Ev::Input, move |ev| { if let Ok(parsed_type) = ev.parse::() { @@ -34,10 +40,14 @@ impl InputBind for StateAccess where Ms: 'static, T: 'static } } -impl InputBind for Atom where Ms: 'static, T: 'static+ std::str::FromStr + std::fmt::Display { - fn bind( self, attr: At) -> (seed::virtual_dom::attrs::Attrs, seed::EventHandler){ +impl InputBind for Atom +where + Ms: 'static, + T: 'static + std::str::FromStr + std::fmt::Display, +{ + fn bind(self, attr: At) -> (seed::virtual_dom::attrs::Attrs, seed::EventHandler) { let val_disp = self.observe_with(|v| format!("{}", v)); - ( + ( attrs!(attr => val_disp), input_ev(Ev::Input, move |ev| { if let Ok(parsed_type) = ev.parse::() { @@ -47,4 +57,3 @@ impl InputBind for Atom where Ms: 'static, T: 'static+ std:: ) } } - diff --git a/seed_hooks/src/update_el.rs b/seed_hooks/src/update_el.rs index b97631d..5edb1f7 100644 --- a/seed_hooks/src/update_el.rs +++ b/seed_hooks/src/update_el.rs @@ -1,5 +1,5 @@ +use atomic_hooks::state_access::{CloneState, StateAccess}; use seed::prelude::*; -use atomic_hooks::state_access::{StateAccess, CloneState}; pub trait StateAccessUpdateEl { fn update_el(self, el: &mut T); diff --git a/seed_hooks/src/utils.rs b/seed_hooks/src/utils.rs index e27ff5a..8c9ec25 100644 --- a/seed_hooks/src/utils.rs +++ b/seed_hooks/src/utils.rs @@ -1,9 +1,9 @@ +use atomic_hooks::state_access::StateAccess; use atomic_hooks::{do_once, topo}; use seed::{prelude::*, *}; use std::cell::RefCell; use std::rc::Rc; use wasm_bindgen::JsCast; -use atomic_hooks::state_access::StateAccess; #[topo::nested] pub fn after_render_once () + 'static + Clone>(func: F) -> StateAccess { diff --git a/seed_styles/seed_style_macros/src/lib.rs b/seed_styles/seed_style_macros/src/lib.rs index fceb02a..0b3eb04 100644 --- a/seed_styles/seed_style_macros/src/lib.rs +++ b/seed_styles/seed_style_macros/src/lib.rs @@ -4,8 +4,8 @@ use self::proc_macro::TokenStream; use heck::CamelCase; use heck::KebabCase; use heck::SnakeCase; -use std::cell::RefCell; use quote::{format_ident, quote}; +use std::cell::RefCell; use syn::parse::{Parse, ParseStream, Result}; use syn::{parse_macro_input, DeriveInput, Expr, ExprArray}; use syn::{FnArg, ItemFn, Pat}; @@ -137,11 +137,11 @@ pub fn expand(input: TokenStream) -> TokenStream { fn prefixes(&self) -> Option>{ #inner_vendor_prefixes_quote } - + }; } - let css_property_name = format!("{}:",snake_case_type_ident.to_string().to_kebab_case()); + let css_property_name = format!("{}:", snake_case_type_ident.to_string().to_kebab_case()); let update_style_quote = quote! { impl CssValueTrait for #css_type_name{ @@ -201,7 +201,7 @@ pub fn expand(input: TokenStream) -> TokenStream { quote! { fn #f_small_name_ident(self) -> Style; fn #short_prop_ident(self) -> Style; - + } } else { quote! { @@ -216,7 +216,7 @@ pub fn expand(input: TokenStream) -> TokenStream { #func_impls_defn )* - + #base_defn_quote @@ -281,7 +281,7 @@ pub fn expand(input: TokenStream) -> TokenStream { impl #trait_name_ident for Style { #(#func_impls)* #base_impl_quote - + } }; @@ -391,14 +391,14 @@ pub fn expand_pseudo(input: TokenStream) -> TokenStream { impl PseudoTrait for Style { #(#func_impls)* - + fn pseudo(mut self, val: &str) -> Style { self.updated_at.push(format!("{}", Location::caller())); self.pseudo = Pseudo::Custom(val.to_string()); self } - + fn lang(mut self, val: &str) -> Style { self.updated_at.push(format!("{}", Location::caller())); self.pseudo = Pseudo::Lang(val.to_string()); @@ -969,8 +969,8 @@ pub fn create_enums(input: TokenStream) -> TokenStream { // msg_type: syn::Ident, // } -fn get_arg_name(fnarg : &FnArg) -> String { -match fnarg { +fn get_arg_name(fnarg: &FnArg) -> String { + match fnarg { FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), FnArg::Typed(t) => { match &*t.pat { @@ -978,379 +978,428 @@ match fnarg { _ => unimplemented!("Cannot get arg name"), } } + } } -} - -fn get_single_type_name(fnarg : &FnArg) -> String { +fn get_single_type_name(fnarg: &FnArg) -> String { match fnarg { - FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), - FnArg::Typed(t) => { - // panic!("{:#?}", t); - match &*t.ty { - syn::Type::Path(syn::TypePath { path, .. }) => { - // panic!("{:#?}", path); - let path = path.get_ident().expect("Are you sure you have passed in an argument struct"); - path.to_string() - }, //syn::parse_quote!(&#ident), - _ => unimplemented!("cannot get single type name"), - } + FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), + FnArg::Typed(t) => { + // panic!("{:#?}", t); + match &*t.ty { + syn::Type::Path(syn::TypePath { path, .. }) => { + // panic!("{:#?}", path); + let path = path + .get_ident() + .expect("Are you sure you have passed in an argument struct"); + path.to_string() + } //syn::parse_quote!(&#ident), + _ => unimplemented!("cannot get single type name"), } + } } - } - +} -fn get_node_msg_type_name(fnarg : &FnArg) -> String { +fn get_node_msg_type_name(fnarg: &FnArg) -> String { match fnarg { - FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), - FnArg::Typed(t) => { - // panic!("{:#?}", t); - match &*t.ty { - syn::Type::Path(syn::TypePath { path, .. }) => { - let segment = path.segments.last().expect("segment to exist"); - match &segment.arguments { - syn::PathArguments::AngleBracketed(generic_args) => { - match generic_args.args.first().expect("generic args to exist"){ - syn::GenericArgument::Type(syn::Type::Path(type_path)) => { - let ident = type_path.path.get_ident().expect("generic argument ident to exist"); - ident.to_string() - } - _ => unimplemented!() + FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), + FnArg::Typed(t) => { + // panic!("{:#?}", t); + match &*t.ty { + syn::Type::Path(syn::TypePath { path, .. }) => { + let segment = path.segments.last().expect("segment to exist"); + match &segment.arguments { + syn::PathArguments::AngleBracketed(generic_args) => { + match generic_args.args.first().expect("generic args to exist") { + syn::GenericArgument::Type(syn::Type::Path(type_path)) => { + let ident = type_path + .path + .get_ident() + .expect("generic argument ident to exist"); + ident.to_string() } - // syn::Type::Path(path) => {} - // _ => unimplemented!(), - // } + _ => unimplemented!(), } - _ => unimplemented!() + // syn::Type::Path(path) => {} + // _ => unimplemented!(), + // } } + _ => unimplemented!(), + } - - // let path = path.get_ident().unwrap(); - - // path.to_string(); - - - }, //syn::parse_quote!(&#ident), - _ => unimplemented!("Cannot get node msg type name"), - } + // let path = path.get_ident().unwrap(); + + // path.to_string(); + } //syn::parse_quote!(&#ident), + _ => unimplemented!("Cannot get node msg type name"), } + } } - } +} - -fn is_option_type(fnarg : &FnArg) -> bool { +fn is_option_type(fnarg: &FnArg) -> bool { match fnarg { - FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), - FnArg::Typed(t) => { - // panic!("{:#?}", t); - match &*t.ty { - syn::Type::Path(syn::TypePath { path, .. }) => { - let segment = path.segments.last().expect("segment to exist"); - // panic!("{:#?}", segment); - if segment.ident.to_string() != "Node" && segment.ident.to_string() != "Option" && segment.ident.to_string() != "Vec" { - panic!("Node type is not Node, Vec or Option") - } + FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), + FnArg::Typed(t) => { + // panic!("{:#?}", t); + match &*t.ty { + syn::Type::Path(syn::TypePath { path, .. }) => { + let segment = path.segments.last().expect("segment to exist"); + // panic!("{:#?}", segment); + if segment.ident.to_string() != "Node" + && segment.ident.to_string() != "Option" + && segment.ident.to_string() != "Vec" + { + panic!("Node type is not Node, Vec or Option") + } - if segment.ident.to_string() == "Option" { - match &segment.arguments { - syn::PathArguments::AngleBracketed(generic_args) => { - match generic_args.args.first().expect("generic args to exist"){ - syn::GenericArgument::Type(syn::Type::Path(type_path)) => { - if type_path.path.segments.first().expect("option to have a type").ident.to_string()!="Node" { - panic!("Option does not contain a Node or a tuple") - } + if segment.ident.to_string() == "Option" { + match &segment.arguments { + syn::PathArguments::AngleBracketed(generic_args) => { + match generic_args.args.first().expect("generic args to exist") { + syn::GenericArgument::Type(syn::Type::Path(type_path)) => { + if type_path + .path + .segments + .first() + .expect("option to have a type") + .ident + .to_string() + != "Node" + { + panic!("Option does not contain a Node or a tuple") } - syn::GenericArgument::Type(syn::Type::Tuple(syn::TypeTuple{elems,..})) => { - - if let Some(the_type) = elems.first() { - match the_type { - syn::Type::Path(syn::TypePath { path, .. }) => { - if path.segments.first().expect("option to have a type").ident.to_string()!="Node" { - panic!("First argument to tuple is not a Node") - } + } + syn::GenericArgument::Type(syn::Type::Tuple( + syn::TypeTuple { elems, .. }, + )) => { + if let Some(the_type) = elems.first() { + match the_type { + syn::Type::Path(syn::TypePath { path, .. }) => { + if path + .segments + .first() + .expect("option to have a type") + .ident + .to_string() + != "Node" + { + panic!( + "First argument to tuple is not a Node" + ) } - _ => unimplemented!() } - - - + _ => unimplemented!(), + } } else { - panic!("tuple doesnt have 2 arguments") - } - } - _ => unimplemented!() + panic!("tuple doesnt have 2 arguments") + } } - // syn::Type::Path(path) => {} - // _ => unimplemented!(), - // } + _ => unimplemented!(), } - - _ => unimplemented!() - } - true - } else { - if segment.ident.to_string() != "Node" && segment.ident.to_string() != "Vec"{ - panic!("argument type is not Node or Vec") + // syn::Type::Path(path) => {} + // _ => unimplemented!(), + // } } - false + + _ => unimplemented!(), } + true + } else { + if segment.ident.to_string() != "Node" && segment.ident.to_string() != "Vec" + { + panic!("argument type is not Node or Vec") + } + false + } - - // let path = path.get_ident().unwrap(); - - // path.to_string(); - - - }, //syn::parse_quote!(&#ident), - syn::Type::Tuple(_) =>false, - exp => unimplemented!("Cannot get option type this was passed instead: {:#?}", exp), - } + // let path = path.get_ident().unwrap(); + + // path.to_string(); + } //syn::parse_quote!(&#ident), + syn::Type::Tuple(_) => false, + exp => unimplemented!("Cannot get option type this was passed instead: {:#?}", exp), } + } } - } - +} - fn get_sub_arg_type(fnarg: &FnArg) -> Option { - match fnarg { - FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), - FnArg::Typed(t) => { - // panic!("{:#?}", t); - match &*t.ty { - syn::Type::Path(syn::TypePath { path, .. }) => { - let segment = path.segments.last().expect("segment to exist"); - // panic!("{:#?}", segment); - if segment.ident.to_string() != "Node" && segment.ident.to_string() != "Option" && segment.ident.to_string() != "Vec" { - panic!("Node type is not Node, Vec or Option") - } +fn get_sub_arg_type(fnarg: &FnArg) -> Option { + match fnarg { + FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), + FnArg::Typed(t) => { + // panic!("{:#?}", t); + match &*t.ty { + syn::Type::Path(syn::TypePath { path, .. }) => { + let segment = path.segments.last().expect("segment to exist"); + // panic!("{:#?}", segment); + if segment.ident.to_string() != "Node" + && segment.ident.to_string() != "Option" + && segment.ident.to_string() != "Vec" + { + panic!("Node type is not Node, Vec or Option") + } - if segment.ident.to_string() == "Option" { - match &segment.arguments { - syn::PathArguments::AngleBracketed(generic_args) => { - match generic_args.args.first().expect("generic args to exist"){ - syn::GenericArgument::Type(syn::Type::Tuple(syn::TypeTuple{elems,..})) => { - if let Some(the_type) = elems.first() { - - match the_type { - syn::Type::Path(syn::TypePath { path, .. }) => { - if path.segments.first().expect("option to have a type").ident.to_string()!="Node" { - panic!("first arg not node"); - } + if segment.ident.to_string() == "Option" { + match &segment.arguments { + syn::PathArguments::AngleBracketed(generic_args) => { + match generic_args.args.first().expect("generic args to exist") { + syn::GenericArgument::Type(syn::Type::Tuple( + syn::TypeTuple { elems, .. }, + )) => { + if let Some(the_type) = elems.first() { + match the_type { + syn::Type::Path(syn::TypePath { path, .. }) => { + if path + .segments + .first() + .expect("option to have a type") + .ident + .to_string() + != "Node" + { + panic!("first arg not node"); } - _ => unimplemented!() } - + _ => unimplemented!(), + } } else { - panic!("tuple doesnt have 2 arguments") - } - - if let Some(the_type) = elems.last() { - match the_type { - syn::Type::Path(syn::TypePath { path, .. }) => { - let path = path.get_ident().expect("Are you sure you have passed in an argument struct"); - Some(path.clone()) - } - _ => unimplemented!() + panic!("tuple doesnt have 2 arguments") + } + + if let Some(the_type) = elems.last() { + match the_type { + syn::Type::Path(syn::TypePath { path, .. }) => { + let path = path.get_ident().expect("Are you sure you have passed in an argument struct"); + Some(path.clone()) } + _ => unimplemented!(), + } } else { None - } - } - - _ => None + } } - // syn::Type::Path(path) => {} - // _ => unimplemented!(), - // } + + _ => None, } - _ => None + // syn::Type::Path(path) => {} + // _ => unimplemented!(), + // } } - } else if segment.ident.to_string() == "Vec" { - match &segment.arguments { - syn::PathArguments::AngleBracketed(generic_args) => { - match generic_args.args.first().expect("generic args to exist"){ - syn::GenericArgument::Type(syn::Type::Tuple(syn::TypeTuple{elems,..})) => { - if let Some(the_type) = elems.first() { - - match the_type { - syn::Type::Path(syn::TypePath { path, .. }) => { - if path.segments.first().expect("vec to have a type").ident.to_string()!="Node" { - panic!("first arg not node"); - } + _ => None, + } + } else if segment.ident.to_string() == "Vec" { + match &segment.arguments { + syn::PathArguments::AngleBracketed(generic_args) => { + match generic_args.args.first().expect("generic args to exist") { + syn::GenericArgument::Type(syn::Type::Tuple( + syn::TypeTuple { elems, .. }, + )) => { + if let Some(the_type) = elems.first() { + match the_type { + syn::Type::Path(syn::TypePath { path, .. }) => { + if path + .segments + .first() + .expect("vec to have a type") + .ident + .to_string() + != "Node" + { + panic!("first arg not node"); } - _ => unimplemented!() } - + _ => unimplemented!(), + } } else { - panic!("tuple doesnt have 2 arguments") - } - - if let Some(the_type) = elems.last() { - match the_type { - syn::Type::Path(syn::TypePath { path, .. }) => { - let path = path.get_ident().expect("Are you sure you have passed in an argument struct"); - Some(path.clone()) - } - _ => unimplemented!() + panic!("tuple doesnt have 2 arguments") + } + + if let Some(the_type) = elems.last() { + match the_type { + syn::Type::Path(syn::TypePath { path, .. }) => { + let path = path.get_ident().expect("Are you sure you have passed in an argument struct"); + Some(path.clone()) } + _ => unimplemented!(), + } } else { None - } - } - - _ => None + } } - // syn::Type::Path(path) => {} - // _ => unimplemented!(), - // } + + _ => None, } - _ => None - } - } else { - if segment.ident.to_string() != "Node" && segment.ident.to_string() != "Vec"{ - panic!("argument type is not Node or Vec") + // syn::Type::Path(path) => {} + // _ => unimplemented!(), + // } } - None + _ => None, + } + } else { + if segment.ident.to_string() != "Node" && segment.ident.to_string() != "Vec" + { + panic!("argument type is not Node or Vec") } + None + } - - // let path = path.get_ident().unwrap(); - - // path.to_string(); - - - }, //syn::parse_quote!(&#ident), - - - syn::Type::Tuple(syn::TypeTuple{elems, ..}) => { - - if let Some(the_type) = elems.last() { - match the_type { - syn::Type::Path(syn::TypePath { path, .. }) => { - let path = path.get_ident().expect("Are you sure you have passed in an argument struct"); - Some(path.clone()) - } - _ => unimplemented!() + // let path = path.get_ident().unwrap(); + + // path.to_string(); + } //syn::parse_quote!(&#ident), + + syn::Type::Tuple(syn::TypeTuple { elems, .. }) => { + if let Some(the_type) = elems.last() { + match the_type { + syn::Type::Path(syn::TypePath { path, .. }) => { + let path = path + .get_ident() + .expect("Are you sure you have passed in an argument struct"); + Some(path.clone()) } + _ => unimplemented!(), + } } else { None } - }, - _ => None, + } + _ => None, } } } } - - -fn is_vec_type(fnarg : &FnArg) -> bool { +fn is_vec_type(fnarg: &FnArg) -> bool { match fnarg { - FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), - FnArg::Typed(t) => { - match &*t.ty { - syn::Type::Path(syn::TypePath { path, .. }) => { - let segment = path.segments.last().expect("segment to exist"); - // panic!("{:#?}", segment); - if segment.ident.to_string() != "Node" && segment.ident.to_string() != "Vec" && segment.ident.to_string() != "Option"{ - panic!("Node type is not Node or Vec") - } + FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), + FnArg::Typed(t) => { + match &*t.ty { + syn::Type::Path(syn::TypePath { path, .. }) => { + let segment = path.segments.last().expect("segment to exist"); + // panic!("{:#?}", segment); + if segment.ident.to_string() != "Node" + && segment.ident.to_string() != "Vec" + && segment.ident.to_string() != "Option" + { + panic!("Node type is not Node or Vec") + } - if segment.ident.to_string() == "Vec" { - match &segment.arguments { - syn::PathArguments::AngleBracketed(generic_args) => { - match generic_args.args.first().expect("generic args to exist"){ - syn::GenericArgument::Type(syn::Type::Path(type_path)) => { - if type_path.path.segments.first().expect("Vec to have a type").ident.to_string()!="Node" { - panic!("Vec does not contain a Node") - } + if segment.ident.to_string() == "Vec" { + match &segment.arguments { + syn::PathArguments::AngleBracketed(generic_args) => { + match generic_args.args.first().expect("generic args to exist") { + syn::GenericArgument::Type(syn::Type::Path(type_path)) => { + if type_path + .path + .segments + .first() + .expect("Vec to have a type") + .ident + .to_string() + != "Node" + { + panic!("Vec does not contain a Node") } - syn::GenericArgument::Type(syn::Type::Tuple(syn::TypeTuple{elems,..})) => { - - if let Some(the_type) = elems.first() { - match the_type { - syn::Type::Path(syn::TypePath { path, .. }) => { - if path.segments.first().expect("option to have a type").ident.to_string()!="Node" { - panic!("First argument to tuple is not a Node") - } + } + syn::GenericArgument::Type(syn::Type::Tuple( + syn::TypeTuple { elems, .. }, + )) => { + if let Some(the_type) = elems.first() { + match the_type { + syn::Type::Path(syn::TypePath { path, .. }) => { + if path + .segments + .first() + .expect("option to have a type") + .ident + .to_string() + != "Node" + { + panic!( + "First argument to tuple is not a Node" + ) } - _ => unimplemented!() } - - - + _ => unimplemented!(), + } } else { - panic!("tuple doesnt have 2 arguments") - } - } - _ => unimplemented!() + panic!("tuple doesnt have 2 arguments") + } } + _ => unimplemented!(), } - - _ => unimplemented!() - } - true - } else { - if segment.ident.to_string() != "Node" && segment.ident.to_string() != "Option"{ - panic!("argument type is not Node or Option") } - false + + _ => unimplemented!(), + } + true + } else { + if segment.ident.to_string() != "Node" + && segment.ident.to_string() != "Option" + { + panic!("argument type is not Node or Option") } - - }, - syn::Type::Tuple(_) =>false, - _ => unimplemented!("Cannot get vec type"), + false + } } + syn::Type::Tuple(_) => false, + _ => unimplemented!("Cannot get vec type"), } + } } - } - - - fn assert_children_have_vec_structure(fnarg : &FnArg) { - match fnarg { - FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), - FnArg::Typed(t) => { - // panic!("{:#?}", t); - match &*t.ty { - syn::Type::Path(syn::TypePath { path, .. }) => { - let segment = path.segments.last().expect("segment to exist"); - // panic!("{:#?}", segment); - if segment.ident.to_string() != "Vec" { - panic!("Children need to have Vec> type!") - } else { - match &segment.arguments { - syn::PathArguments::AngleBracketed(generic_args) => { - match generic_args.args.first().expect("generic args to exist"){ - syn::GenericArgument::Type(syn::Type::Path(type_path)) => { - if type_path.path.segments.first().expect("vec to have a type").ident.to_string()!="Node" { - panic!("Vec does not contain a Node") - } - } - _ => unimplemented!() +} + +fn assert_children_have_vec_structure(fnarg: &FnArg) { + match fnarg { + FnArg::Receiver(_) => panic!("cannot be a method with self receiver"), + FnArg::Typed(t) => { + // panic!("{:#?}", t); + match &*t.ty { + syn::Type::Path(syn::TypePath { path, .. }) => { + let segment = path.segments.last().expect("segment to exist"); + // panic!("{:#?}", segment); + if segment.ident.to_string() != "Vec" { + panic!("Children need to have Vec> type!") + } else { + match &segment.arguments { + syn::PathArguments::AngleBracketed(generic_args) => { + match generic_args.args.first().expect("generic args to exist") { + syn::GenericArgument::Type(syn::Type::Path(type_path)) => { + if type_path + .path + .segments + .first() + .expect("vec to have a type") + .ident + .to_string() + != "Node" + { + panic!("Vec does not contain a Node") } } - _ => unimplemented!() + _ => unimplemented!(), } } - - }, - _ => unimplemented!("Cannot check children"), + _ => unimplemented!(), + } } } + _ => unimplemented!("Cannot check children"), + } } - } - + } +} - thread_local! { static COUNTER: RefCell = RefCell::new(1); } -#[track_caller] +#[track_caller] #[proc_macro_attribute] pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { - let mut input_fn: ItemFn = syn::parse_macro_input!(input); - + if !input_fn.sig.ident.to_string().ends_with("_view") { panic!("Your function name needs to end with _view"); } @@ -1365,8 +1414,6 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { *c }); - - let view_ident_long = format_ident!("{}_{}", view_ident_string, location.to_string()); let view_ident = format_ident!("{}", view_ident_string); @@ -1378,8 +1425,8 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { let mut children_used = true; // Allow us to iter over the view arguments in turn. - let has_args = if let Some(first_arg) = &input_fn.sig.inputs.first(){ - if get_arg_name(first_arg) == "root" || get_arg_name(first_arg) == "_root" { + let has_args = if let Some(first_arg) = &input_fn.sig.inputs.first() { + if get_arg_name(first_arg) == "root" || get_arg_name(first_arg) == "_root" { false } else { true @@ -1392,15 +1439,14 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { let mut view_args_ident = None; if has_args { - if let Some(view_args_fn_arg) = input_iter.next(){ - view_args_ident = Some(format_ident!("{}",get_single_type_name(view_args_fn_arg))) + if let Some(view_args_fn_arg) = input_iter.next() { + view_args_ident = Some(format_ident!("{}", get_single_type_name(view_args_fn_arg))) } else { panic!("Cannot determine the type for view arguments. If your view does not have any arguments pass the () type.") }; } - let msg_type_ident = if let Some(root_fn_arg) = input_iter.next(){ - + let msg_type_ident = if let Some(root_fn_arg) = input_iter.next() { let argument_name = get_arg_name(root_fn_arg); if (argument_name != "root") && (argument_name != "_root") { panic!("the first Node argument must be root or _root") @@ -1408,15 +1454,14 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { if argument_name == "_root" { root_ident = format_ident!("_root"); } - format_ident!("{}",get_node_msg_type_name(root_fn_arg)) - + format_ident!("{}", get_node_msg_type_name(root_fn_arg)) } else { panic!("Cannot determine the Msg type for this seed view, are you sure you are returning Node>") }; let view_builder = format_ident!("{}Builder", view_ident_string.to_camel_case()); - if let Some(children_arg) = input_iter.next(){ + if let Some(children_arg) = input_iter.next() { let argument_name = get_arg_name(children_arg); if (argument_name != "children") && (argument_name != "_children") { panic!("The argument after root must be 'children' or '_children'") @@ -1427,7 +1472,6 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { if argument_name == "_children" { children_used = false; } - }; let mut vec_of_args = vec![]; @@ -1438,8 +1482,8 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { let mut use_shortcuts = quote!(); for input in &mut input_iter { - let arg_name = format_ident!("{}",get_arg_name(input)); - let qualified_arg_name = format_ident!("{}_{}", view_ident ,get_arg_name(input)); + let arg_name = format_ident!("{}", get_arg_name(input)); + let qualified_arg_name = format_ident!("{}_{}", view_ident, get_arg_name(input)); // let arg_name_long = format_ident!( "{}_{}_{}", view_ident ,get_arg_name(input), location ); use_shortcuts = quote!( @@ -1447,21 +1491,24 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { use #qualified_arg_name as #arg_name; ); - vec_of_all_args.push( arg_name.clone() ); - - vec_of_args.push( (arg_name.clone() , is_option_type(input), is_vec_type(input), get_sub_arg_type(input) ) ); + vec_of_all_args.push(arg_name.clone()); + + vec_of_args.push(( + arg_name.clone(), + is_option_type(input), + is_vec_type(input), + get_sub_arg_type(input), + )); if is_option_type(input) { - vec_of_optional_args.push( arg_name.clone() ); + vec_of_optional_args.push(arg_name.clone()); } if is_vec_type(input) { - vec_of_vec_args.push( arg_name.clone() ); + vec_of_vec_args.push(arg_name.clone()); } } - - let mut view_builder_inner_quote = quote! { pub root: Node<#msg_type_ident>,}; let mut view_builder_empty_impl_inner_quote = quote! {root: div![],}; let mut view_function_call_impl_inner_quote = if has_args { @@ -1471,14 +1518,17 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { }; for (name, optional, is_a_vec, maybe_arg_type) in vec_of_args.iter() { - let new_line = match (*optional, *is_a_vec, maybe_arg_type) { - (true, false, Some(arg_type)) => quote! { #name: Option<(Node<#msg_type_ident>, #arg_type)>,}, + (true, false, Some(arg_type)) => { + quote! { #name: Option<(Node<#msg_type_ident>, #arg_type)>,} + } (false, false, Some(arg_type)) => quote! { #name: (Node<#msg_type_ident>, #arg_type),}, - (false, true , Some(arg_type)) => quote! { #name: Vec<(Node<#msg_type_ident>, #arg_type)>,}, + (false, true, Some(arg_type)) => { + quote! { #name: Vec<(Node<#msg_type_ident>, #arg_type)>,} + } (true, false, None) => quote! { #name: Option>,}, (false, false, None) => quote! { #name: Node<#msg_type_ident>,}, - (false, true , None) => quote! { #name: Vec>,}, + (false, true, None) => quote! { #name: Vec>,}, (true, true, _) => panic!("You should never have an optional vec arg"), }; @@ -1488,30 +1538,26 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { }; let new_line = match (*optional, *is_a_vec, maybe_arg_type) { - (true, false, Some(_arg_type)) => quote! { #name: None,}, + (true, false, Some(_arg_type)) => quote! { #name: None,}, (false, false, Some(arg_type)) => quote! { #name: (empty![], #arg_type::default() ),}, - (false, true , Some(_arg_type)) =>quote! { #name: vec![],}, - (true, false, None) => quote! { #name: None,}, - (false, false, None) => quote! { #name: empty![],}, - (false, true, None) => quote! { #name: vec![],}, + (false, true, Some(_arg_type)) => quote! { #name: vec![],}, + (true, false, None) => quote! { #name: None,}, + (false, false, None) => quote! { #name: empty![],}, + (false, true, None) => quote! { #name: vec![],}, (true, true, _) => panic!("You should never have an optional vec arg"), }; - view_builder_empty_impl_inner_quote = quote! { #view_builder_empty_impl_inner_quote #new_line }; - // view_builder_update_el_defn_quote = quote! { // trait UpdateEl#view_builder { // fn update_el(self, &mut el:El); // } // }; - - // view_builder_update_el_impl_quote = quote! { // impl UpdateEl#view_builder for { // fn update_el(self, &mut el:El){} @@ -1525,7 +1571,7 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { // quote! { self.#name, } // }; - let new_line = quote!{ self.#name, }; + let new_line = quote! { self.#name, }; view_function_call_impl_inner_quote = quote! { #view_function_call_impl_inner_quote @@ -1535,7 +1581,7 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { let view_render_impl_quote = if children_used { quote!( - let children = + let children = match &mut self.root { seed::virtual_dom::node::Node::Element(ref mut el) => { std::mem::replace(&mut el.children, vec![]) @@ -1552,9 +1598,9 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { }; ) } else { - quote!( - let children = vec![]; - ) + quote!( + let children = vec![]; + ) }; let mut args_quote = quote!(); @@ -1565,7 +1611,7 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { args_quote = quote!(pub args: #view_args_ident,); args_impl_quote = quote!(args: #view_args_ident::default(),); } - + let view_builder_quote = quote! { pub struct #view_builder<#msg_type_ident> where #msg_type_ident : 'static { #args_quote @@ -1580,10 +1626,10 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { } } - pub fn render(mut self) -> Node<#msg_type_ident> { - + pub fn render(mut self) -> Node<#msg_type_ident> { + #view_render_impl_quote - + #input_fn_ident( #view_function_call_impl_inner_quote ) @@ -1595,25 +1641,19 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { } }; - let view_trait_impls_quote = quote! {}; - + let mut args_macro_quote = quote! {}; - for (name, optional , is_a_vec, maybe_arg_type ) in vec_of_args.iter() { + for (name, optional, is_a_vec, maybe_arg_type) in vec_of_args.iter() { let builder_field_name = name.clone(); let name_long = format_ident!("{}_{}_{}", view_ident, name, location.to_string()); let qualified_name = format_ident!("{}_{}", view_ident, name); let has_args = maybe_arg_type.is_some(); let node_name = format_ident!("Node{}", qualified_name.to_string().to_camel_case()); - - - let macro_item_impl_quote = - - - match (optional, is_a_vec, has_args) { - (false,false,false) => quote! { + let macro_item_impl_quote = match (optional, is_a_vec, has_args) { + (false, false, false) => quote! { #[allow(unused_macros)] #[macro_export] macro_rules! #name_long { @@ -1625,65 +1665,66 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { // empty![] } }; - } + } pub use #name_long as #qualified_name; - - + + pub struct #node_name<#msg_type_ident> (pub Node<#msg_type_ident>); impl LocalUpdateEl> for #node_name where T:'static{ fn update_el(self, _el: &mut El){ // we dont really need _el - + if let Ok(sa) = illicit::get::>>() { sa.update(|builder| builder.#builder_field_name = self.0); } } } - + }, - (false,false,true) => { + (false, false, true) => { let arg_type = maybe_arg_type.clone().unwrap(); quote! { - #[macro_export] - macro_rules! #name_long { - ( $($ part:tt)* ) => { - { - #[allow(unused_mut)] - let mut argument_struct = #arg_type::default(); - let mut eld = El::empty(seed::virtual_dom::Tag::Div); - process_submacro_part_has_args!([#qualified_name,[$($part)*]]) - - } - }; - } + #[macro_export] + macro_rules! #name_long { + ( $($ part:tt)* ) => { + { + #[allow(unused_mut)] + let mut argument_struct = #arg_type::default(); + let mut eld = El::empty(seed::virtual_dom::Tag::Div); + process_submacro_part_has_args!([#qualified_name,[$($part)*]]) - pub use #name_long as #qualified_name; - - pub struct #node_name<#msg_type_ident> (pub (Node<#msg_type_ident>,#arg_type )); + } + }; + } - impl LocalUpdateEl> for #node_name where T:'static{ - fn update_el(self, _el: &mut El){ - // we dont really need _el - + pub use #name_long as #qualified_name; - if let Ok(sa) = illicit::get::>>() { - sa.update(|builder| builder.#builder_field_name = self.0); - } + pub struct #node_name<#msg_type_ident> (pub (Node<#msg_type_ident>,#arg_type )); + + impl LocalUpdateEl> for #node_name where T:'static{ + fn update_el(self, _el: &mut El){ + // we dont really need _el + + + if let Ok(sa) = illicit::get::>>() { + sa.update(|builder| builder.#builder_field_name = self.0); + } + } } - } - impl, I: Iterator> LocalUpdateElForIterator for I { - fn update_el(self, el: &mut El) { - for item in self { - item.update_el(el); + impl, I: Iterator> LocalUpdateElForIterator for I { + fn update_el(self, el: &mut El) { + for item in self { + item.update_el(el); + } } } + } - - }}, - (false,true,false) => quote! { + } + (false, true, false) => quote! { #[macro_export] macro_rules! #name_long { ($($ part:tt)* ) => { @@ -1700,8 +1741,8 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { impl LocalUpdateEl> for #node_name where T:'static{ fn update_el(self, _el: &mut El){ // we dont really need _el - - + + if let Ok(sa) = illicit::get::>>() { sa.update(|builder| builder.#builder_field_name.push(self.0)); } @@ -1709,118 +1750,116 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { } - - + + }, - (false,true,true) => { + (false, true, true) => { let arg_type = maybe_arg_type.clone().unwrap(); quote! { - #[macro_export] - macro_rules! #name_long { - ($($ part:tt)* ) => { - { - #[allow(unused_mut)] - let mut argument_struct = #arg_type::default(); - let mut eld = El::empty(seed::virtual_dom::Tag::Div); - process_submacro_part_a_vec_has_args!([#qualified_name,[$($part)*]]) - - } - }; - } - pub use #name_long as #qualified_name; + #[macro_export] + macro_rules! #name_long { + ($($ part:tt)* ) => { + { + #[allow(unused_mut)] + let mut argument_struct = #arg_type::default(); + let mut eld = El::empty(seed::virtual_dom::Tag::Div); + process_submacro_part_a_vec_has_args!([#qualified_name,[$($part)*]]) - pub struct #node_name<#msg_type_ident> (pub (Node<#msg_type_ident>,#arg_type )); + } + }; + } + pub use #name_long as #qualified_name; - impl LocalUpdateEl> for #node_name where T:'static{ - fn update_el(self, _el: &mut El){ - // we dont really need _el - + pub struct #node_name<#msg_type_ident> (pub (Node<#msg_type_ident>,#arg_type )); - if let Ok(sa) = illicit::get::>>() { - sa.update(|builder| builder.#builder_field_name.push(self.0)); - } - } - } + impl LocalUpdateEl> for #node_name where T:'static{ + fn update_el(self, _el: &mut El){ + // we dont really need _el - - }}, - (true,false,false) => { - - quote! { - #[macro_export] - macro_rules! #name_long { - ( $($ part:tt)* ) => { - { - #[allow(unused_mut)] - - let mut eld = El::empty(seed::virtual_dom::Tag::Div); - process_submacro_part_optional!([#qualified_name,[$($part)*]]) - + + if let Ok(sa) = illicit::get::>>() { + sa.update(|builder| builder.#builder_field_name.push(self.0)); + } } - }; + } + + } - pub use #name_long as #qualified_name; + } + (true, false, false) => { + quote! { + #[macro_export] + macro_rules! #name_long { + ( $($ part:tt)* ) => { + { + #[allow(unused_mut)] - - pub struct #node_name<#msg_type_ident> (pub Node<#msg_type_ident>); + let mut eld = El::empty(seed::virtual_dom::Tag::Div); + process_submacro_part_optional!([#qualified_name,[$($part)*]]) - impl LocalUpdateEl> for #node_name where T:'static{ - fn update_el(self, _el: &mut El){ - // we dont really need _el - + } + }; + } + pub use #name_long as #qualified_name; - if let Ok(sa) = illicit::get::>>() { - sa.update(|builder| builder.#builder_field_name = Some(self.0)); - } + + pub struct #node_name<#msg_type_ident> (pub Node<#msg_type_ident>); + + impl LocalUpdateEl> for #node_name where T:'static{ + fn update_el(self, _el: &mut El){ + // we dont really need _el + + + if let Ok(sa) = illicit::get::>>() { + sa.update(|builder| builder.#builder_field_name = Some(self.0)); + } + } } - } - - }}, - (true,false,true) => { + + } + } + (true, false, true) => { let arg_type = maybe_arg_type.clone().unwrap(); quote! { - #[macro_export] - macro_rules! #name_long { - ( $($ part:tt)* ) => { - { - #[allow(unused_mut)] - let mut argument_struct = #arg_type::default(); - let mut eld = El::empty(seed::virtual_dom::Tag::Div); - process_submacro_part_optional_has_args!([#qualified_name,[$($part)*]]) - - } - }; - } - use #name_long as #qualified_name; + #[macro_export] + macro_rules! #name_long { + ( $($ part:tt)* ) => { + { + #[allow(unused_mut)] + let mut argument_struct = #arg_type::default(); + let mut eld = El::empty(seed::virtual_dom::Tag::Div); + process_submacro_part_optional_has_args!([#qualified_name,[$($part)*]]) - pub struct #node_name<#msg_type_ident> (pub (Node<#msg_type_ident>,#arg_type )); + } + }; + } + use #name_long as #qualified_name; - impl LocalUpdateEl> for #node_name where T:'static{ - fn update_el(self, _el: &mut El){ - // we dont really need _el - + pub struct #node_name<#msg_type_ident> (pub (Node<#msg_type_ident>,#arg_type )); - if let Ok(sa) = illicit::get::>>() { - sa.update(|builder| builder.#builder_field_name = Some(self.0)); - } + impl LocalUpdateEl> for #node_name where T:'static{ + fn update_el(self, _el: &mut El){ + // we dont really need _el + + + if let Ok(sa) = illicit::get::>>() { + sa.update(|builder| builder.#builder_field_name = Some(self.0)); + } + } } - } - }}, - (true,true,_) => panic!("You cant have optional as well as vector args"), - - + } + } + (true, true, _) => panic!("You cant have optional as well as vector args"), }; - args_macro_quote = quote! { #args_macro_quote #macro_item_impl_quote }; } - let main_view_macro_name_view_ident = format_ident!("MainViewMacroName_{}", view_ident); let macro_impl_quote = quote! { @@ -1831,18 +1870,18 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { #[macro_export] macro_rules! #view_ident_long { - + ( $($ part:tt)* ) => { - + { #use_shortcuts #[allow(unused_mut)] let mut builder = #view_builder::<_>::default_empty(); - + process_part!([#main_view_macro_name_view_ident, [#(#vec_of_all_args),*], [$($part)*]]) ; - + builder.render() } }; @@ -1850,8 +1889,6 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { pub use #view_ident_long as #view_ident; }; - - let inner_block = input_fn.block; input_fn.block = syn::parse_quote! {{ @@ -1892,19 +1929,16 @@ pub fn view_macro(_args: TokenStream, input: TokenStream) -> TokenStream { .into() } - -struct ProcessPartArray{ +struct ProcessPartArray { parts: Vec, } - enum ProcessPart { - Assign(ProcessPartAssign), Neither(ProcessPartNeither), } -struct ProcessPartAssign{ +struct ProcessPartAssign { left_ident: syn::Ident, right: Box, } @@ -1917,35 +1951,45 @@ struct ProcessPartNeither { impl Parse for ProcessPartArray { fn parse(input: ParseStream) -> Result { // an array is passed to the process_part macro. - let args :ExprArray = input.parse()?; + let args: ExprArray = input.parse()?; // we need to iterate over it, the first element is the main macro name // the next element is a list of all arguments // the next element is a list of optional arguments // the final element is the actual expression being processed. let mut iter_for_args = args.elems.iter(); - - let macro_name_expr = iter_for_args.next().cloned().expect("macro_name_expr to exist"); - + + let macro_name_expr = iter_for_args + .next() + .cloned() + .expect("macro_name_expr to exist"); + // all_args and optional_args are needed when processing a macro expression. - let _all_args = iter_for_args.next().cloned().expect("This ExprArray should exist"); - + let _all_args = iter_for_args + .next() + .cloned() + .expect("This ExprArray should exist"); let expr = iter_for_args.next().cloned().expect("expression to exist"); - let main_macro_name_ident = match macro_name_expr { Expr::Path(path) => { - - let ident = path.path.get_ident().expect("MainViewMacroName to exist"); - let ident_string = ident.to_string(); - if ident_string.starts_with("MainViewMacroName_"){ - format_ident!("{}",ident_string.trim_start_matches("MainViewMacroName_").to_string()) + let ident = path.path.get_ident().expect("MainViewMacroName to exist"); + let ident_string = ident.to_string(); + if ident_string.starts_with("MainViewMacroName_") { + format_ident!( + "{}", + ident_string + .trim_start_matches("MainViewMacroName_") + .to_string() + ) } else { panic!("Cannot determine main macro name") } } - _ => {panic!("cannot determine main macro name")} + _ => { + panic!("cannot determine main macro name") + } }; // The main expression can be an assign, a macro, or something else @@ -1953,17 +1997,19 @@ impl Parse for ProcessPartArray { // if its a macro we construct a struct that enables the correct macro to be called // if its something else we allow update the root element. - if let Expr::Array(expr_array) = expr { - let mut vec_of_processed_parts = vec![]; + if let Expr::Array(expr_array) = expr { + let mut vec_of_processed_parts = vec![]; - - for expr in expr_array.elems { - match expr { - + for expr in expr_array.elems { + match expr { Expr::Assign(expr_assign) => { let left_ident = if let Expr::Path(path) = *expr_assign.left { let path = path.path; - path.clone().get_ident().clone().expect("left ident to exist").clone() + path.clone() + .get_ident() + .clone() + .expect("left ident to exist") + .clone() } else { unimplemented!() }; @@ -1983,9 +2029,9 @@ impl Parse for ProcessPartArray { // let is_an_argument_macro = if match &all_args { // Expr::Array(expr_array) => { - // expr_array.elems.iter().any(|item| + // expr_array.elems.iter().any(|item| // if let Expr::Path(path) = item { - // path.path.get_ident().unwrap().to_string() == ident.to_string() + // path.path.get_ident().unwrap().to_string() == ident.to_string() // } else { // unimplemented!() // } @@ -1998,7 +2044,6 @@ impl Parse for ProcessPartArray { // false // }; - // if is_an_argument_macro { // vec_of_processed_parts.push(ProcessPart::Macro(ProcessPartMacro { // main_name_ident: main_macro_name_ident.clone(), @@ -2015,7 +2060,7 @@ impl Parse for ProcessPartArray { // } // } exp => { - // not a macro or an assign, therefore we construct a struct + // not a macro or an assign, therefore we construct a struct // to enable the root element to be updated. vec_of_processed_parts.push(ProcessPart::Neither(ProcessPartNeither { @@ -2025,141 +2070,124 @@ impl Parse for ProcessPartArray { } } } - Ok(ProcessPartArray{ + Ok(ProcessPartArray { parts: vec_of_processed_parts, }) - - } - else { + } else { panic!("dsdsd") } - - -} + } } #[proc_macro] pub fn process_part(input: TokenStream) -> TokenStream { - let processed_part_array = parse_macro_input!(input as ProcessPartArray); let mut combined_quote = quote!(); - for part in processed_part_array.parts { + for part in processed_part_array.parts { match part { - - - ProcessPart::Assign(assign) => { - let left_ident = assign.left_ident; - let expr = assign.right; - - if left_ident.to_string() == "extend" { - combined_quote = quote!( - #combined_quote - builder.root = #expr; - ) - } else { - - combined_quote = quote!( - #combined_quote - builder.args.#left_ident = #expr; - ) - } - } - ProcessPart::Neither(ProcessPartNeither{ - expr, main_name_ident}) => { - let view_builder = format_ident!("{}Builder", main_name_ident.to_string().to_camel_case()); - + ProcessPart::Assign(assign) => { + let left_ident = assign.left_ident; + let expr = assign.right; + + if left_ident.to_string() == "extend" { + combined_quote = quote!( + #combined_quote + builder.root = #expr; + ) + } else { + combined_quote = quote!( + #combined_quote + builder.args.#left_ident = #expr; + ) + } + } + ProcessPart::Neither(ProcessPartNeither { + expr, + main_name_ident, + }) => { + let view_builder = + format_ident!("{}Builder", main_name_ident.to_string().to_camel_case()); + combined_quote = quote!( - + #combined_quote let empty = empty![]; let mut root_backup = std::mem::replace(&mut builder.root, empty); - + let empty_builder = #view_builder::<_>::default_empty(); let backedup_builder = std::mem::replace(&mut builder, empty_builder); - + let sa_builder = use_state(||backedup_builder); - + illicit::Layer::offer(sa_builder).enter(|| { - + match &mut root_backup { seed::virtual_dom::Node::Element(ref mut ela) => { #expr.update_el(ela); } _ => {panic!("huh")} } - + }); - + builder = sa_builder.remove().unwrap(); let _ = std::mem::replace(&mut builder.root, root_backup); - + ); - - - - - - // quote!().into() - } + + // quote!().into() + } } } - // panic!("{:#?}", combined_quote); - quote!({ + // panic!("{:#?}", combined_quote); + quote!({ #combined_quote - }).into() + }) + .into() } - struct AsElem { - elem_name_ident : syn::Ident, - affected_node_ident : syn::Ident, - exprs : Vec, + elem_name_ident: syn::Ident, + affected_node_ident: syn::Ident, + exprs: Vec, } - impl Parse for AsElem { fn parse(input: ParseStream) -> Result { let elem_name_ident = input.parse::()?; let _comma = input.parse::()?; let affected_node_ident = input.parse::()?; let mut exprs = vec![]; - if let Ok(_comma) = input.parse::(){ - - + if let Ok(_comma) = input.parse::() { let mut done = false; while !done { - if let Ok(expr) = input.parse::(){ + if let Ok(expr) = input.parse::() { exprs.push(expr); } else { done = true; } - if let Ok(_comma) = input.parse::(){ - + if let Ok(_comma) = input.parse::() { } else { done = true } } } - Ok( - AsElem { - elem_name_ident, - affected_node_ident, - exprs, - } - ) + Ok(AsElem { + elem_name_ident, + affected_node_ident, + exprs, + }) } } - - #[proc_macro] pub fn as_tag(input: TokenStream) -> TokenStream { let as_tag = parse_macro_input!(input as AsElem); let affected_node_ident = as_tag.affected_node_ident; - let elem_name_ident = format_ident!("{}",as_tag.elem_name_ident.to_string().to_camel_case()); + let elem_name_ident = format_ident!("{}", as_tag.elem_name_ident.to_string().to_camel_case()); let exprs = as_tag.exprs.iter(); let mut exprs_quote = quote!(); @@ -2170,7 +2198,6 @@ pub fn as_tag(input: TokenStream) -> TokenStream { #expr.update_el(ela); }); } - let exp = quote!({ let mut change_from_text_to_node = true; @@ -2180,11 +2207,11 @@ pub fn as_tag(input: TokenStream) -> TokenStream { } let mut new_node = if change_from_text_to_node { - + let empty_node = Node::Empty; let old_text_node = std::mem::replace(&mut #affected_node_ident , empty_node); - + let mut el = El::empty(Tag::#elem_name_ident); let mut new_node_inner = seed::virtual_dom::Node::Element(el); @@ -2196,7 +2223,7 @@ pub fn as_tag(input: TokenStream) -> TokenStream { _ => panic!("cannot use as_tag with Text or empty nodes") } } ; - + new_node_inner } else { #affected_node_ident @@ -2209,22 +2236,17 @@ pub fn as_tag(input: TokenStream) -> TokenStream { } _ => panic!("cannot use as_tag with Text or empty nodes") } - new_node + new_node }); - exp.into() - + exp.into() } - -struct ProcessSubMacroPartArray{ - - name : syn::Ident, +struct ProcessSubMacroPartArray { + name: syn::Ident, parts: Vec, } - - enum ProcessSubMacroPart { Assign(ProcessSubMacroPartAssign), Neither(ProcessSubMacroPartNeither), @@ -2241,81 +2263,86 @@ struct ProcessSubMacroPartNeither { impl Parse for ProcessSubMacroPartArray { fn parse(input: ParseStream) -> Result { - let args :ExprArray = input.parse()?; - - let mut iter_for_args = args.elems.iter(); - - - let macro_name_expr = iter_for_args.next().cloned().expect("macro_name_expr to exist"); - - - let expr = iter_for_args.next().cloned().expect("expression to exist"); - - - let main_macro_name_ident = match macro_name_expr { - Expr::Path(path) => { - path.path.get_ident().expect("MainViewMacroName to exist").clone() - } - _ => {panic!("canwewnot determine main macro name")} - }; - - - // The main expression can be an assign, a macro, or something else - // if its an assign macro we construct a struct that enables optional arguments to be set - // if its a macro we construct a struct that enables the correct macro to be called - // if its something else we allow update the root element. - - if let Expr::Array(expr_array) = expr { - let mut vec_of_processed_parts = vec![]; - - for expr in expr_array.elems { - match expr { - - + let args: ExprArray = input.parse()?; + + let mut iter_for_args = args.elems.iter(); + + let macro_name_expr = iter_for_args + .next() + .cloned() + .expect("macro_name_expr to exist"); + + let expr = iter_for_args.next().cloned().expect("expression to exist"); + + let main_macro_name_ident = match macro_name_expr { + Expr::Path(path) => path + .path + .get_ident() + .expect("MainViewMacroName to exist") + .clone(), + _ => { + panic!("canwewnot determine main macro name") + } + }; + + // The main expression can be an assign, a macro, or something else + // if its an assign macro we construct a struct that enables optional arguments to be set + // if its a macro we construct a struct that enables the correct macro to be called + // if its something else we allow update the root element. + + if let Expr::Array(expr_array) = expr { + let mut vec_of_processed_parts = vec![]; + + for expr in expr_array.elems { + match expr { Expr::Assign(expr_assign) => { let left_ident = if let Expr::Path(path) = *expr_assign.left { let path = path.path; - path.clone().get_ident().clone().expect("left ident to exist").clone() + path.clone() + .get_ident() + .clone() + .expect("left ident to exist") + .clone() } else { unimplemented!() }; - vec_of_processed_parts.push(ProcessSubMacroPart::Assign(ProcessSubMacroPartAssign { - left_ident: left_ident.clone(), - right: expr_assign.right, - })) + vec_of_processed_parts.push(ProcessSubMacroPart::Assign( + ProcessSubMacroPartAssign { + left_ident: left_ident.clone(), + right: expr_assign.right, + }, + )) } exp => { - // not a macro or an assign, therefore we construct a struct + // not a macro or an assign, therefore we construct a struct // to enable the root element to be updated. - vec_of_processed_parts.push(ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither { - expr: exp.clone(), - })) + vec_of_processed_parts.push(ProcessSubMacroPart::Neither( + ProcessSubMacroPartNeither { expr: exp.clone() }, + )) } } } - - Ok(ProcessSubMacroPartArray{ + + Ok(ProcessSubMacroPartArray { name: main_macro_name_ident, parts: vec_of_processed_parts, }) - -} else { - panic!{"should never get here"}; - -} -} + } else { + panic! {"should never get here"}; + } + } } #[proc_macro] pub fn process_submacro_part_a_vec(input: TokenStream) -> TokenStream { let processed_part_array = parse_macro_input!(input as ProcessSubMacroPartArray); - let name =processed_part_array.name; + let name = processed_part_array.name; let node_name = format_ident!("Node{}", name.to_string().to_camel_case()); let mut combined_quote = quote!(); - for part in processed_part_array.parts { + for part in processed_part_array.parts { match part { ProcessSubMacroPart::Assign(assign) => { let left_ident = assign.left_ident; @@ -2328,7 +2355,7 @@ pub fn process_submacro_part_a_vec(input: TokenStream) -> TokenStream { #exp ) } - ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither{expr}) => { + ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither { expr }) => { let exp = quote!( #expr.update_el( &mut eld); ); @@ -2338,22 +2365,23 @@ pub fn process_submacro_part_a_vec(input: TokenStream) -> TokenStream { #exp ) } + } } -} quote!({ #combined_quote #node_name(Node::Element(eld)) - }).into() + }) + .into() } #[proc_macro] pub fn process_submacro_part_optional(input: TokenStream) -> TokenStream { let processed_part_array = parse_macro_input!(input as ProcessSubMacroPartArray); - let name =processed_part_array.name; + let name = processed_part_array.name; let node_name = format_ident!("Node{}", name.to_string().to_camel_case()); let mut combined_quote = quote!(); - for part in processed_part_array.parts { + for part in processed_part_array.parts { match part { ProcessSubMacroPart::Assign(assign) => { let left_ident = assign.left_ident; @@ -2366,7 +2394,7 @@ pub fn process_submacro_part_optional(input: TokenStream) -> TokenStream { #exp ) } - ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither{expr}) => { + ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither { expr }) => { let exp = quote!( #expr.update_el( &mut eld); ); @@ -2376,24 +2404,24 @@ pub fn process_submacro_part_optional(input: TokenStream) -> TokenStream { #exp ) } + } } -} quote!({ #combined_quote #node_name(Node::Element(eld)) - }).into() + }) + .into() } - #[proc_macro] pub fn process_submacro_part_has_args(input: TokenStream) -> TokenStream { let processed_part_array = parse_macro_input!(input as ProcessSubMacroPartArray); - let name =processed_part_array.name; + let name = processed_part_array.name; let node_name = format_ident!("Node{}", name.to_string().to_camel_case()); let mut combined_quote = quote!(); - for part in processed_part_array.parts { + for part in processed_part_array.parts { match part { ProcessSubMacroPart::Assign(assign) => { let left_ident = assign.left_ident; @@ -2406,7 +2434,7 @@ pub fn process_submacro_part_has_args(input: TokenStream) -> TokenStream { #exp ) } - ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither{expr}) => { + ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither { expr }) => { let exp = quote!( #expr.update_el( &mut eld); ); @@ -2416,23 +2444,23 @@ pub fn process_submacro_part_has_args(input: TokenStream) -> TokenStream { #exp ) } + } } -} quote!({ #combined_quote #node_name(( Node::Element(eld) , argument_struct)) - }).into() + }) + .into() } - #[proc_macro] pub fn process_submacro_part_optional_has_args(input: TokenStream) -> TokenStream { let processed_part_array = parse_macro_input!(input as ProcessSubMacroPartArray); - let name =processed_part_array.name; + let name = processed_part_array.name; let node_name = format_ident!("Node{}", name.to_string().to_camel_case()); let mut combined_quote = quote!(); - for part in processed_part_array.parts { + for part in processed_part_array.parts { match part { ProcessSubMacroPart::Assign(assign) => { let left_ident = assign.left_ident; @@ -2445,7 +2473,7 @@ pub fn process_submacro_part_optional_has_args(input: TokenStream) -> TokenStrea #exp ) } - ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither{expr}) => { + ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither { expr }) => { let exp = quote!( #expr.update_el( &mut eld); ); @@ -2455,23 +2483,23 @@ pub fn process_submacro_part_optional_has_args(input: TokenStream) -> TokenStrea #exp ) } + } } -} quote!({ #combined_quote #node_name(( Node::Element(eld) , argument_struct)) - }).into() + }) + .into() } - #[proc_macro] pub fn process_submacro_part_a_vec_has_args(input: TokenStream) -> TokenStream { let processed_part_array = parse_macro_input!(input as ProcessSubMacroPartArray); - let name =processed_part_array.name; + let name = processed_part_array.name; let node_name = format_ident!("Node{}", name.to_string().to_camel_case()); let mut combined_quote = quote!(); - for part in processed_part_array.parts { + for part in processed_part_array.parts { match part { ProcessSubMacroPart::Assign(assign) => { let left_ident = assign.left_ident; @@ -2484,7 +2512,7 @@ pub fn process_submacro_part_a_vec_has_args(input: TokenStream) -> TokenStream { #exp ) } - ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither{expr}) => { + ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither { expr }) => { let exp = quote!( #expr.update_el( &mut eld); ); @@ -2494,15 +2522,15 @@ pub fn process_submacro_part_a_vec_has_args(input: TokenStream) -> TokenStream { #exp ) } + } } -} quote!({ #combined_quote #node_name(( Node::Element(eld) , argument_struct)) - }).into() + }) + .into() } - #[proc_macro] pub fn process_submacro_part(input: TokenStream) -> TokenStream { let processed_part_array = parse_macro_input!(input as ProcessSubMacroPartArray); @@ -2511,10 +2539,9 @@ pub fn process_submacro_part(input: TokenStream) -> TokenStream { let node_name = format_ident!("Node{}", name.to_string().to_camel_case()); let mut combined_quote = quote!(); - for part in processed_part_array.parts { + for part in processed_part_array.parts { match part { - ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither{expr}) => { - + ProcessSubMacroPart::Neither(ProcessSubMacroPartNeither { expr }) => { let exp = quote!( #expr.update_el( &mut eld); ); @@ -2523,14 +2550,14 @@ pub fn process_submacro_part(input: TokenStream) -> TokenStream { #combined_quote #exp ); - } - - _exp=>panic!("Shoudl never get an assign ") + + _exp => panic!("Shoudl never get an assign "), + } } -} quote!({ #combined_quote #node_name(Node::Element(eld)) - }).into() + }) + .into() } diff --git a/seed_styles/seed_style_macros/tests/progress.rs b/seed_styles/seed_style_macros/tests/progress.rs index 066d949..3baaee5 100644 --- a/seed_styles/seed_style_macros/tests/progress.rs +++ b/seed_styles/seed_style_macros/tests/progress.rs @@ -11,4 +11,4 @@ fn tests() { //t.pass("tests/08-inclusive-range.rs"); //t.compile_fail("tests/09-ident-span.rs"); //t.pass("tests/10-interaction-with-macrorules.rs"); -} \ No newline at end of file +} diff --git a/seed_styles/src/lib.rs b/seed_styles/src/lib.rs index 39a49f9..20dbddd 100644 --- a/seed_styles/src/lib.rs +++ b/seed_styles/src/lib.rs @@ -1,4 +1,3 @@ - mod style; // exports @@ -7,7 +6,7 @@ pub use style::CssValueTrait; // style builder pub use style::s; -pub use seed_style_macros::{view_macro, as_tag, process_part, process_submacro_part,*}; +pub use seed_style_macros::{as_tag, process_part, process_submacro_part, view_macro, *}; #[macro_export] macro_rules! with_dollar_sign { @@ -17,31 +16,31 @@ macro_rules! with_dollar_sign { } } - // style property argument trait pub use style::{ - PseudoTrait, // exports for Seed Layout composition::{default_breakpoint_theme, Composition, SeedBreakpoint, WithLayoutComposition}, - //ro col layout - row_col_layout::{Row, *, Column, RowBuilder, ColumnBuilder, RowColumnArgs, RowItemArgs, ColumnItemArgs,}, - // Css Values css_values::*, // resizing helpers::conditionally_skip_rendering, layout::{Layout, LayoutArea, NoArea, WithGridLayout}, // measures - measures::{cm, em, hsl, hsla,hsluv, hsluva, pc, px, rem, rgb, rgba, vh, vw, ExactLength}, + measures::{cm, em, hsl, hsla, hsluv, hsluva, pc, px, rem, rgb, rgba, vh, vw, ExactLength}, // presets - presets::{seed_colors, default_colors_theme}, + presets::{default_colors_theme, seed_colors}, + //ro col layout + row_col_layout::{ + Column, ColumnBuilder, ColumnItemArgs, Row, RowBuilder, RowColumnArgs, RowItemArgs, *, + }, + theme::change_theme_with_name, - - theme::{app_themes, load_app_themes}, + // themes theme::Theme, + theme::{app_themes, load_app_themes}, // themes, conditional rendering - theme::{except, only, only_and_above, only_and_below, at_breakpoint_and_above}, + theme::{at_breakpoint_and_above, except, only, only_and_above, only_and_below}, //theme alias keys theme::{ BorderRadiusTheme, BorderStyleTheme, BorderTheme, BorderWidthTheme, BreakpointTheme, @@ -52,14 +51,15 @@ pub use style::{ // global style api GlobalStyle, // extension trait to allow Style structs to be update_el processed by seed. - LocalUpdateEl,LocalUpdateElForIterator, + LocalUpdateEl, + LocalUpdateElForIterator, + PseudoTrait, // Style struct, technically user shouldn't really need to access this directly Style, // style property argument trait UpdateStyle, }; - // pub trait UpdateView { // fn update_view(self, builder: &mut B); // } diff --git a/seed_styles/src/style.rs b/seed_styles/src/style.rs index ab83a73..903a113 100644 --- a/seed_styles/src/style.rs +++ b/seed_styles/src/style.rs @@ -900,12 +900,7 @@ impl Keyframes { // global: String, // } -fn add_global_init_css_to_head( - css: &str, - short_hash: &str, - style: &Style, - selector: &str, -) { +fn add_global_init_css_to_head(css: &str, short_hash: &str, style: &Style, selector: &str) { let head_elem = document().get_elements_by_tag_name("head").item(0).unwrap(); let css = if !style.keyframes.frames.is_empty() { @@ -919,12 +914,7 @@ fn add_global_init_css_to_head( .iter() .map(|c| { if let Combinator::Pre(c) = c { - format!( - "{}{}{}", - selector, - c, - style.pseudo.render() - ) + format!("{}{}{}", selector, c, style.pseudo.render()) } else { String::new() } @@ -978,12 +968,7 @@ fn add_global_init_css_to_head( css ), - (None, None) => format!( - "\n{}{}{{\n{}}}\n", - selector, - style.pseudo.render(), - css - ), + (None, None) => format!("\n{}{}{{\n{}}}\n", selector, style.pseudo.render(), css), } }; @@ -1076,10 +1061,7 @@ fn add_global_init_css_to_head( for (media_breakpoint, rule_vec) in &style.media_rules { let mut media_string = String::new(); - media_string.push_str(&format!( - "{}{{\n{}{{\n", - media_breakpoint, selector - )); + media_string.push_str(&format!("{}{{\n{}{{\n", media_breakpoint, selector)); for rule in rule_vec { media_string.push_str(&rule.render()); @@ -1642,12 +1624,7 @@ impl GlobalStyle { for (selector, style) in &self.styles { let rendered_css = style.render(); - add_global_init_css_to_head( - &rendered_css, - "global_init", - &style, - &selector, - ); + add_global_init_css_to_head(&rendered_css, "global_init", &style, &selector); } }); } @@ -1674,12 +1651,7 @@ impl GlobalStyle { for (selector, style) in &self.styles { let rendered_css = style.render(); - add_global_init_css_to_head( - &rendered_css, - &short_hash, - &style, - &selector, - ); + add_global_init_css_to_head(&rendered_css, &short_hash, &style, &selector); STYLES_USED.with(|css_set_ref| { css_set_ref .borrow_mut() diff --git a/seed_styles/src/style/composition.rs b/seed_styles/src/style/composition.rs index 5e51b42..2fd776b 100644 --- a/seed_styles/src/style/composition.rs +++ b/seed_styles/src/style/composition.rs @@ -170,7 +170,6 @@ where self.render_layout(*idx_of_smallest_layout, model) } } - } pub fn set_content Node + 'static>( diff --git a/seed_styles/src/style/css_values.rs b/seed_styles/src/style/css_values.rs index f39de2c..59a0106 100644 --- a/seed_styles/src/style/css_values.rs +++ b/seed_styles/src/style/css_values.rs @@ -604,7 +604,8 @@ pub enum CssTextDecorationColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -1600,7 +1601,12 @@ pub enum CssMaxHeight { #[derive(Display, Clone, Debug, CssStyleMacro)] #[display(fmt = "border: {};")] pub enum CssBorder { - #[display(fmt = "{} {} {}", "_0.value_only()", "_1.value_only()", "_2.value_only()",)] + #[display( + fmt = "{} {} {}", + "_0.value_only()", + "_1.value_only()", + "_2.value_only()" + )] Border(CssBorderWidth, CssBorderStyle, CssColor), #[display(fmt = "inherit")] Inherit, @@ -1610,7 +1616,12 @@ pub enum CssBorder { #[derive(Display, Clone, Debug, CssStyleMacro)] #[display(fmt = "border-left: {};")] pub enum CssBorderLeft { - #[display(fmt = "{} {} {}", "_0.value_only()", "_1.value_only()", "_2.value_only()",)] + #[display( + fmt = "{} {} {}", + "_0.value_only()", + "_1.value_only()", + "_2.value_only()" + )] Border(CssBorderWidth, CssBorderStyle, CssColor), #[display(fmt = "inherit")] Inherit, @@ -1620,7 +1631,12 @@ pub enum CssBorderLeft { #[derive(Display, Clone, Debug, CssStyleMacro)] #[display(fmt = "border-right: {};")] pub enum CssBorderRight { - #[display(fmt = "{} {} {}", "_0.value_only()", "_1.value_only()", "_2.value_only()",)] + #[display( + fmt = "{} {} {}", + "_0.value_only()", + "_1.value_only()", + "_2.value_only()" + )] Border(CssBorderWidth, CssBorderStyle, CssColor), #[display(fmt = "inherit")] Inherit, @@ -1630,7 +1646,12 @@ pub enum CssBorderRight { #[derive(Display, Clone, Debug, CssStyleMacro)] #[display(fmt = "border-top: {};")] pub enum CssBorderTop { - #[display(fmt = "{} {} {}", "_0.value_only()", "_1.value_only()", "_2.value_only()",)] + #[display( + fmt = "{} {} {}", + "_0.value_only()", + "_1.value_only()", + "_2.value_only()" + )] Border(CssBorderWidth, CssBorderStyle, CssColor), #[display(fmt = "inherit")] Inherit, @@ -1640,7 +1661,12 @@ pub enum CssBorderTop { #[derive(Display, Clone, Debug, CssStyleMacro)] #[display(fmt = "border-bottom: {};")] pub enum CssBorderBottom { - #[display(fmt = "{} {} {}", "_0.value_only()", "_1.value_only()", "_2.value_only()",)] + #[display( + fmt = "{} {} {}", + "_0.value_only()", + "_1.value_only()", + "_2.value_only()" + )] Border(CssBorderWidth, CssBorderStyle, CssColor), #[display(fmt = "inherit")] Inherit, @@ -1650,7 +1676,12 @@ pub enum CssBorderBottom { #[derive(Display, Clone, Debug, CssStyleMacro)] #[display(fmt = "outline: {};")] pub enum CssOutline { - #[display(fmt = "{} {} {}", "_0.value_only()", "_1.value_only()", "_2.value_only()",)] + #[display( + fmt = "{} {} {}", + "_0.value_only()", + "_1.value_only()", + "_2.value_only()" + )] Outline(CssOutlineWidth, CssOutlineStyle, CssColor), #[display(fmt = "inherit")] Inherit, @@ -1662,7 +1693,12 @@ pub enum CssOutline { #[derive(Display, Clone, Debug, CssStyleMacro)] #[display(fmt = "outline-left: {};")] pub enum CssOutlineLeft { - #[display(fmt = "{} {} {}", "_0.value_only()", "_1.value_only()", "_2.value_only()",)] + #[display( + fmt = "{} {} {}", + "_0.value_only()", + "_1.value_only()", + "_2.value_only()" + )] Outline(CssOutlineWidth, CssOutlineStyle, CssColor), #[display(fmt = "inherit")] Inherit, @@ -1674,7 +1710,12 @@ pub enum CssOutlineLeft { #[derive(Display, Clone, Debug, CssStyleMacro)] #[display(fmt = "outline-right: {};")] pub enum CssOutlineRight { - #[display(fmt = "{} {} {}", "_0.value_only()", "_1.value_only()", "_2.value_only()",)] + #[display( + fmt = "{} {} {}", + "_0.value_only()", + "_1.value_only()", + "_2.value_only()" + )] Outline(CssOutlineWidth, CssOutlineStyle, CssColor), #[display(fmt = "inherit")] Inherit, @@ -1686,7 +1727,12 @@ pub enum CssOutlineRight { #[derive(Display, Clone, Debug, CssStyleMacro)] #[display(fmt = "outline-top: {};")] pub enum CssOutlineTop { - #[display(fmt = "{} {} {}", "_0.value_only()", "_1.value_only()", "_2.value_only()",)] + #[display( + fmt = "{} {} {}", + "_0.value_only()", + "_1.value_only()", + "_2.value_only()" + )] Outline(CssOutlineWidth, CssOutlineStyle, CssColor), #[display(fmt = "inherit")] Inherit, @@ -1698,7 +1744,12 @@ pub enum CssOutlineTop { #[derive(Display, Clone, Debug, CssStyleMacro)] #[display(fmt = "outline-bottom: {};")] pub enum CssOutlineBottom { - #[display(fmt = "{} {} {}", "_0.value_only()", "_1.value_only()", "_2.value_only()",)] + #[display( + fmt = "{} {} {}", + "_0.value_only()", + "_1.value_only()", + "_2.value_only()" + )] Outline(CssOutlineWidth, CssOutlineStyle, CssColor), #[display(fmt = "inherit")] Inherit, @@ -1828,7 +1879,7 @@ pub enum CssColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), + Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), @@ -1844,7 +1895,8 @@ pub enum CssStroke { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -1860,7 +1912,8 @@ pub enum CssBackgroundColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -1875,7 +1928,8 @@ pub enum CssFill { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -1891,7 +1945,8 @@ pub enum CssBorderColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -1907,7 +1962,8 @@ pub enum CssBorderLeftColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -1923,7 +1979,7 @@ pub enum CssBorderRightColor { #[display(fmt = "{} {} {}", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), + Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), @@ -1940,7 +1996,8 @@ pub enum CssBorderTopColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -1956,7 +2013,8 @@ pub enum CssBorderBottomColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -1971,7 +2029,8 @@ pub enum CssOutlineColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -1986,7 +2045,8 @@ pub enum CssOutlineLeftColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -2001,7 +2061,8 @@ pub enum CssOutlineRightColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -2016,7 +2077,8 @@ pub enum CssOutlineTopColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -2031,7 +2093,8 @@ pub enum CssOutlineBottomColor { #[display(fmt = "hsl({},{}%,{}%)", _0, _1, _2)] Hsl(f64, f64, f64), #[display(fmt = "hsla({},{}%,{}%,{})", _0, _1, _2, _3)] - Hsla(f64, f64, f64, f64), #[display(fmt = "#{:06x}", _0)] + Hsla(f64, f64, f64, f64), + #[display(fmt = "#{:06x}", _0)] Hex(i32), StringValue(String), #[display(fmt = "inherit")] @@ -2608,11 +2671,14 @@ create_enums!([ "WritingMode", ]); -pub fn trim_css_ends(property:T, name: &str) -> String { - property.to_string().trim_start_matches(name).trim_end_matches(";").to_string() +pub fn trim_css_ends(property: T, name: &str) -> String { + property + .to_string() + .trim_start_matches(name) + .trim_end_matches(";") + .to_string() } - #[derive(Debug, Clone)] pub struct CssMedia(pub String); diff --git a/seed_styles/src/style/from_traits.rs b/seed_styles/src/style/from_traits.rs index b2220bb..68566d7 100644 --- a/seed_styles/src/style/from_traits.rs +++ b/seed_styles/src/style/from_traits.rs @@ -260,14 +260,12 @@ impl From for CssTop { } } - impl From for CssColumnWidth { fn from(v: ExactLength) -> Self { Self::Length(v) } } - impl From for CssBottom { fn from(v: ExactLength) -> Self { Self::Length(v) @@ -411,12 +409,18 @@ impl From for CssLineHeight { } } -trait ToHexColor where Q:std::fmt::LowerHex{ - fn to_hex_color(self) -> String; +trait ToHexColor +where + Q: std::fmt::LowerHex, +{ + fn to_hex_color(self) -> String; } -impl ToHexColor for Q where Q:std::fmt::LowerHex{ - fn to_hex_color(self) -> String{ - format!("#{:06x}",self) +impl ToHexColor for Q +where + Q: std::fmt::LowerHex, +{ + fn to_hex_color(self) -> String { + format!("#{:06x}", self) } -} \ No newline at end of file +} diff --git a/seed_styles/src/style/layout.rs b/seed_styles/src/style/layout.rs index c465dae..a90bbc6 100644 --- a/seed_styles/src/style/layout.rs +++ b/seed_styles/src/style/layout.rs @@ -58,21 +58,19 @@ where } } - -pub trait WithGridLayout -{ +pub trait WithGridLayout { fn grid(style: Style) -> Layout; } -impl WithGridLayout for Layout -{ +impl WithGridLayout for Layout { fn grid(style: Style) -> Layout { Layout:: { areas: vec![], layout: vec![], container_styles: None, area_styles: HashMap::new(), - }.style(style) + } + .style(style) } } diff --git a/seed_styles/src/style/measures.rs b/seed_styles/src/style/measures.rs index 23a6523..a7f1fb6 100644 --- a/seed_styles/src/style/measures.rs +++ b/seed_styles/src/style/measures.rs @@ -59,15 +59,19 @@ pub fn em>(val: T) -> ExactLength { } } -pub fn hsl,S: Into,L: Into>(h: H, s: S, l: L) -> CssColor { +pub fn hsl, S: Into, L: Into>(h: H, s: S, l: L) -> CssColor { let h = h.into(); let s = s.into(); let l = l.into(); CssColor::Hsl(h, s, l) } - -pub fn hsla,S: Into,L: Into, A:Into>(h: H, s: S, l: L, a:A) -> CssColor { +pub fn hsla, S: Into, L: Into, A: Into>( + h: H, + s: S, + l: L, + a: A, +) -> CssColor { let h = h.into(); let s = s.into(); let l = l.into(); @@ -75,26 +79,29 @@ pub fn hsla,S: Into,L: Into, A:Into>(h: H, s: S, l: CssColor::Hsla(h, s, l, a) } -pub fn hsluva,S: Into,L: Into, A:Into>(h: H, s: S, l: L, a:A) -> CssColor { +pub fn hsluva, S: Into, L: Into, A: Into>( + h: H, + s: S, + l: L, + a: A, +) -> CssColor { let h = h.into(); let s = s.into(); let l = l.into(); let a = a.into(); - let rgb = hsluv::hsluv_to_rgb((h,s,l)); - CssColor::Rgba(rgb.0*255., rgb.1*255., rgb.2*255., a) + let rgb = hsluv::hsluv_to_rgb((h, s, l)); + CssColor::Rgba(rgb.0 * 255., rgb.1 * 255., rgb.2 * 255., a) } - -pub fn hsluv,S: Into,L: Into>(h: H, s: S, l: L) -> CssColor { +pub fn hsluv, S: Into, L: Into>(h: H, s: S, l: L) -> CssColor { let h = h.into(); let s = s.into(); let l = l.into(); - let rgb = hsluv::hsluv_to_rgb((h,s,l)); - CssColor::Rgba(rgb.0*255., rgb.1*255., rgb.2*255., 1.0) + let rgb = hsluv::hsluv_to_rgb((h, s, l)); + CssColor::Rgba(rgb.0 * 255., rgb.1 * 255., rgb.2 * 255., 1.0) } - -pub fn rgb,G: Into,B: Into>(r: R, g: G, b: B) -> CssColor { +pub fn rgb, G: Into, B: Into>(r: R, g: G, b: B) -> CssColor { let r = r.into(); let g = g.into(); let b = b.into(); @@ -102,7 +109,12 @@ pub fn rgb,G: Into,B: Into>(r: R, g: G, b: B) -> CssColor CssColor::Rgba(r, g, b, 1.0) } -pub fn rgba,G: Into,B: Into,A: Into>(r: R ,g: G, b: B, a: A) -> CssColor { +pub fn rgba, G: Into, B: Into, A: Into>( + r: R, + g: G, + b: B, + a: A, +) -> CssColor { let r = r.into(); let g = g.into(); let b = b.into(); diff --git a/seed_styles/src/style/row_col_layout.rs b/seed_styles/src/style/row_col_layout.rs index 1ff2bf4..4794a72 100644 --- a/seed_styles/src/style/row_col_layout.rs +++ b/seed_styles/src/style/row_col_layout.rs @@ -1,14 +1,11 @@ -use seed::{prelude::*, *}; -use super::measures::{ExactLength, px}; +use super::measures::{px, ExactLength}; use super::*; use crate::style::s; use crate::view_macro; - +use seed::{prelude::*, *}; use crate::style::state_access::StateAccess; - - // #[view_macro] // fn center_view(root: Node, children: Vec>) -> Node { // root![ @@ -23,12 +20,11 @@ use crate::style::state_access::StateAccess; // } pub struct RowColumnArgs { - pub gap: ExactLength, - pub padding: ExactLength, - pub flex: Flex, + pub gap: ExactLength, + pub padding: ExactLength, + pub flex: Flex, } - impl Default for RowColumnArgs { fn default() -> Self { RowColumnArgs { @@ -46,8 +42,6 @@ pub enum Flex { Custom(String), } - - pub enum RowAlign { Left, Center, @@ -63,26 +57,29 @@ pub enum RowAlign { RightBottom, } - pub struct RowItemArgs { pub align: RowAlign, pub flex: Flex, } impl std::default::Default for RowItemArgs { - fn default() -> Self { + fn default() -> Self { RowItemArgs { - align: RowAlign::Left, - flex: Flex::Unset, - } + align: RowAlign::Left, + flex: Flex::Unset, + } } } - #[view_macro] #[allow(non_snake_case)] -fn Row_view(args: RowColumnArgs, mut root: Node, mut children: Vec>, mut Item: Vec<(Node, RowItemArgs)>) -> Node { - let (flex,gap, padding) = (args.flex, args.gap, args.padding); +fn Row_view( + args: RowColumnArgs, + mut root: Node, + mut children: Vec>, + mut Item: Vec<(Node, RowItemArgs)>, +) -> Node { + let (flex, gap, padding) = (args.flex, args.gap, args.padding); let mut gap = gap.clone(); gap.value = gap.value / 2.0; @@ -91,8 +88,6 @@ fn Row_view(args: RowColumnArgs, mut root: Node, mut children: Vec(args: RowColumnArgs, mut root: Node, mut children: Vec (), Flex::None => item.0.style(s().flex("0 0 auto")), - Flex::Full => item.0.style(s().flex("1 1 0%").min_width(px(0)).min_height(px(0))), + Flex::Full => item + .0 + .style(s().flex("1 1 0%").min_width(px(0)).min_height(px(0))), Flex::Content => item.0.style(s().flex("1 0 auto")), Flex::Custom(flex_string) => item.0.style(s().flex(flex_string.as_str())), } match item.1.align { - RowAlign::Left => {item.0.style(s().p(padding.clone()).name("row_item"));left_nodes.push(item)}, - RowAlign::Center => {item.0.style(s().p(padding.clone()).name("row_item"));center_nodes.push(item)}, - RowAlign::Right=> {item.0.style(s().p(padding.clone()).name("row_item"));right_nodes.insert(0,item)}, - - RowAlign::LeftTop => {item.0.style(s().align_self_flex_start().p(padding.clone()).name("row_item")); left_nodes.push(item);}, - RowAlign::CenterTop=> {item.0.style(s().align_self_flex_start().p(padding.clone()).name("row_item"));center_nodes.push(item)}, - RowAlign::RightTop => {item.0.style(s().align_self_flex_start().p(padding.clone()).name("row_item")); right_nodes.insert(0,item)}, - - RowAlign::LeftMiddle => {item.0.style(s().align_self_center().p(padding.clone()).name("row_item")); left_nodes.push(item)}, - RowAlign::CenterMiddle => {item.0.style(s().align_self_center().p(padding.clone()).name("row_item")); center_nodes.push(item)}, - RowAlign::RightMiddle => {item.0.style(s().align_self_center().p(padding.clone()).name("row_item")); right_nodes.insert(0,item)}, - - RowAlign::LeftBottom => {item.0.style(s().align_self_flex_end().p(padding.clone()).name("row_item")); left_nodes.push(item)}, - RowAlign::CenterBottom=> {item.0.style(s().align_self_flex_end().p(padding.clone()).name("row_item")); center_nodes.push(item)}, - RowAlign::RightBottom => {item.0.style(s().align_self_flex_end().p(padding.clone()).name("row_item")); right_nodes.insert(0,item)}, - } - - - - - } - - - for mut c in children.drain(0..){ + RowAlign::Left => { + item.0.style(s().p(padding.clone()).name("row_item")); + left_nodes.push(item) + } + RowAlign::Center => { + item.0.style(s().p(padding.clone()).name("row_item")); + center_nodes.push(item) + } + RowAlign::Right => { + item.0.style(s().p(padding.clone()).name("row_item")); + right_nodes.insert(0, item) + } + + RowAlign::LeftTop => { + item.0.style( + s().align_self_flex_start() + .p(padding.clone()) + .name("row_item"), + ); + left_nodes.push(item); + } + RowAlign::CenterTop => { + item.0.style( + s().align_self_flex_start() + .p(padding.clone()) + .name("row_item"), + ); + center_nodes.push(item) + } + RowAlign::RightTop => { + item.0.style( + s().align_self_flex_start() + .p(padding.clone()) + .name("row_item"), + ); + right_nodes.insert(0, item) + } + + RowAlign::LeftMiddle => { + item.0 + .style(s().align_self_center().p(padding.clone()).name("row_item")); + left_nodes.push(item) + } + RowAlign::CenterMiddle => { + item.0 + .style(s().align_self_center().p(padding.clone()).name("row_item")); + center_nodes.push(item) + } + RowAlign::RightMiddle => { + item.0 + .style(s().align_self_center().p(padding.clone()).name("row_item")); + right_nodes.insert(0, item) + } + + RowAlign::LeftBottom => { + item.0.style( + s().align_self_flex_end() + .p(padding.clone()) + .name("row_item"), + ); + left_nodes.push(item) + } + RowAlign::CenterBottom => { + item.0.style( + s().align_self_flex_end() + .p(padding.clone()) + .name("row_item"), + ); + center_nodes.push(item) + } + RowAlign::RightBottom => { + item.0.style( + s().align_self_flex_end() + .p(padding.clone()) + .name("row_item"), + ); + right_nodes.insert(0, item) + } + } + } + + for mut c in children.drain(0..) { c.style(s().mx(gap.clone())); c.style(s().first_child().margin_left(px(0))); c.style(s().last_child().margin_right(px(0))); - - left_nodes.push( (c, RowItemArgs::default())); + + left_nodes.push((c, RowItemArgs::default())); } - root.style(s().name("row_layout").display_grid()); match flex { Flex::Unset => (), @@ -151,44 +204,103 @@ fn Row_view(args: RowColumnArgs, mut root: Node, mut children: Vec root.style(s().flex(flex_string.as_str())), } - match ( left_nodes.len(), center_nodes.len(), right_nodes.len()){ + match (left_nodes.len(), center_nodes.len(), right_nodes.len()) { (0, 0, 0) => empty![], (0, 0, _) => root![ - s().grid_template_columns("minmax(0px, 1fr)").grid_template_rows("minmax(0,1fr)"), - div![s().display_flex().flex_direction_row().justify_content_flex_end(),right_nodes.iter().map(|(Item,_arg)| Item)], + s().grid_template_columns("minmax(0px, 1fr)") + .grid_template_rows("minmax(0,1fr)"), + div![ + s().display_flex() + .flex_direction_row() + .justify_content_flex_end(), + right_nodes.iter().map(|(Item, _arg)| Item) + ], ], (0, _, 0) => root![ - s().grid_template_columns("auto").grid_template_rows("minmax(0,1fr)"), - div![s().display_flex().flex_direction_row().justify_content_center(), center_nodes.iter().map(|(Item,_arg)| Item)], + s().grid_template_columns("auto") + .grid_template_rows("minmax(0,1fr)"), + div![ + s().display_flex() + .flex_direction_row() + .justify_content_center(), + center_nodes.iter().map(|(Item, _arg)| Item) + ], ], (0, _, _) => root![ - s().grid_template_columns("minmax(0px, 1fr) auto minmax(0px, 1fr)").grid_template_rows("minmax(0,1fr)"), + s().grid_template_columns("minmax(0px, 1fr) auto minmax(0px, 1fr)") + .grid_template_rows("minmax(0,1fr)"), div![], - div![s().mr(gap.clone()).display_flex().flex_direction_row().justify_content_center(), center_nodes.iter().map(|(Item,_arg)| Item)], - div![s().ml(gap.clone()).display_flex().flex_direction_row().justify_content_flex_end(),right_nodes.iter().map(|(Item,_arg)| Item)], + div![ + s().mr(gap.clone()) + .display_flex() + .flex_direction_row() + .justify_content_center(), + center_nodes.iter().map(|(Item, _arg)| Item) + ], + div![ + s().ml(gap.clone()) + .display_flex() + .flex_direction_row() + .justify_content_flex_end(), + right_nodes.iter().map(|(Item, _arg)| Item) + ], ], (_, 0, 0) => root![ - s().grid_template_columns("minmax(0px, 1fr)").grid_template_rows("minmax(0,1fr)"), - div![s().display_flex().flex_direction_row().justify_content_flex_start(), left_nodes.iter().map(|(Item,_arg)| Item)], + s().grid_template_columns("minmax(0px, 1fr)") + .grid_template_rows("minmax(0,1fr)"), + div![ + s().display_flex() + .flex_direction_row() + .justify_content_flex_start(), + left_nodes.iter().map(|(Item, _arg)| Item) + ], ], (_, 0, _) => root![ - s().grid_template_columns("minmax(0px, 1fr) minmax(0px, 1fr)").grid_template_rows("minmax(0,1fr)"), - div![s().mr(gap.clone()).display_flex().flex_direction_row().justify_content_flex_start(),left_nodes.iter().map(|(Item,_arg)| Item)], - div![s().ml(gap.clone()).display_flex().flex_direction_row().justify_content_flex_end(),right_nodes.iter().map(|(Item,_arg)| Item)], + s().grid_template_columns("minmax(0px, 1fr) minmax(0px, 1fr)") + .grid_template_rows("minmax(0,1fr)"), + div![ + s().mr(gap.clone()) + .display_flex() + .flex_direction_row() + .justify_content_flex_start(), + left_nodes.iter().map(|(Item, _arg)| Item) + ], + div![ + s().ml(gap.clone()) + .display_flex() + .flex_direction_row() + .justify_content_flex_end(), + right_nodes.iter().map(|(Item, _arg)| Item) + ], ], (_, _, _) => root![ - s().grid_template_columns("minmax(0px, 1fr) auto minmax(0px, 1fr)").grid_template_rows("minmax(0,1fr)"), - div![s().mr(gap.clone()).display_flex().flex_direction_row().justify_content_flex_start(), left_nodes.iter().map(|(Item,_arg)| Item)], - div![s().mx(gap.clone()).display_flex().flex_direction_row().justify_content_center(), center_nodes.iter().map(|(Item,_arg)| Item)], - div![s().ml(gap.clone()).display_flex().flex_direction_row().justify_content_flex_end(), right_nodes.iter().map(|(Item,_arg)| Item)], + s().grid_template_columns("minmax(0px, 1fr) auto minmax(0px, 1fr)") + .grid_template_rows("minmax(0,1fr)"), + div![ + s().mr(gap.clone()) + .display_flex() + .flex_direction_row() + .justify_content_flex_start(), + left_nodes.iter().map(|(Item, _arg)| Item) + ], + div![ + s().mx(gap.clone()) + .display_flex() + .flex_direction_row() + .justify_content_center(), + center_nodes.iter().map(|(Item, _arg)| Item) + ], + div![ + s().ml(gap.clone()) + .display_flex() + .flex_direction_row() + .justify_content_flex_end(), + right_nodes.iter().map(|(Item, _arg)| Item) + ], ], } } - - - - pub enum ColumnAlign { Top, Middle, @@ -210,69 +322,133 @@ pub struct ColumnItemArgs { } impl std::default::Default for ColumnItemArgs { - fn default() -> Self { - ColumnItemArgs { + fn default() -> Self { + ColumnItemArgs { align: ColumnAlign::Top, flex: Flex::Unset, - } + } } } - #[view_macro] #[allow(non_snake_case)] -pub fn Column_view(args: RowColumnArgs, mut root: Node, mut children: Vec>, mut Item: Vec<(Node, ColumnItemArgs)>) -> Node { - let (flex,gap, padding) = (args.flex, args.gap, args.padding); +pub fn Column_view( + args: RowColumnArgs, + mut root: Node, + mut children: Vec>, + mut Item: Vec<(Node, ColumnItemArgs)>, +) -> Node { + let (flex, gap, padding) = (args.flex, args.gap, args.padding); - let mut gap = gap.clone(); + let mut gap = gap.clone(); gap.value = gap.value / 2.0; - + let mut top_nodes = vec![]; let mut middle_nodes = vec![]; let mut bottom_nodes = vec![]; - for Item in Item.drain(0..) { let mut item = Item; item.0.style(s().my(gap.clone())); item.0.style(s().first_child().margin_top(px(0))); item.0.style(s().last_child().margin_bottom(px(0))); - - + match &item.1.flex { Flex::Unset => (), Flex::None => item.0.style(s().flex("0 0 auto")), - Flex::Full => item.0.style(s().flex("1 1 0%").min_width(px(0)).min_height(px(0))), + Flex::Full => item + .0 + .style(s().flex("1 1 0%").min_width(px(0)).min_height(px(0))), Flex::Content => item.0.style(s().flex("1 0 auto")), Flex::Custom(flex_string) => item.0.style(s().flex(flex_string.as_str())), } match item.1.align { - ColumnAlign::Top => {item.0.style(s().p(padding.clone()).name("col_item"));top_nodes.push(item)}, - ColumnAlign::Bottom=> {item.0.style(s().p(padding.clone()).name("col_item"));bottom_nodes.insert(0,item)}, - ColumnAlign::Middle =>{item.0.style(s().p(padding.clone()).name("col_item")); middle_nodes.push(item)}, - ColumnAlign::TopLeft => {item.0.style(s().align_self_flex_start().p(padding.clone()).name("col_item")); top_nodes.push(item);}, - ColumnAlign::MiddleLeft=> {item.0.style(s().align_self_flex_start().p(padding.clone()).name("col_item")); middle_nodes.push(item)}, - ColumnAlign::BottomLeft => {item.0.style(s().align_self_flex_start().p(padding.clone()).name("col_item")); bottom_nodes.insert(0,item)}, - ColumnAlign::TopCenter => {item.0.style(s().align_self_center().p(padding.clone()).name("col_item")); top_nodes.push(item)}, - ColumnAlign::MiddleCenter => {item.0.style(s().align_self_center().p(padding.clone()).name("col_item")); middle_nodes.push(item)}, - ColumnAlign::BottomCenter => {item.0.style(s().align_self_center().p(padding.clone()).name("col_item")); bottom_nodes.insert(0,item)}, - ColumnAlign::TopRight => {item.0.style(s().align_self_flex_end().p(padding.clone()).name("col_item")); top_nodes.push(item)}, - ColumnAlign::MiddleRight => {item.0.style(s().align_self_flex_end().p(padding.clone()).name("col_item")); middle_nodes.push(item)}, - ColumnAlign::BottomRight => {item.0.style(s().align_self_flex_end().p(padding.clone()).name("col_item")); bottom_nodes.insert(0,item)}, + ColumnAlign::Top => { + item.0.style(s().p(padding.clone()).name("col_item")); + top_nodes.push(item) + } + ColumnAlign::Bottom => { + item.0.style(s().p(padding.clone()).name("col_item")); + bottom_nodes.insert(0, item) + } + ColumnAlign::Middle => { + item.0.style(s().p(padding.clone()).name("col_item")); + middle_nodes.push(item) + } + ColumnAlign::TopLeft => { + item.0.style( + s().align_self_flex_start() + .p(padding.clone()) + .name("col_item"), + ); + top_nodes.push(item); + } + ColumnAlign::MiddleLeft => { + item.0.style( + s().align_self_flex_start() + .p(padding.clone()) + .name("col_item"), + ); + middle_nodes.push(item) + } + ColumnAlign::BottomLeft => { + item.0.style( + s().align_self_flex_start() + .p(padding.clone()) + .name("col_item"), + ); + bottom_nodes.insert(0, item) + } + ColumnAlign::TopCenter => { + item.0 + .style(s().align_self_center().p(padding.clone()).name("col_item")); + top_nodes.push(item) + } + ColumnAlign::MiddleCenter => { + item.0 + .style(s().align_self_center().p(padding.clone()).name("col_item")); + middle_nodes.push(item) + } + ColumnAlign::BottomCenter => { + item.0 + .style(s().align_self_center().p(padding.clone()).name("col_item")); + bottom_nodes.insert(0, item) + } + ColumnAlign::TopRight => { + item.0.style( + s().align_self_flex_end() + .p(padding.clone()) + .name("col_item"), + ); + top_nodes.push(item) + } + ColumnAlign::MiddleRight => { + item.0.style( + s().align_self_flex_end() + .p(padding.clone()) + .name("col_item"), + ); + middle_nodes.push(item) + } + ColumnAlign::BottomRight => { + item.0.style( + s().align_self_flex_end() + .p(padding.clone()) + .name("col_item"), + ); + bottom_nodes.insert(0, item) + } } } - for mut c in children.drain(0..){ + for mut c in children.drain(0..) { c.style(s().mx(gap.clone())); c.style(s().first_child().margin_top(px(0))); c.style(s().last_child().margin_bottom(px(0))); top_nodes.push((c, ColumnItemArgs::default())); } - - - root.style(s().name("row_layout").display_grid()); match flex { Flex::Unset => (), @@ -282,40 +458,107 @@ pub fn Column_view(args: RowColumnArgs, mut root: Node, mut children: Ve Flex::Custom(flex_string) => root.style(s().flex(flex_string.as_str())), } - - root.style(s().flex("1 1 0%").min_height(px(0)).name("column_layout").display_grid()); + root.style( + s().flex("1 1 0%") + .min_height(px(0)) + .name("column_layout") + .display_grid(), + ); - match ( top_nodes.len(), middle_nodes.len(), bottom_nodes.len()){ + match (top_nodes.len(), middle_nodes.len(), bottom_nodes.len()) { (0, 0, 0) => empty![], (0, 0, _) => root![ - s().grid_template_rows("minmax(0px, 1fr)").grid_template_columns("minmax(0,1fr)"), - div![s().display_flex().flex_direction_column().justify_content_flex_end(),bottom_nodes.iter().map(|(Item,_arg)| Item)], + s().grid_template_rows("minmax(0px, 1fr)") + .grid_template_columns("minmax(0,1fr)"), + div![ + s().display_flex() + .flex_direction_column() + .justify_content_flex_end(), + bottom_nodes.iter().map(|(Item, _arg)| Item) + ], ], (0, _, 0) => root![ - s().grid_template_rows("auto").grid_template_columns("minmax(0,1fr)"), - div![s().display_flex().flex_direction_column().justify_content_center(), middle_nodes.iter().map(|(Item,_arg)| Item)], + s().grid_template_rows("auto") + .grid_template_columns("minmax(0,1fr)"), + div![ + s().display_flex() + .flex_direction_column() + .justify_content_center(), + middle_nodes.iter().map(|(Item, _arg)| Item) + ], ], (0, _, _) => root![ - s().grid_template_rows("minmax(0px, 1fr) auto minmax(0px, 1fr)").grid_template_columns("minmax(0,1fr)"), + s().grid_template_rows("minmax(0px, 1fr) auto minmax(0px, 1fr)") + .grid_template_columns("minmax(0,1fr)"), div![], - div![s().mb(gap.clone()).display_flex().flex_direction_column().justify_content_center(), middle_nodes.iter().map(|(Item,_arg)| Item)], - div![s().mt(gap.clone()).display_flex().flex_direction_column().justify_content_flex_end(), bottom_nodes.iter().map(|(Item,_arg)| Item)], + div![ + s().mb(gap.clone()) + .display_flex() + .flex_direction_column() + .justify_content_center(), + middle_nodes.iter().map(|(Item, _arg)| Item) + ], + div![ + s().mt(gap.clone()) + .display_flex() + .flex_direction_column() + .justify_content_flex_end(), + bottom_nodes.iter().map(|(Item, _arg)| Item) + ], ], (_, 0, 0) => root![ - s().grid_template_rows("minmax(0px, 1fr)").grid_template_columns("minmax(0,1fr)"), - div![s().display_flex().flex_direction_column().justify_content_flex_start(), top_nodes.iter().map(|(Item,_arg)| Item)], + s().grid_template_rows("minmax(0px, 1fr)") + .grid_template_columns("minmax(0,1fr)"), + div![ + s().display_flex() + .flex_direction_column() + .justify_content_flex_start(), + top_nodes.iter().map(|(Item, _arg)| Item) + ], ], (_, 0, _) => root![ - s().grid_template_rows("minmax(0px, 1fr) minmax(0px, 1fr)").grid_template_columns("minmax(0,1fr)"), - div![s().mb(gap.clone()).display_flex().flex_direction_column().justify_content_flex_start(), top_nodes.iter().map(|(Item,_arg)| Item)], - div![s().mt(gap.clone()).display_flex().flex_direction_column().justify_content_flex_end(), bottom_nodes.iter().map(|(Item,_arg)| Item)], + s().grid_template_rows("minmax(0px, 1fr) minmax(0px, 1fr)") + .grid_template_columns("minmax(0,1fr)"), + div![ + s().mb(gap.clone()) + .display_flex() + .flex_direction_column() + .justify_content_flex_start(), + top_nodes.iter().map(|(Item, _arg)| Item) + ], + div![ + s().mt(gap.clone()) + .display_flex() + .flex_direction_column() + .justify_content_flex_end(), + bottom_nodes.iter().map(|(Item, _arg)| Item) + ], ], (_, _, _) => root![ - s().grid_template_rows("minmax(0px, 1fr) auto minmax(0px, 1fr)").grid_template_columns("minmax(0,1fr)"), - div![s().mb(gap.clone()).display_flex().flex_direction_column().justify_content_flex_start(), top_nodes.iter().map(|(Item,_arg)| Item)], - div![s().my(gap.clone()).display_flex().flex_direction_column().justify_content_center(), middle_nodes.iter().map(|(Item,_arg)| Item)], - div![s().mt(gap.clone()).display_flex().flex_direction_column().justify_content_flex_end(), bottom_nodes.iter().map(|(Item,_arg)| Item)], + s().grid_template_rows("minmax(0px, 1fr) auto minmax(0px, 1fr)") + .grid_template_columns("minmax(0,1fr)"), + div![ + s().mb(gap.clone()) + .display_flex() + .flex_direction_column() + .justify_content_flex_start(), + top_nodes.iter().map(|(Item, _arg)| Item) + ], + div![ + s().my(gap.clone()) + .display_flex() + .flex_direction_column() + .justify_content_center(), + middle_nodes.iter().map(|(Item, _arg)| Item) + ], + div![ + s().mt(gap.clone()) + .display_flex() + .flex_direction_column() + .justify_content_flex_end(), + bottom_nodes.iter().map(|(Item, _arg)| Item) + ], ], } } -// pub use Column; \ No newline at end of file +// pub use Column; diff --git a/seed_styles/src/style/theme.rs b/seed_styles/src/style/theme.rs index 59e6c64..3a4bbbe 100644 --- a/seed_styles/src/style/theme.rs +++ b/seed_styles/src/style/theme.rs @@ -4,13 +4,13 @@ use crate::style::ReturnBpTuple; use crate::style::{CssValueTrait, Rule, Style, UpdateStyle}; use anymap::any::Any; use seed::{prelude::*, *}; +use seed_hooks::atom::Atom; use seed_hooks::*; use seed_style_macros::generate_froms; use std::cell::RefCell; use std::collections::HashMap; use std::hash::Hash; use std::marker::PhantomData; -use seed_hooks::atom::Atom; pub trait BorderTheme: Eq + Hash + Clone {} pub trait BorderWidthTheme: Eq + Hash + Clone {} @@ -34,15 +34,14 @@ thread_local! { static THEMES_VEC : RefCell> = RefCell::new(vec![]); } - pub fn change_theme_with_name(name: &str, theme: Theme) { - app_themes().update( |v| + app_themes().update(|v| { if let Some(existing_theme) = v.iter_mut().find(|t| &t.name == name) { let _old_theme = std::mem::replace(existing_theme, theme); } else { panic!("old theme doesnt exist"); } - ) + }) } impl From for CssWidth { @@ -1344,27 +1343,22 @@ where } } -pub fn at_breakpoint_and_above(bp: T) -> bool +pub fn at_breakpoint_and_above(bp: T) -> bool where - T: BreakpointTheme + 'static,{ + T: BreakpointTheme + 'static, +{ let bp_pair = with_themes(ReturnBpTuple(bp)); match bp_pair { - (lower, Some(_higher)) => { - window() - .match_media(&format!("(min-width: {}px)", lower)) - .unwrap() - .unwrap() - .matches() - - } - (lower, None) => { - window() - .match_media(&format!("(min-width: {}px)", lower)) - .unwrap() - .unwrap() - .matches() - - } + (lower, Some(_higher)) => window() + .match_media(&format!("(min-width: {}px)", lower)) + .unwrap() + .unwrap() + .matches(), + (lower, None) => window() + .match_media(&format!("(min-width: {}px)", lower)) + .unwrap() + .unwrap() + .matches(), } } @@ -1498,7 +1492,6 @@ pub trait ActOnIteratorOfThemes { // } // } - #[atom] pub fn app_themes() -> Atom> { vec![] @@ -1508,13 +1501,10 @@ pub fn with_themes(with: Q) -> R where Q: ActOnIteratorOfThemes, { - app_themes().observe_with (|v| - with.call(v.iter()) - ) + app_themes().observe_with(|v| with.call(v.iter())) } - -pub fn load_app_themes(themes:&[fn()->Theme]) { +pub fn load_app_themes(themes: &[fn() -> Theme]) { for theme in themes { app_themes().update(|t| t.push(theme())) } @@ -1814,8 +1804,6 @@ impl Theme { self.overloaded_general_lookup(alias) } - - pub fn get(&self, alias: T) -> Option where Self: OverloadedStyleLookUp,