yew_alt_html/
lib.rs

1//! Alternative macro for building Html in Yew.
2//!
3//! This crate experiments on creating a macro that would be easier to use.
4//! For this, the [`html!` syntax](https://yew.rs/docs/concepts/html)
5//! that was a bit cumbersome to use
6//! is replaced by direct usage of values in `ah!`.
7//!
8//! Following problems should be solved by this crate:
9//!
10//! - Having to use `{}` inside tags even when values are simple literals.
11//! - Having to wrap attributes in `{}`
12//!   (mind that shorthand still uses `{ variable }`).
13//! - Having to repeat generics (Yew-only) and tag names
14//!   (not very HTML to omit, but still neat to have considered)
15//!   when closing tags.
16//! - Having to use fragment `<></>` when using multiple nodes in the macro root.
17//! - Not being able to use `match` just like `if`.
18//! - Cumbersome `{ for ... }` notation.
19//!
20//! ## Example
21//!
22//! ```rust
23//! use yew::prelude::*;
24//! use yew_alt_html::ah;
25//!
26//! enum LoadState {
27//!     Loading,
28//!     Failed,
29//!     Loaded,
30//! }
31//!
32//! #[function_component]
33//! pub fn App() -> Html {
34//!     let name = "Yew";
35//!     let italic_style = "font-style: italic";
36//!
37//!     use LoadState::*;
38//!     let state = Loaded;
39//!     let items = vec![1, 2, 3];
40//!     ah! {
41//!         <h1 style=italic_style>"Hello " name "!"</>
42//!         match state {
43//!             Loading => "Loading...",
44//!             Failed => "Load failed!",
45//!             Loaded => <p>"Welcome to "<code>"yew-alt-html"</>"!"</>,
46//!         }
47//!         <ul>
48//!             for item in items {
49//!                 <li>item</>
50//!             }
51//!         </>
52//!     }
53//! }
54//! ```
55
56mod content;
57mod logic;
58mod reader;
59
60#[macro_use]
61mod util;
62
63#[macro_use]
64mod tt;
65
66use proc_macro::*;
67pub(crate) use tt_call_macro;
68pub(crate) use tt_path;
69pub(crate) use tt_stream;
70
71use self::logic::errors::InvalidSyntax;
72use self::logic::read_children;
73use self::reader::TokenReader;
74
75macro_rules! impl_proc_macro {
76    ($($name:ident -> $yew_name:ident),* $(,)?) => {
77        $(#[proc_macro]
78        pub fn $name(item: TokenStream) -> TokenStream {
79            let reader = TokenReader::from(item);
80
81            match read_children::<read_children::InBlock>(reader) {
82                Ok(children) => tt_call_macro!(::yew::$yew_name!(children)),
83                Err(InvalidSyntax(e, span)) => tt::compile_error(e, span),
84            }
85        })*
86    };
87}
88
89impl_proc_macro!(ah -> html, ah_nested -> html_nested);