#![doc = include_str!("../README.md")]

#![allow(unused_imports)]

#[cfg(feature = "cli")]
mod cli;

#[cfg(feature = "package")]
mod package;

#[cfg(feature = "target")]
mod target;


mod util;



use proc_macro::TokenStream;
use quote::quote;
use syn::parse_macro_input;


/// Easily allow a function to be used as a CLI subcommand.
///
/// ```
///# use cicero_macro as cicero;
///
/// #[cicero::cli]
/// fn add_one(value: usize) -> usize {
///     value + 1
/// }
///
/// assert_eq!(add_one(7), 8); //can still call as a regular function
///
/// let add_one_task = add_one { value: 41 }; //will be constructed by `clap`
/// assert_eq!(add_one_task.run(), 42);
/// ```
///
/// To use this macro, add this dependency to your `Cargo.toml`:
/// ```toml
/// clap = { version = "4", features = ["derive"] }
/// ```
///
/// Attributes added to the function and its parameters will instead be added to the struct and its fields,
/// allowing `clap` attributes to be used.
#[cfg(feature = "cli")]
#[proc_macro_attribute]
pub fn cli(_args: TokenStream, input: TokenStream) -> TokenStream {

    let function = parse_macro_input!(input as syn::ItemFn);

    let expanded = cli::cli_macro_implementation(function)
        .unwrap_or_else(|cause| cause.to_compile_error());

    TokenStream::from(expanded)
}



#[cfg(feature = "package")]
#[allow(missing_docs)] //documented on re-export in `cicero` crate
#[proc_macro]
pub fn package(_args: TokenStream) -> TokenStream {

    let expanded = package::package_macro_implementation();

    TokenStream::from(expanded)
}


/// Templates module with values for each target platform supported by the Rust compiler.
#[cfg(feature = "target")]
#[allow(non_snake_case)]
#[proc_macro]
pub fn target(_args: TokenStream) -> TokenStream {

    let expanded = target::target_macro_implementation();

    TokenStream::from(expanded)
}
