diff --git a/src/css.rs b/src/css.rs new file mode 100644 index 0000000..1ed1c97 --- /dev/null +++ b/src/css.rs @@ -0,0 +1,171 @@ +#[macro_export] +macro_rules! __css { + ($style:expr,)=>{}; + ( + $style:expr, ($name:ident): $value:expr + ) => {{ + $style.other.insert(stringify!($name).to_string(), Box::new($value)); + }}; + ( + $style:expr, ($name:ident): $value:expr, $($other:tt)* + ) => {{ + $style.other.insert(stringify!($name).to_string(), Box::new($value)); + $crate::__css!($($other)*); + }}; + ( + $style:expr, $name:ident: $value:expr + ) => {{ + $style.$name = $value; + }}; +} + +#[macro_export] +macro_rules! _css { + ($style:expr,) => {}; + ( + $hm:expr, .$name:ident { $($inner:tt)* } $($rest:tt)* + ) => {{ + let name = $crate::ui::StyleName::Class(stringify!($name).to_string()); + if let Some(style) = $hm.get_mut(&name) { + $crate::__css!(style.0, $($inner)*); + } else { + let mut style = $crate::ui::Style::default(); + + $crate::__css!(style.0, $($inner)*); + + $hm.insert( + name, + style, + ); + } + $crate::_css!($hm, $($rest)*); + }}; + ( + $hm:expr, .$name:ident:$kind:ident { $($inner:tt)* } $($rest:tt)* + ) => {{ + let name = $crate::ui::StyleName::Class(stringify!($name).to_string()); + if let Some(style) = $hm.get_mut(&name) { + let mut style_elem = $crate::ui::StyleElement::default(); + $crate::__css!(style_elem, $($inner)*); + style.1.insert(stringify!($kind).to_string(), style_elem); + } else { + let mut style = $crate::ui::Style::default(); + + let mut style_elem = $crate::ui::StyleElement::default(); + $crate::__css!(style_elem, $($inner)*); + style.1.insert(stringify!($kind).to_string(), style_elem); + + $hm.insert( + name, + style, + ); + } + $crate::_css!($hm, $($rest)*); + }}; + + + ( + $hm:expr, #$name:ident { $($inner:tt)* } $($rest:tt)* + ) => {{ + let name = $crate::ui::StyleName::Id(stringify!($name).to_string()); + if let Some(style) = $hm.get_mut(&name) { + $crate::__css!(style.0, $($inner)*); + } else { + let mut style = $crate::ui::Style::default(); + + $crate::__css!(style.0, $($inner)*); + + $hm.insert( + name, + style, + ); + } + $crate::_css!($hm, $($rest)*); + }}; + ( + $hm:expr, #$name:ident:$kind:ident { $($inner:tt)* } $($rest:tt)* + ) => {{ + let name = $crate::ui::StyleName::Id(stringify!($name).to_string()); + if let Some(style) = $hm.get_mut(&name) { + let mut style_elem = $crate::ui::StyleElement::default(); + $crate::__css!(style_elem, $($inner)*); + style.1.insert(stringify!($kind).to_string(), style_elem); + } else { + let mut style = $crate::ui::Style::default(); + + let mut style_elem = $crate::ui::StyleElement::default(); + $crate::__css!(style_elem, $($inner)*); + style.1.insert(stringify!($kind).to_string(), style_elem); + + $hm.insert( + name, + style, + ); + } + $crate::_css!($hm, $($rest)*); + }}; + + + ( + $hm:expr, $name:ident { $($inner:tt)* } $($rest:tt)* + ) => {{ + let name = $crate::ui::StyleName::Component(stringify!($name).to_string()); + if let Some(style) = $hm.get_mut(&name) { + $crate::__css!(style.0, $($inner)*); + } else { + let mut style = $crate::ui::Style::default(); + + $crate::__css!(style.0, $($inner)*); + + $hm.insert( + name, + style, + ); + } + $crate::_css!($hm, $($rest)*); + }}; + ( + $hm:expr, $name:ident:$kind:ident { $($inner:tt)* } $($rest:tt)* + ) => {{ + let name = $crate::ui::StyleName::Component(stringify!($name).to_string()); + if let Some(style) = $hm.get_mut(&name) { + let mut style_elem = $crate::ui::StyleElement::default(); + $crate::__css!(style_elem, $($inner)*); + style.1.insert(stringify!($kind).to_string(), style_elem); + } else { + let mut style = $crate::ui::Style::default(); + + let mut style_elem = $crate::ui::StyleElement::default(); + $crate::__css!(style_elem, $($inner)*); + style.1.insert(stringify!($kind).to_string(), style_elem); + + $hm.insert( + name, + style, + ); + } + $crate::_css!($hm, $($rest)*); + }}; +} + +/// Creates a styling map `Css` +/// +/// # Examples +/// ``` +/// .btn: clicked { +/// color: Blue +/// } +/// ``` +/// +/// # Returns +/// `Css` +#[macro_export] +macro_rules! css { + ( + $($inner:tt)* + ) => {{ + let mut hm: $crate::ui::Css = std::collections::HashMap::new(); + $crate::_css!(hm, $($inner)*); + hm + }}; +} diff --git a/src/lib.rs b/src/lib.rs index 92b23b6..040d1da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,8 @@ pub mod app; pub mod macros; pub mod ui; pub mod utils; +pub mod rsx; +pub mod css; pub use app::run; diff --git a/src/macros.rs b/src/macros.rs index 54c5fea..02ecc4c 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,90 +1,3 @@ -#[macro_export] -macro_rules! parse_rsx_param { - ($elem:expr, $($k:ident).+: $v:expr) => { - $elem.$($k).+ = $v; - }; - - ($elem:expr, $($k:ident).+: $v:expr, $($rest:tt)*) => { - $elem.$($k).+ = $v; - osui::parse_rsx_param!($elem, $($rest)*); - }; - ($elem:expr, $p:path) => { - $p; - }; - ($elem:expr, $($k:ident).+, $($rest:tt)*) => { - $elem.$($k).+; - osui::parse_rsx_param!($elem, $($rest)*); - }; - ($elem:expr, $($k:ident).+., $($rest:tt)*) => { - $elem.$($k). - +.; - osui::parse_rsx_param!($elem, $($rest)*); - }; - - ($elem:expr, $($k:ident).+.: $v:expr) => { - $elem.$($k).+. = $v; - }; - ($elem:expr, $($k:ident).+.: $v:expr, $($rest:tt)*) => { - $elem.$($k).+. = $v; - osui::parse_rsx_param!($elem, $($rest)*); - }; - - ($elem:expr, for ($($for:tt)*) { $($inner:tt)* } $($rest:tt)*) => { - if $elem.children.is_none() {$elem.children = $crate::Children::Children(Vec::new(), 0)} - if let $crate::Children::Children(children, _) = &mut $elem.children { - for $($for)* { - children.push({$($inner)*}) - } - } - osui::parse_rsx_param!($elem, $($rest)*); - }; - - ($elem:expr, {$inner_elem:expr} $($rest:tt)*) => { - if $elem.children.is_none() {$elem.children = $crate::Children::Children(Vec::new(), 0)} - if let $crate::Children::Children(children, _) = &mut $elem.children { - children.push({$inner_elem}); - } - osui::parse_rsx_param!($elem, $($rest)*); - }; - - ($elem:expr, $elem_path:path { $($inner:tt)* } $($rest:tt)*) => { - if $elem.children.is_none() {$elem.children = $crate::Children::Children(Vec::new(), 0)} - if let $crate::Children::Children(children, _) = &mut $elem.children { - children.push(osui::rsx_elem!($elem_path { $($inner)* })); - } - osui::parse_rsx_param!($elem, $($rest)*) - }; - - ($elem:expr, $text:expr) => { - if $elem.children.is_none() {$elem.children = $crate::Children::Text(format!($text))} - }; - ($elem:expr, $text:expr, $($inner:tt)*) => { - if $elem.children.is_none() {$elem.children = $crate::Children::Text(format!($text, $($inner)*))} - }; - - ($elem:expr, ) => {}; -} - -#[macro_export] -macro_rules! rsx_elem { - ($elem:path { $($inner:tt)* }) => {{ - #[allow(unused_mut)] - let mut elem = $elem(); - $crate::parse_rsx_param!(elem, $($inner)*); - elem as $crate::Element - }}; -} - -#[macro_export] -macro_rules! rsx { - ($($inner:tt)*) => {{ - let mut elem = $crate::ui::div(); - $crate::parse_rsx_param!(elem, $($inner)* ); - elem - }}; - -} - #[macro_export] macro_rules! val { ($a:expr) => { @@ -102,165 +15,4 @@ macro_rules! run_handler { ($self:ident.$handler:ident) => {{ &$self.$handler; }}; -} - -#[macro_export] -macro_rules! __css { - ($style:expr,)=>{}; - ( - $style:expr, ($name:ident): $value:expr - ) => {{ - $style.other.insert(stringify!($name).to_string(), Box::new($value)); - }}; - ( - $style:expr, ($name:ident): $value:expr, $($other:tt)* - ) => {{ - $style.other.insert(stringify!($name).to_string(), Box::new($value)); - $crate::__css!($($other)*); - }}; - ( - $style:expr, $name:ident: $value:expr - ) => {{ - $style.$name = $value; - }}; -} - -#[macro_export] -macro_rules! _css { - ($style:expr,) => {}; - ( - $hm:expr, .$name:ident { $($inner:tt)* } $($rest:tt)* - ) => {{ - let name = $crate::ui::StyleName::Class(stringify!($name).to_string()); - if let Some(style) = $hm.get_mut(&name) { - $crate::__css!(style.0, $($inner)*); - } else { - let mut style = $crate::ui::Style::default(); - - $crate::__css!(style.0, $($inner)*); - - $hm.insert( - name, - style, - ); - } - $crate::_css!($hm, $($rest)*); - }}; - ( - $hm:expr, .$name:ident:$kind:ident { $($inner:tt)* } $($rest:tt)* - ) => {{ - let name = $crate::ui::StyleName::Class(stringify!($name).to_string()); - if let Some(style) = $hm.get_mut(&name) { - let mut style_elem = $crate::ui::StyleElement::default(); - $crate::__css!(style_elem, $($inner)*); - style.1.insert(stringify!($kind).to_string(), style_elem); - } else { - let mut style = $crate::ui::Style::default(); - - let mut style_elem = $crate::ui::StyleElement::default(); - $crate::__css!(style_elem, $($inner)*); - style.1.insert(stringify!($kind).to_string(), style_elem); - - $hm.insert( - name, - style, - ); - } - $crate::_css!($hm, $($rest)*); - }}; - - - ( - $hm:expr, #$name:ident { $($inner:tt)* } $($rest:tt)* - ) => {{ - let name = $crate::ui::StyleName::Id(stringify!($name).to_string()); - if let Some(style) = $hm.get_mut(&name) { - $crate::__css!(style.0, $($inner)*); - } else { - let mut style = $crate::ui::Style::default(); - - $crate::__css!(style.0, $($inner)*); - - $hm.insert( - name, - style, - ); - } - $crate::_css!($hm, $($rest)*); - }}; - ( - $hm:expr, #$name:ident:$kind:ident { $($inner:tt)* } $($rest:tt)* - ) => {{ - let name = $crate::ui::StyleName::Id(stringify!($name).to_string()); - if let Some(style) = $hm.get_mut(&name) { - let mut style_elem = $crate::ui::StyleElement::default(); - $crate::__css!(style_elem, $($inner)*); - style.1.insert(stringify!($kind).to_string(), style_elem); - } else { - let mut style = $crate::ui::Style::default(); - - let mut style_elem = $crate::ui::StyleElement::default(); - $crate::__css!(style_elem, $($inner)*); - style.1.insert(stringify!($kind).to_string(), style_elem); - - $hm.insert( - name, - style, - ); - } - $crate::_css!($hm, $($rest)*); - }}; - - - ( - $hm:expr, $name:ident { $($inner:tt)* } $($rest:tt)* - ) => {{ - let name = $crate::ui::StyleName::Component(stringify!($name).to_string()); - if let Some(style) = $hm.get_mut(&name) { - $crate::__css!(style.0, $($inner)*); - } else { - let mut style = $crate::ui::Style::default(); - - $crate::__css!(style.0, $($inner)*); - - $hm.insert( - name, - style, - ); - } - $crate::_css!($hm, $($rest)*); - }}; - ( - $hm:expr, $name:ident:$kind:ident { $($inner:tt)* } $($rest:tt)* - ) => {{ - let name = $crate::ui::StyleName::Component(stringify!($name).to_string()); - if let Some(style) = $hm.get_mut(&name) { - let mut style_elem = $crate::ui::StyleElement::default(); - $crate::__css!(style_elem, $($inner)*); - style.1.insert(stringify!($kind).to_string(), style_elem); - } else { - let mut style = $crate::ui::Style::default(); - - let mut style_elem = $crate::ui::StyleElement::default(); - $crate::__css!(style_elem, $($inner)*); - style.1.insert(stringify!($kind).to_string(), style_elem); - - $hm.insert( - name, - style, - ); - } - $crate::_css!($hm, $($rest)*); - }}; -} - -#[macro_export] -macro_rules! css { - ( - $($inner:tt)* - ) => {{ - let mut hm: $crate::ui::Css = std::collections::HashMap::new(); - $crate::_css!(hm, $($inner)*); - hm - }}; -} +} \ No newline at end of file diff --git a/src/rsx.rs b/src/rsx.rs new file mode 100644 index 0000000..ea010bf --- /dev/null +++ b/src/rsx.rs @@ -0,0 +1,95 @@ +#[macro_export] +macro_rules! parse_rsx_param { + ($elem:expr, $($k:ident).+: $v:expr) => { + $elem.$($k).+ = $v; + }; + + ($elem:expr, $($k:ident).+: $v:expr, $($rest:tt)*) => { + $elem.$($k).+ = $v; + osui::parse_rsx_param!($elem, $($rest)*); + }; + ($elem:expr, $p:path) => { + $p; + }; + ($elem:expr, $($k:ident).+, $($rest:tt)*) => { + $elem.$($k).+; + osui::parse_rsx_param!($elem, $($rest)*); + }; + ($elem:expr, $($k:ident).+., $($rest:tt)*) => { + $elem.$($k). + +.; + osui::parse_rsx_param!($elem, $($rest)*); + }; + + ($elem:expr, $($k:ident).+.: $v:expr) => { + $elem.$($k).+. = $v; + }; + ($elem:expr, $($k:ident).+.: $v:expr, $($rest:tt)*) => { + $elem.$($k).+. = $v; + osui::parse_rsx_param!($elem, $($rest)*); + }; + + ($elem:expr, for ($($for:tt)*) { $($inner:tt)* } $($rest:tt)*) => { + if $elem.children.is_none() {$elem.children = $crate::Children::Children(Vec::new(), 0)} + if let $crate::Children::Children(children, _) = &mut $elem.children { + for $($for)* { + children.push({$($inner)*}) + } + } + osui::parse_rsx_param!($elem, $($rest)*); + }; + + ($elem:expr, {$inner_elem:expr} $($rest:tt)*) => { + if $elem.children.is_none() {$elem.children = $crate::Children::Children(Vec::new(), 0)} + if let $crate::Children::Children(children, _) = &mut $elem.children { + children.push({$inner_elem}); + } + osui::parse_rsx_param!($elem, $($rest)*); + }; + + ($elem:expr, $elem_path:path { $($inner:tt)* } $($rest:tt)*) => { + if $elem.children.is_none() {$elem.children = $crate::Children::Children(Vec::new(), 0)} + if let $crate::Children::Children(children, _) = &mut $elem.children { + children.push(osui::rsx_elem!($elem_path { $($inner)* })); + } + osui::parse_rsx_param!($elem, $($rest)*) + }; + + ($elem:expr, $text:expr) => { + if $elem.children.is_none() {$elem.children = $crate::Children::Text(format!($text))} + }; + ($elem:expr, $text:expr, $($inner:tt)*) => { + if $elem.children.is_none() {$elem.children = $crate::Children::Text(format!($text, $($inner)*))} + }; + + ($elem:expr, ) => {}; +} + +#[macro_export] +macro_rules! rsx_elem { + ($elem:path { $($inner:tt)* }) => {{ + #[allow(unused_mut)] + let mut elem = $elem(); + $crate::parse_rsx_param!(elem, $($inner)*); + elem as $crate::Element + }}; +} + +/// Makes a div and puts elements into it +/// +/// # Example +/// ``` +/// rsx! { +/// button { class: "btn", "Click me!" } +/// } +/// ``` +/// +/// # Returns +/// A `osui::Element` - Which is a `Box` +#[macro_export] +macro_rules! rsx { + ($($inner:tt)*) => { + $crate::rsx_elem!{ $crate::ui::div { $($inner)* } } + }; + +}