1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#![feature(proc_macro_diagnostic)]
#[macro_use] extern crate syn;
#[macro_use] extern crate quote;
#[macro_use]
mod macros;
mod attr;
mod enu;
use syn::spanned::Spanned;
use proc_macro::TokenStream;
#[proc_macro_derive(BreadCrumbs, attributes(breadcrumb, breadcrumbs))]
pub fn derive_breadcrumbs(input: TokenStream) -> TokenStream {
let derive_input = parse_macro_input!(input as syn::DeriveInput);
let crate_path = quote!{::yew_route_breadcrumbs};
let ident = &derive_input.ident;
let implementation = match &derive_input.data {
syn::Data::Enum(enu) => enu::handle_enum(&derive_input.attrs, enu, &derive_input),
syn::Data::Struct(_) => {
let breadcrumbs = attr::get_attribute_crumbs(&derive_input.attrs);
if breadcrumbs.is_empty() {
quote! {None}
} else {
quote! { Some(vec![#(#breadcrumbs),*]) }
}
}
_ => {
derive_input.span()
.unwrap()
.error("BreadCrumbs can only be applied to enums and structs")
.emit();
quote! {}
}
};
let output = quote! {
impl #crate_path::BreadCrumbs for #ident {
fn breadcrumbs(&self) -> Option<Vec<#crate_path::StaticCrumb>> {
#implementation
}
}
impl #ident {
pub fn breadcrumbs(&self) -> Option<Vec<#crate_path::StaticCrumb>> {
#crate_path::BreadCrumbs::breadcrumbs(self)
}
}
};
output.into()
}