#[macro_export]
macro_rules! impl_debug {
($ty:ty) => {
impl core::fmt::Debug for $ty {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(core::any::type_name::<Self>())
}
}
};
}
#[macro_export]
macro_rules! raw_view {
($ty:ty, $axis:expr) => {
impl $crate::NativeView for $ty {
fn stretch_axis(&self) -> $crate::layout::StretchAxis {
$axis
}
}
impl $crate::View for $ty {
fn body(self, _env: &$crate::Environment) -> impl $crate::View {
$crate::Native::new(self)
}
fn stretch_axis(&self) -> $crate::layout::StretchAxis {
$axis
}
}
};
($ty:ty) => {
impl $crate::NativeView for $ty {}
impl $crate::View for $ty {
fn body(self, _env: &$crate::Environment) -> impl $crate::View {
$crate::Native::new(self)
}
fn stretch_axis(&self) -> $crate::layout::StretchAxis {
$crate::layout::StretchAxis::None
}
}
};
}
#[macro_export]
macro_rules! configurable {
(@impl $(#[$meta:meta])*; $view:ident, $config:ty, $axis:expr) => {
$crate::configurable!(
@impl $(#[$meta])*;
$view,
$config,
$axis,
|config: $config, _env: &$crate::Environment| config
);
};
(@impl $(#[$meta:meta])*; $view:ident, $config:ty, $axis:expr, $resolve_native:expr) => {
$(#[$meta])*
pub struct $view($config);
impl $crate::NativeView for $config {
fn stretch_axis(&self) -> $crate::layout::StretchAxis {
$axis
}
}
impl $crate::view::ConfigurableView for $view {
type Config = $config;
#[inline] fn config(self) -> Self::Config { self.0 }
}
impl $crate::view::ViewConfiguration for $config {
type View = $view;
#[inline] fn render(self) -> Self::View { $view(self) }
}
impl From<$config> for $view {
#[inline] fn from(value: $config) -> Self { Self(value) }
}
impl $crate::view::View for $view {
fn body(self, env: &$crate::Environment) -> impl $crate::View {
use $crate::view::ConfigurableView;
let config = self.config();
if let Some(hook) = env.get::<$crate::view::Hook<$config>>() {
$crate::AnyView::new(hook.apply(env, config))
} else {
$crate::AnyView::new($crate::Native::new(($resolve_native)(config, env)))
}
}
fn stretch_axis(&self) -> $crate::layout::StretchAxis {
$crate::NativeView::stretch_axis(&self.0)
}
}
};
(@impl_dynamic $(#[$meta:meta])*; $view:ident, $config:ty, $stretch_fn:expr) => {
$crate::configurable!(
@impl_dynamic $(#[$meta])*;
$view,
$config,
$stretch_fn,
|config: $config, _env: &$crate::Environment| config
);
};
(@impl_dynamic $(#[$meta:meta])*; $view:ident, $config:ty, $stretch_fn:expr, $resolve_native:expr) => {
$(#[$meta])*
#[derive(Debug)]
pub struct $view($config);
impl $crate::NativeView for $config {
fn stretch_axis(&self) -> $crate::layout::StretchAxis {
($stretch_fn)(self)
}
}
impl $crate::view::ConfigurableView for $view {
type Config = $config;
#[inline] fn config(self) -> Self::Config { self.0 }
}
impl $crate::view::ViewConfiguration for $config {
type View = $view;
#[inline] fn render(self) -> Self::View { $view(self) }
}
impl From<$config> for $view {
#[inline] fn from(value: $config) -> Self { Self(value) }
}
impl $crate::view::View for $view {
fn body(self, env: &$crate::Environment) -> impl $crate::View {
use $crate::view::ConfigurableView;
let config = self.config();
if let Some(hook) = env.get::<$crate::view::Hook<$config>>() {
$crate::AnyView::new(hook.apply(env, config))
} else {
$crate::AnyView::new($crate::Native::new(($resolve_native)(config, env)))
}
}
fn stretch_axis(&self) -> $crate::layout::StretchAxis {
$crate::NativeView::stretch_axis(&self.0)
}
}
};
($(#[$meta:meta])* $view:ident, $config:ty, |$param:ident| $body:expr, resolve |$config_param:ident, $env_param:ident| $resolve_body:expr) => {
$crate::configurable!(
@impl_dynamic $(#[$meta])*;
$view,
$config,
|$param: &$config| $body,
|$config_param: $config, $env_param: &$crate::Environment| $resolve_body
);
};
($(#[$meta:meta])* $view:ident, $config:ty, |$param:ident| $body:expr) => {
$crate::configurable!(@impl_dynamic $(#[$meta])*; $view, $config, |$param: &$config| $body);
};
($(#[$meta:meta])* $view:ident, $config:ty, $axis:expr, resolve |$config_param:ident, $env_param:ident| $body:expr) => {
$crate::configurable!(
@impl $(#[$meta])*;
$view,
$config,
$axis,
|$config_param: $config, $env_param: &$crate::Environment| $body
);
};
($(#[$meta:meta])* $view:ident, $config:ty, $axis:expr) => {
$crate::configurable!(@impl $(#[$meta])*; $view, $config, $axis);
};
($(#[$meta:meta])* $view:ident, $config:ty, resolve |$config_param:ident, $env_param:ident| $body:expr) => {
$crate::configurable!(
@impl $(#[$meta])*;
$view,
$config,
$crate::layout::StretchAxis::None,
|$config_param: $config, $env_param: &$crate::Environment| $body
);
};
($(#[$meta:meta])* $view:ident, $config:ty) => {
$crate::configurable!(@impl $(#[$meta])*; $view, $config, $crate::layout::StretchAxis::None);
};
}
macro_rules! tuples {
($macro:ident) => {
$macro!();
$macro!(T0);
$macro!(T0, T1);
$macro!(T0, T1, T2);
$macro!(T0, T1, T2, T3);
$macro!(T0, T1, T2, T3, T4);
$macro!(T0, T1, T2, T3, T4, T5);
$macro!(T0, T1, T2, T3, T4, T5, T6);
$macro!(T0, T1, T2, T3, T4, T5, T6, T7);
$macro!(T0, T1, T2, T3, T4, T5, T6, T7, T8);
$macro!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);
$macro!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
$macro!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
$macro!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
$macro!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
$macro!(
T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
);
};
}
#[macro_export]
macro_rules! impl_extractor {
($ty:ty) => {
impl $crate::extract::Extractor for $ty {
fn extract(env: &$crate::Environment) -> core::result::Result<Self, $crate::Error> {
$crate::extract::Extractor::extract(env)
.map(|value: $crate::extract::Use<$ty>| value.0)
}
}
};
}
#[macro_export]
macro_rules! impl_deref {
($ty:ty,$target:ty) => {
impl core::ops::Deref for $ty {
type Target = $target;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl core::ops::DerefMut for $ty {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
};
}