rust_tg_bot/lib.rs
1//! # rust-tg-bot
2//!
3//! Complete, asynchronous Telegram Bot API framework for Rust, faithfully ported
4//! from [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot).
5//!
6//! This is the facade crate that re-exports everything from:
7//! - [`rust_tg_bot_raw`](raw) — Bot API types and methods
8//! - [`rust_tg_bot_ext`](ext) — Application framework (handlers, filters, persistence)
9//!
10//! ## Quick Start
11//!
12//! ```toml
13//! [dependencies]
14//! rust-tg-bot = "1.0"
15//! ```
16//!
17//! ```rust,ignore
18//! use rust_tg_bot::ext::prelude::*;
19//!
20//! #[tokio::main]
21//! async fn main() {
22//! let app = ApplicationBuilder::new()
23//! .token(std::env::var("TELEGRAM_BOT_TOKEN").unwrap())
24//! .build();
25//! app.add_handler(CommandHandler::new("start", start), 0).await;
26//! app.run_polling().await.unwrap();
27//! }
28//! ```
29//!
30//! See the [README](https://github.com/HexiCoreDev/rust-telegram-bot) and
31//! [guide](https://rust-tg-bot-docs.vercel.app/) for full documentation.
32#![forbid(unsafe_code)]
33
34// Re-export everything from both crates for convenience
35pub use rust_tg_bot_raw as raw;
36pub use rust_tg_bot_raw::bot::Bot;
37pub use rust_tg_bot_raw::error;
38pub use rust_tg_bot_raw::types;
39
40pub use rust_tg_bot_ext as ext;
41pub use rust_tg_bot_ext::prelude;
42
43// Re-export the derive macro when the `macros` feature is enabled.
44#[cfg(feature = "macros")]
45pub use rust_tg_bot_macros::BotCommands;
46
47/// Runtime configuration for [`run`].
48pub struct RuntimeConfig {
49 /// Number of tokio worker threads. `None` = system default (CPU core count).
50 pub worker_threads: Option<usize>,
51 /// Stack size per worker thread in bytes. Default: 8 MB.
52 pub thread_stack_size: usize,
53}
54
55impl Default for RuntimeConfig {
56 fn default() -> Self {
57 Self {
58 worker_threads: None,
59 thread_stack_size: 8 * 1024 * 1024,
60 }
61 }
62}
63
64impl RuntimeConfig {
65 /// Set the number of worker threads.
66 pub fn workers(mut self, n: usize) -> Self {
67 self.worker_threads = Some(n);
68 self
69 }
70 /// Set the stack size per worker thread in bytes.
71 pub fn stack_size(mut self, bytes: usize) -> Self {
72 self.thread_stack_size = bytes;
73 self
74 }
75}
76
77/// Run an async entry point with a tokio runtime configured for Telegram bot workloads.
78///
79/// Uses sensible defaults: all CPU cores as worker threads, 8 MB stack per thread
80/// (needed for the deeply nested async state machines in Bot API calls).
81///
82/// # Basic usage
83///
84/// ```rust,ignore
85/// fn main() {
86/// rust_tg_bot::run(async {
87/// let app = ApplicationBuilder::new().token(token).build();
88/// app.run_polling().await.unwrap();
89/// });
90/// }
91/// ```
92///
93/// # Custom configuration
94///
95/// ```rust,ignore
96/// fn main() {
97/// rust_tg_bot::run_configured(
98/// RuntimeConfig::default().workers(4),
99/// async { /* ... */ },
100/// );
101/// }
102/// ```
103#[deprecated(since = "1.0.0-beta.2", note = "Use #[tokio::main] directly instead")]
104pub fn run<F: std::future::Future<Output = ()> + Send>(future: F) {
105 run_configured(RuntimeConfig::default(), future);
106}
107
108/// Like [`run`], but with explicit [`RuntimeConfig`].
109pub fn run_configured<F: std::future::Future<Output = ()> + Send>(
110 config: RuntimeConfig,
111 future: F,
112) {
113 let mut builder = tokio::runtime::Builder::new_multi_thread();
114 builder
115 .thread_stack_size(config.thread_stack_size)
116 .enable_all();
117 if let Some(n) = config.worker_threads {
118 builder.worker_threads(n);
119 }
120 builder
121 .build()
122 .expect("failed to build tokio runtime")
123 .block_on(future);
124}