yew_and_bulma_macros/lib.rs
1//! # Procedural macros for [Yew and Bulma][yew-and-bulma]
2//!
3//! This crate provides various [procedural macros][proc-macro] for the
4//! [Yew and Bulma][yew-and-bulma] crate. Most importantly, the
5//! [`macro@crate::base_component_properties`] macro, which adds various HTML
6//! attributes, such as `id`, `class` or event attributes like `onclick`.
7//!
8//! ### Supported Targets (for Yew Client-Side Rendering only)
9//! - `wasm32-unknown-unknown`
10//!
11//! # Examples
12//!
13//! ```rust
14//! use yew_and_bulma_macros::base_component_properties;
15//!
16//! // This will add the `id`, `class` and all standard event HTML attributes.
17//! #[base_component_properties]
18//! // #[derive(Properties, PartialEq)] // From yew
19//! struct MyProperties;
20//! ```
21//!
22//! [yew-and-bulma]: https://crates.io/crates/yew-and-bulma
23//! [proc-macro]: https://doc.rust-lang.org/reference/procedural-macros.html
24#![cfg_attr(nightly_error_messages, feature(rustc_attrs))]
25#![forbid(unsafe_code)]
26
27/// Provides all HTML attributes which should be added to properties.
28///
29/// Defines helpers and provides definitions for all HTML attributes that
30/// should be found on [Yew component properties][yew].
31///
32/// [yew]: https://yew.rs/docs/concepts/function-components/properties
33mod attributes;
34
35use core::panic;
36
37use proc_macro::TokenStream;
38use quote::quote;
39use syn::{parse_macro_input, DeriveInput};
40
41use crate::attributes::BaseAttributes;
42
43/// Adds fields for the `id`, `class` and [all standard event][events] HTML
44/// attributes.
45///
46/// # Examples
47///
48/// ```rust
49/// use yew_and_bulma_macros::base_component_properties;
50///
51/// // This will add the `id`, `class` and all standard event HTML attributes.
52/// #[base_component_properties]
53/// // #[derive(Properties, PartialEq)] // From yew
54/// struct MyProperties;
55/// ```
56///
57/// [events]: https://developer.mozilla.org/en-US/docs/Web/API/Element#events
58#[proc_macro_attribute]
59pub fn base_component_properties(_args: TokenStream, input: TokenStream) -> TokenStream {
60 let input = parse_macro_input!(input as DeriveInput);
61
62 let mut struct_data = match input.data.clone() {
63 syn::Data::Struct(struct_data) => struct_data,
64 _ => panic!("`BaseProperties` must be used on structs."),
65 };
66
67 let expanded = match &mut struct_data.fields {
68 syn::Fields::Named(fields) => {
69 for attr in BaseAttributes::default().attributes() {
70 fields.named.push(attr);
71 }
72
73 let struct_data = DeriveInput {
74 data: syn::Data::Struct(struct_data),
75 ..input
76 };
77
78 quote! {
79 #struct_data
80 }
81 }
82 _ => quote! { #input },
83 };
84
85 expanded.into()
86}