1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use crate try_bot_main;
use crate try_derive_builder;
use crate try_command;
use crate try_commands;
use crate;
use crate try_derive_file_holder;
use crate;
use TokenStream;
use proc_macro_error;
/// 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
/// 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])
/// }
/// ```
/// 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
/// Return a map of commands to be used by `BotBuilder::commands`
/// 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
/// Returns the handler for the given function
/// 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);
/// }
/// ```
/// Returns the daemons associated to the given functions