rust_tg_bot_macros/lib.rs
1//! Procedural macros for the `rust-tg-bot` Telegram Bot framework.
2//!
3//! This crate provides the [`BotCommands`] derive macro, which turns an enum
4//! into a self-parsing command handler with automatic help-text generation and
5//! Telegram `setMyCommands` integration.
6//!
7//! # Example
8//!
9//! ```rust,ignore
10//! use rust_tg_bot_macros::BotCommands;
11//!
12//! #[derive(BotCommands, Clone)]
13//! #[command(rename_rule = "lowercase")]
14//! enum Command {
15//! #[command(description = "Display help text")]
16//! Help,
17//! #[command(description = "Start the bot")]
18//! Start,
19//! #[command(description = "Set username")]
20//! Username(String),
21//! #[command(description = "Set age")]
22//! Age(u32),
23//! }
24//! ```
25
26extern crate proc_macro;
27
28mod bot_commands;
29mod command;
30mod command_attr;
31mod command_enum;
32mod error;
33mod fields_parse;
34mod rename_rules;
35
36pub(crate) use error::{compile_error, Result};
37use proc_macro::TokenStream;
38use syn::{parse_macro_input, DeriveInput};
39
40use crate::bot_commands::bot_commands_impl;
41
42/// Derive macro that generates command-parsing infrastructure for a Telegram bot.
43///
44/// Annotate an enum with `#[derive(BotCommands)]` to automatically generate:
45///
46/// - `parse(text, bot_name) -> Result<Self, ParseError>` -- parse incoming message text
47/// - `descriptions() -> String` -- formatted help text for all commands
48/// - `bot_commands() -> Vec<BotCommand>` -- suitable for the `setMyCommands` API call
49///
50/// # Enum-level attributes
51///
52/// | Attribute | Default | Description |
53/// |-----------|---------|-------------|
54/// | `rename_rule` | `"identity"` | How variant names map to command strings |
55/// | `prefix` | `"/"` | Command prefix character(s) |
56/// | `description` | none | Global description header for help text |
57/// | `command_separator` | `" "` | Separator between the command and its arguments |
58///
59/// # Variant-level attributes
60///
61/// | Attribute | Description |
62/// |-----------|-------------|
63/// | `description` | Help text for this command |
64/// | `rename` | Override the command string for this variant |
65/// | `parse_with` | `"default"`, `"split"`, or a custom `fn(String) -> Result<T, E>` |
66/// | `separator` | Argument separator when using `parse_with = "split"` |
67/// | `hide` | Exclude from help text and `bot_commands()` |
68#[proc_macro_derive(BotCommands, attributes(command))]
69pub fn bot_commands_derive(tokens: TokenStream) -> TokenStream {
70 let input = parse_macro_input!(tokens as DeriveInput);
71 bot_commands_impl(input).unwrap_or_else(<_>::into).into()
72}