From 234a0e4607a13568c2a6f267e706ad7b47a69318 Mon Sep 17 00:00:00 2001 From: Temirkhan Myrzamadi Date: Fri, 6 Mar 2020 15:05:44 +0600 Subject: [PATCH] Remove the high-level overview from lib.rs --- src/lib.rs | 299 +---------------------------------------------------- 1 file changed, 1 insertion(+), 298 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a0b2e00a..65d62808 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,308 +2,11 @@ //! using the [`async`/`.await`] syntax in [Rust]. It handles all the difficult //! stuff so you can focus only on your business logic. //! -//! See also [our GitHub repository](https://github.com/teloxide/teloxide). -//! -//! # Getting started -//! 1. Create a new bot using [@Botfather] to get a token in the format -//! `123456789:blablabla`. -//! 2. Initialise the `TELOXIDE_TOKEN` environmental -//! variable to your token: -//! ```text -//! # Unix -//! $ export TELOXIDE_TOKEN= -//! -//! # Windows -//! $ set TELOXIDE_TOKEN= -//! ``` -//! -//! 3. Be sure that you are up to date: -//! ```bash -//! # If you're using stable -//! $ rustup update stable -//! $ rustup override set stable -//! -//! # If you're using nightly -//! $ rustup update nightly -//! $ rustup override set nightly -//! ``` -//! -//! 4. Execute `cargo new my_bot`, enter the directory and put these lines into -//! your `Cargo.toml`: -//! ```text -//! [dependencies] -//! teloxide = "0.2.0" -//! log = "0.4.8" -//! tokio = "0.2.11" -//! pretty_env_logger = "0.4.0" -//! ``` -//! -//! # The ping-pong bot -//! This bot has a single message handler, which answers "pong" to each incoming -//! message: -//! -//! ([Full](https://github.com/teloxide/teloxide/blob/master/examples/ping_pong_bot/src/main.rs)) -//! ```no_run -//! use teloxide::prelude::*; -//! -//! #[tokio::main] -//! async fn main() { -//! teloxide::enable_logging!(); -//! log::info!("Starting ping_pong_bot!"); -//! -//! let bot = Bot::from_env(); -//! -//! Dispatcher::new(bot) -//! .messages_handler(|rx: DispatcherHandlerRx| { -//! rx.for_each(|message| async move { -//! message.answer("pong").send().await.log_on_error().await; -//! }) -//! }) -//! .dispatch() -//! .await; -//! } -//! ``` -//! -//!
-//! -//! -//! -//!
-//! -//! # Commands -//! Commands are defined similar to how we define CLI using [structopt]. This -//! bot says "I am a cat! Meow!" on `/meow`, generates a random number within -//! [0; 1) on `/generate`, and shows the usage guide on `/help`: -//! -//! ([Full](https://github.com/teloxide/teloxide/blob/master/examples/simple_commands_bot/src/main.rs)) -//! ```no_run -//! // Imports are omitted... -//! # #[allow(unreachable_code)] -//! # use teloxide::{prelude::*, utils::command::BotCommand}; -//! # use rand::{thread_rng, Rng}; -//! -//! #[derive(BotCommand)] -//! #[command( -//! rename = "lowercase", -//! description = "These commands are supported:" -//! )] -//! enum Command { -//! #[command(description = "display this text.")] -//! Help, -//! #[command(description = "be a cat.")] -//! Meow, -//! #[command(description = "generate a random number within [0; 1).")] -//! Generate, -//! } -//! -//! fn generate() -> String { -//! thread_rng().gen_range(0.0, 1.0).to_string() -//! } -//! -//! async fn answer( -//! cx: DispatcherHandlerCx, -//! command: Command, -//! ) -> ResponseResult<()> { -//! match command { -//! Command::Help => cx.answer(Command::descriptions()).send().await?, -//! Command::Generate => cx.answer(generate()).send().await?, -//! Command::Meow => cx.answer("I am a cat! Meow!").send().await?, -//! }; -//! -//! Ok(()) -//! } -//! -//! async fn handle_commands(rx: DispatcherHandlerRx) { -//! // Only iterate through commands in a proper format: -//! rx.commands::(panic!("Insert here your bot's name")) -//! // Execute all incoming commands concurrently: -//! .for_each_concurrent(None, |(cx, command, _)| async move { -//! answer(cx, command).await.log_on_error().await; -//! }) -//! .await; -//! } -//! -//! #[tokio::main] -//! async fn main() { -//! // Setup is omitted... -//! # teloxide::enable_logging!(); -//! # log::info!("Starting simple_commands_bot!"); -//! # let bot = Bot::from_env(); -//! # Dispatcher::new(bot).messages_handler(handle_commands).dispatch().await; -//! } -//! ``` -//! -//!
-//! -//! -//! -//!

-//!
-//! -//! -//! See? The dispatcher gives us a stream of messages, so we can handle it as we -//! want! Here we use our `.commands::()` and -//! [`.for_each_concurrent()`], but others are also available: -//! - [`.flatten()`](https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.flatten) -//! - [`.left_stream()`](https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.left_stream) -//! - [`.scan()`](https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.scan) -//! - [`.skip_while()`](https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.skip_while) -//! - [`.zip()`](https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.zip) -//! - [`.select_next_some()`](https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.select_next_some) -//! - [`.fold()`](https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.fold) -//! - [`.inspect()`](https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.inspect) -//! - ... And lots of [others](https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html)! -//! -//! # Guess a number -//! Wanna see more? This is a bot, which starts a game on each incoming message. -//! You must guess a number from 1 to 10 (inclusively): -//! -//! ([Full](https://github.com/teloxide/teloxide/blob/master/examples/guess_a_number_bot/src/main.rs)) -//! ```no_run -//! // Setup is omitted... -//! # #[macro_use] -//! # extern crate smart_default; -//! # use teloxide::prelude::*; -//! # use rand::{thread_rng, Rng}; -//! -//! #[derive(SmartDefault)] -//! enum Dialogue { -//! #[default] -//! Start, -//! ReceiveAttempt(u8), -//! } -//! -//! async fn handle_message( -//! cx: DialogueDispatcherHandlerCx, -//! ) -> ResponseResult> { -//! match cx.dialogue { -//! Dialogue::Start => { -//! cx.answer( -//! "Let's play a game! Guess a number from 1 to 10 \ -//! (inclusively).", -//! ) -//! .send() -//! .await?; -//! next(Dialogue::ReceiveAttempt(thread_rng().gen_range(1, 11))) -//! } -//! Dialogue::ReceiveAttempt(secret) => match cx.update.text() { -//! None => { -//! cx.answer("Oh, please, send me a text message!") -//! .send() -//! .await?; -//! next(cx.dialogue) -//! } -//! Some(text) => match text.parse::() { -//! Ok(attempt) => match attempt { -//! x if !(1..=10).contains(&x) => { -//! cx.answer( -//! "Oh, please, send me a number in the range \ -//! [1; 10]!", -//! ) -//! .send() -//! .await?; -//! next(cx.dialogue) -//! } -//! x if x == secret => { -//! cx.answer("Congratulations! You won!") -//! .send() -//! .await?; -//! exit() -//! } -//! _ => { -//! cx.answer("No.").send().await?; -//! next(cx.dialogue) -//! } -//! }, -//! Err(_) => { -//! cx.answer( -//! "Oh, please, send me a number in the range [1; \ -//! 10]!", -//! ) -//! .send() -//! .await?; -//! next(cx.dialogue) -//! } -//! }, -//! }, -//! } -//! } -//! -//! #[tokio::main] -//! async fn main() { -//! // Setup is omitted... -//! # teloxide::enable_logging!(); -//! # log::info!("Starting guess_a_number_bot!"); -//! # let bot = Bot::from_env(); -//! # Dispatcher::new(bot) -//! # .messages_handler(DialogueDispatcher::new(|cx| async move { -//! # handle_message(cx).await.expect("Something wrong with the bot!") -//! # })) -//! # .dispatch() -//! # .await; -//! } -//! ``` -//! -//!
-//! -//! -//! -//!

-//!
-//! -//! Our [finite automaton], designating a user dialogue, cannot be in an invalid -//! state, and this is why it is called "type-safe". We could use `enum` + -//! `Option`s instead, but it will lead is to lots of unpleasure `.unwrap()`s. -//! -//! Remember that a classical [finite automaton] is defined by its initial -//! state, a list of its possible states and a transition function? We can think -//! that `Dialogue` is a finite automaton with a context type at each state -//! (`Dialogue::Start` has `()`, `Dialogue::ReceiveAttempt` has `u8`). -//! -//! See [examples/dialogue_bot] to see a bit more complicated bot with -//! dialogues. [See all examples](https://github.com/teloxide/teloxide/tree/master/examples). -//! -//! # Recommendations -//! -//! - Use this pattern: -//! -//! ```rust -//! #[tokio::main] -//! async fn main() { -//! run().await; -//! } -//! -//! async fn run() { -//! // Your logic here... -//! } -//! ``` -//! -//! Instead of this: -//! -//! ```rust -//! #[tokio::main] -//! async fn main() { -//! // Your logic here... -//! } -//! ``` -//! -//! The second one produces very strange compiler messages because of the -//! `#[tokio::main]` macro. However, the examples above use the second one for -//! brevity. +//! For a high-level overview, see [our GitHub repository](https://github.com/teloxide/teloxide). //! //! [Telegram bots]: https://telegram.org/blog/bot-revolution //! [`async`/`.await`]: https://rust-lang.github.io/async-book/01_getting_started/01_chapter.html //! [Rust]: https://www.rust-lang.org/ -//! [finite automaton]: https://en.wikipedia.org/wiki/Finite-state_machine -//! [examples/dialogue_bot]: https://github.com/teloxide/teloxide/blob/master/examples/dialogue_bot/src/main.rs -//! [structopt]: https://docs.rs/structopt/0.3.9/structopt/ -//! [@Botfather]: https://t.me/botfather -//! [streams]: https://docs.rs/futures/0.3.4/futures/stream/index.html -//! [all 30+ patterns]: https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html -//! [`.for_each_concurrent()`]: https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.for_each_concurrent -//! [See more examples]: https://github.com/teloxide/teloxide/tree/master/examples -//! [category theory]: https://en.wikipedia.org/wiki/Category_theory -//! [coproduct]: https://en.wikipedia.org/wiki/Coproduct // https://github.com/teloxide/teloxide/raw/master/logo.svg doesn't work in html_logo_url, I don't know why. #![doc(