use crate::view::View;
pub trait Component {
fn render(&self) -> View;
}
pub trait ComponentState {
type Props;
fn new(props: Self::Props) -> Self;
fn render(&self) -> View;
}
#[macro_export]
macro_rules! component {
($name:ident, $body:expr) => {
pub fn $name() -> $crate::view::View {
$body
}
};
}
#[macro_export]
macro_rules! stateful_component {
($name:ident { $($field:ident: $ty:ty),* $(,)? } => $render:expr) => {
pub struct $name {
$(pub $field: $ty),*
}
impl $crate::component::Component for $name {
fn render(&self) -> $crate::view::View {
$render(self)
}
}
};
}
#[cfg(test)]
mod tests {
use crate::component::Component;
use crate::view::View;
crate::component! {
test_banner,
View::text("banner")
}
#[test]
fn component_macro_renders_view() {
let v = test_banner();
assert_eq!(v.view_type(), "Text");
}
#[test]
fn component_trait_render() {
struct StaticRow;
impl Component for StaticRow {
fn render(&self) -> View {
View::label("row")
}
}
assert_eq!(StaticRow.render().view_type(), "Label");
}
}