telegram-bot2-macros 0.1.3

telegram-bot2-macros contains all macros used by the telegram-bot2 crate
Documentation
use crate::bot_main::try_bot_main;
use crate::builder::try_derive_builder;
use crate::command::try_command;
use crate::command::try_commands;
use crate::daemon::{try_daemon, try_daemons};
use crate::file_holder::try_derive_file_holder;
use crate::handler::{try_handler, try_handlers};
use proc_macro::TokenStream;
use proc_macro_error::proc_macro_error;

mod bot_main;
mod builder;
mod command;
mod constants;
mod daemon;
mod file_holder;
mod handler;

/// Creates a builder for the structure.
/// It will have the following properties:
/// - A new() function, with parameters for each non-optional field of the structure
/// - A method for each optional parameter to initialize that field. It returns self to allow chained calls
#[proc_macro_derive(Builder)]
#[proc_macro_error]
pub fn derive_buildable(item: TokenStream) -> TokenStream {
    try_derive_builder(item).unwrap()
}

/// Builds a main around the function.
/// It should return a BotBuilder, which will be launched by the main.
///
/// The return type of the function does not have to be specified and can be `_`
///
/// ## Example
/// ```
/// #[bot]
/// async fn bot() -> _ {
///     BotBuilder::new()
///         .interval(Duration::from_secs(0))
///         .timeout(5)
///         .handler(handlers![handler])
///         .commands(commands![soup])
/// }
/// ```
#[proc_macro_attribute]
#[proc_macro_error]
pub fn bot(attr: TokenStream, item: TokenStream) -> TokenStream {
    try_bot_main(attr, item).unwrap()
}

/// Define a command handler
///
/// It requires a single parameter, a string literal for the syntax of the command. It should have the following format: `"/command [static|<dynamic>]"`
///
/// ## Static parameters
/// Static parameters must be exact matches, at the specified position
///
/// ## Dynamic parameters
/// Dynamic parameters are surrounded by angle brackets in the syntax. They are parsed from the command message and passed to the handler.
///
/// The handler function must have parameters with the same names. They are parsed using the [FromStr](std::str::FromStr) trait.
///
/// The Option and Vec types have specific behaviors:\
/// They must appear in the following order in the syntax : Neither => Option => Vec (once)\
/// When all classic parameters are parsed, if they are remaining arguments in the command call, they are parsed regarding the contained type of the options/vec (in order)
///
/// ## Example
/// ```
/// #[bot_command("/soup <id>")]
/// async fn soup(bot: &Bot, chat: ChatId, id: i64) -> Result<(), ()> {
///     bot.send_message(SendMessageBuilder::new(chat, format!("Soup {} requested", id)).build()).await.unwrap();
///     Ok(())
/// }
/// ```
///
/// ### Option
/// Given the following handler:
/// ```
/// #[bot_command("/soup <id> <name>")]
/// async fn soup(bot: &Bot, chat: ChatId, id: Option<i64>, name: Option<String>) -> Result<(), ()> {
///     bot.send_message(SendMessageBuilder::new(chat, format!("Soup {}@{} requested", name.unwrap_or("None".to_string()), id.unwrap_or(0))).build()).await.unwrap();
///     Ok(())
/// }
/// ```
/// Issuing the command `/soup 10 roulottes` will result in the message `"Soup roulottes@10 requested"`, while `"/soup 10"` will yield `"Soup None@10 requested"`. `"/soup roulottes"` won't be parsed successfully
#[proc_macro_attribute]
#[proc_macro_error]
pub fn command(attr: TokenStream, item: TokenStream) -> TokenStream {
    try_command(attr, item).unwrap()
}

/// Return a map of commands to be used by `BotBuilder::commands`
#[proc_macro]
#[proc_macro_error]
pub fn commands(item: TokenStream) -> TokenStream {
    try_commands(item).unwrap()
}

#[proc_macro_derive(FileHolder)]
#[proc_macro_error]
pub fn derive_file_holder(item: TokenStream) -> TokenStream {
    try_derive_file_holder(item).unwrap()
}
/// Creates a generic update handler for the function
///
/// All parameters must implement the FromUpdate trait
///
/// The macro may take those parameters:
/// - `rank`(usize):  the priority of this handler, 0 being the lowest
/// - `restrict` (list of `UpdateType`): the updates that may be passed to the handler
#[proc_macro_attribute]
#[proc_macro_error]
pub fn handler(attr: TokenStream, item: TokenStream) -> TokenStream {
    try_handler(attr, item).unwrap()
}

/// Returns the handler for the given function
#[proc_macro]
#[proc_macro_error]
pub fn handlers(item: TokenStream) -> TokenStream {
    try_handlers(item).unwrap()
}

/// You can setup daemons that run in the background and have access to the BotState. Daemon function are annotated with [`#[daemon]`][macro@crate::daemon] and require a `interval` parameter, which specifies the time between two calls (in seconds).
///
/// The interval time is the time between calls, it does not starts at the end of the last call. For example, if the interval is set to 60s and the daemon takes 5s to complete, the next call will proceeds 55s after the first one ends.\
/// The timer is precise at a millisecond order. If no interval is specified, the daemon is ran once at the start of the bot (useful for dynamically scheduled tasks).
///
/// The parameters of the function are parsed by the `FromDaemon` trait, at each call
/// ```rust
/// #[daemon(interval = 5)]
/// async fn hello(state: &BotState<Mutex<usize>>) {
///     let mut lock = state.lock().unwrap();
///     *lock += 1;
///     println!("Increasing counter to {}", lock);
/// }
/// ```
#[proc_macro_attribute]
#[proc_macro_error]
pub fn daemon(attr: TokenStream, item: TokenStream) -> TokenStream {
    try_daemon(attr, item).unwrap()
}

/// Returns the daemons associated to the given functions
#[proc_macro]
#[proc_macro_error]
pub fn daemons(item: TokenStream) -> TokenStream {
    try_daemons(item).unwrap()
}