icondata_macros/
lib.rs

1extern crate proc_macro;
2
3/// # Icon Macro
4/// This macro allows you to write `icon!(IconName)` instead of `Icon::from(Library::IconName)`.
5/// It is simply a quality of life improvement, and is not required to use this crate. It is
6/// enabled with the **`macros`** feature.
7///
8/// ### Example
9/// ```
10/// use icondata::{icon, Icon};
11/// 
12///
13/// let icon: Icon = icon!(AiFileImageTwotone);
14/// assert_eq!(icon, Icon::from(icondata::AiIcon::AiFileImageTwotone));
15/// // Instead of:
16/// // let icon: Icon = Icon::from(AiIcon::AiFileImageTwotone);
17/// ```
18#[proc_macro]
19pub fn icon(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
20    let mut input = input.into_iter();
21
22    let icon_ident = match input.next() {
23        Some(token) => match token {
24            proc_macro::TokenTree::Ident(i) => i,
25            _ => panic!("Expected an identifier, but received a different token type."),
26        },
27        None => panic!("Expected an identifier, but received an empty token stream."),
28    };
29    // Ensure that there are no more tokens in the token stream
30    if input.next().is_some() {
31        panic!("Expected only one identifier, but received multiple tokens.");
32    }
33    let icon_string = icon_ident.to_string();
34
35    let (lib_short_name, icon_name) = icon_string.split_at(2);
36    let lower_lib_short_name = lib_short_name.to_lowercase();
37
38    format!(
39        "icondata::Icon::from(icondata::{}Icon::{}{})",
40        lower_lib_short_name, lib_short_name, icon_name
41    )
42    .parse()
43    .unwrap()
44}