1#![cfg_attr(not(doctest),doc = include_str!("../README.md"))]
2#![warn(missing_docs)]
3
4use proc_macro::TokenStream;
5use quote::quote;
6use syn::{parse_macro_input, ItemFn};
7
8use crate::app::AppGenerator;
9use crate::command::CommandGenerator;
10use crate::inventory::InventoryGenerator;
11
12mod app;
13mod command;
14mod inventory;
15
16#[proc_macro]
30pub fn app(_input: TokenStream) -> TokenStream {
31 let app_generator = AppGenerator::new();
32 app_generator.app_function().into()
33}
34
35#[proc_macro_attribute]
63pub fn command(attrs: TokenStream, input: TokenStream) -> TokenStream {
64 let input_function = parse_macro_input!(input as ItemFn);
65
66 let command_generator = CommandGenerator::new(attrs.into(), input_function.clone());
67 let inventory_generator = InventoryGenerator::new(&command_generator);
68
69 let inventory_struct_for_subcommands = inventory_generator.inventory();
70 let submit_command_to_inventory = inventory_generator.submit_command();
71
72 let initialization_function_for_command = command_generator.initialization_function();
73 let wrapper_function_for_command = command_generator.wrapper_function();
74
75 let output = quote! {
76 #inventory_struct_for_subcommands
77
78 #input_function
79
80 #initialization_function_for_command
81
82 #wrapper_function_for_command
83
84 #submit_command_to_inventory
85 };
86
87 output.into()
88}