rust-dominator/src/macros.rs

152 lines
4.2 KiB
Rust

#[macro_export]
macro_rules! apply_methods {
($this:expr, {}) => {
$this
};
($this:expr, { .$name:ident!($($args:tt)*) $($rest:tt)* }) => {{
let this = $this;
let this = $name!(this, $($args)*);
$crate::apply_methods!(this, { $($rest)* })
}};
($this:expr, { .$name:ident($($args:expr),*) $($rest:tt)* }) => {{
let this = $this.$name($($args),*);
$crate::apply_methods!(this, { $($rest)* })
}};
($this:expr, { .$name:ident::<$($types:ty),*>($($args:expr),*) $($rest:tt)* }) => {{
let this = $this.$name::<$($types),*>($($args),*);
$crate::apply_methods!(this, { $($rest)* })
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __internal_builder {
($default:ty, $make:ident, $kind:expr) => {
$crate::__internal_builder!($default, $make, $kind => $default, {})
};
($default:ty, $make:ident, $kind:expr, $($rest:tt)*) => {
$crate::__internal_builder!($default, $make, $kind => $default, $($rest)*)
};
($default:ty, $make:ident, $kind:expr => $t:ty) => {
$crate::__internal_builder!($default, $make, $kind => $t, {})
};
($default:ty, $make:ident, $kind:expr => $t:ty, $($methods:tt)*) => {{
let builder = $crate::DomBuilder::<$t>::$make($kind);
let output = $crate::apply_methods!(builder, $($methods)*);
$crate::DomBuilder::into_dom(output)
}};
}
#[macro_export]
macro_rules! with_node {
($this:ident, $name:ident => { $($methods:tt)* }) => {{
let $name = $crate::DomBuilder::__internal_element(&$this);
$crate::apply_methods!($this, { $($methods)* })
}};
}
#[macro_export]
macro_rules! with_cfg {
($this:ident, $cfg:meta, { $($methods:tt)* }) => {{
#[cfg($cfg)]
let this = $crate::apply_methods!($this, { $($methods)* });
#[cfg(not($cfg))]
let this = $this;
this
}};
}
#[macro_export]
macro_rules! shadow_root {
($this:ident, $mode:expr => { $($methods:tt)* }) => {{
let shadow = $crate::DomBuilder::__internal_shadow_root(&$this, $mode);
let shadow = $crate::apply_methods!(shadow, { $($methods)* });
$crate::DomBuilder::__internal_transfer_callbacks($this, shadow)
}};
}
#[macro_export]
macro_rules! html {
($($args:tt)+) => {
$crate::__internal_builder!($crate::__internal::HtmlElement, new_html, $($args)+)
};
}
#[macro_export]
macro_rules! svg {
($($args:tt)+) => {
$crate::__internal_builder!($crate::__internal::SvgElement, new_svg, $($args)+)
};
}
#[macro_export]
macro_rules! dom_builder {
($node:expr, { $($methods:tt)* }) => {{
let builder = $crate::DomBuilder::new($node);
let output = $crate::apply_methods!(builder, { $($methods)* });
$crate::DomBuilder::into_dom(output)
}};
}
#[macro_export]
macro_rules! stylesheet {
($rule:expr) => {
$crate::stylesheet!($rule, {})
};
($rule:expr, { $($methods:tt)* }) => {
$crate::StylesheetBuilder::__internal_done($crate::apply_methods!($crate::StylesheetBuilder::__internal_new($rule), { $($methods)* }))
};
}
#[macro_export]
macro_rules! class {
($($methods:tt)*) => {{
$crate::ClassBuilder::__internal_done($crate::apply_methods!($crate::ClassBuilder::__internal_new(), { $($methods)* }))
}};
}
#[macro_export]
macro_rules! pseudo {
($this:ident, $rules:expr) => {
$crate::pseudo!($this, $rules, {})
};
($this:ident, $rules:expr, { $($methods:tt)* }) => {{
$crate::stylesheet!($crate::__internal::Pseudo::new($crate::ClassBuilder::__internal_class_name(&$this), $rules), { $($methods)* });
$this
}};
}
// TODO this is pretty inefficient, it iterates over the token tree one token at a time
// TODO this should only work for ::std::clone::Clone::clone
#[doc(hidden)]
#[macro_export]
macro_rules! __internal_clone_split {
(($($x:ident)*), $t:ident => $y:expr) => {{
$(let $x = $x.clone();)*
let $t = $t.clone();
$y
}};
(($($x:ident)*), $t:ident, $($after:tt)*) => {
$crate::__internal_clone_split!(($($x)* $t), $($after)*)
};
}
// TODO move into gloo ?
#[macro_export]
macro_rules! clone {
($($input:tt)*) => { $crate::__internal_clone_split!((), $($input)*) };
}