Add BotBuilder

This commit is contained in:
Temirkhan Myrzamadi 2020-02-13 20:12:24 +06:00
parent 315e9ab80c
commit 7a7254b8a1
7 changed files with 90 additions and 54 deletions

View file

@ -14,6 +14,7 @@ tokio-util = { version = "0.2.0", features = ["full"] }
reqwest = { version = "0.10", features = ["json", "stream", "native-tls-vendored"] } reqwest = { version = "0.10", features = ["json", "stream", "native-tls-vendored"] }
log = "0.4.8" log = "0.4.8"
pretty_env_logger = "0.4.0"
bytes = "0.5.3" bytes = "0.5.3"
mime = "0.3.16" mime = "0.3.16"

View file

@ -177,12 +177,9 @@ async fn main() {
} }
async fn run() { async fn run() {
std::env::set_var("RUST_LOG", "info"); let bot = Bot::from_env().enable_logging(crate_name!()).build();
pretty_env_logger::init();
log::info!("Starting dialogue_bot!"); log::info!("Starting dialogue_bot!");
let bot = Bot::from_env();
Dispatcher::new(bot) Dispatcher::new(bot)
.message_handler(&DialogueDispatcher::new(|ctx| async move { .message_handler(&DialogueDispatcher::new(|ctx| async move {
handle_message(ctx) handle_message(ctx)

View file

@ -6,13 +6,9 @@ async fn main() {
} }
async fn run() { async fn run() {
// Configure the fancy logger. let bot = Bot::from_env().enable_logging(crate_name!()).build();
std::env::set_var("RUST_LOG", "info");
pretty_env_logger::init();
log::info!("Starting multiple_handlers_bot!"); log::info!("Starting multiple_handlers_bot!");
let bot = Bot::from_env();
// Create a dispatcher with multiple handlers of different types. This will // Create a dispatcher with multiple handlers of different types. This will
// print One! and Two! on every incoming UpdateKind::Message. // print One! and Two! on every incoming UpdateKind::Message.
Dispatcher::<RequestError>::new(bot) Dispatcher::<RequestError>::new(bot)

View file

@ -6,13 +6,9 @@ async fn main() {
} }
async fn run() { async fn run() {
// Configure the fancy logger. let bot = Bot::from_env().enable_logging(crate_name!()).build();
std::env::set_var("RUST_LOG", "info");
pretty_env_logger::init();
log::info!("Starting ping_pong_bot!"); log::info!("Starting ping_pong_bot!");
let bot = Bot::from_env();
// Create a dispatcher with a single message handler that answers "pong" to // Create a dispatcher with a single message handler that answers "pong" to
// each incoming message. // each incoming message.
Dispatcher::<RequestError>::new(bot) Dispatcher::<RequestError>::new(bot)

View file

@ -1,3 +1,5 @@
use log::LevelFilter;
use pretty_env_logger::env_logger::WriteStyle;
use reqwest::Client; use reqwest::Client;
use std::sync::Arc; use std::sync::Arc;
@ -12,57 +14,92 @@ pub struct Bot {
} }
impl Bot { impl Bot {
/// Creates a new `Bot` with the `TELOXIDE_TOKEN` environmental variable (a /// Returns [`BotBuilder`] from the `TELOXIDE_TOKEN` environmental variable
/// bot's token) and the default [`reqwest::Client`]. /// (a bot's token).
/// ///
/// # Panics /// # Panics
/// If cannot get the `TELOXIDE_TOKEN` environmental variable. /// If cannot get the `TELOXIDE_TOKEN` environmental variable.
/// ///
/// [`reqwest::Client`]: https://docs.rs/reqwest/0.10.1/reqwest/struct.Client.html /// [`BotBuilder`]: crate::BotBuilder
pub fn from_env() -> Arc<Self> { pub fn from_env() -> BotBuilder {
Self::new( BotBuilder {
std::env::var("TELOXIDE_TOKEN") token: std::env::var("TELOXIDE_TOKEN")
.expect("Cannot get the TELOXIDE_TOKEN env variable"), .expect("Cannot get the TELOXIDE_TOKEN env variable"),
) client: None,
}
} }
/// Creates a new `Bot` with the `TELOXIDE_TOKEN` environmental variable (a /// Returns [`BotBuilder`] with the specified token.
/// bot's token) and your [`reqwest::Client`].
/// ///
/// # Panics /// [`BotBuilder`]: crate::BotBuilder
/// If cannot get the `TELOXIDE_TOKEN` environmental variable. pub fn new<S>(token: S) -> BotBuilder
///
/// [`reqwest::Client`]: https://docs.rs/reqwest/0.10.1/reqwest/struct.Client.html
pub fn from_env_with_client(client: Client) -> Arc<Self> {
Self::with_client(
std::env::var("TELOXIDE_TOKEN")
.expect("Cannot get the TELOXIDE_TOKEN env variable"),
client,
)
}
/// Creates a new `Bot` with the specified token and the default
/// [`reqwest::Client`].
///
/// [`reqwest::Client`]: https://docs.rs/reqwest/0.10.1/reqwest/struct.Client.html
pub fn new<S>(token: S) -> Arc<Self>
where where
S: Into<String>, S: Into<String>,
{ {
Self::with_client(token, Client::new()) BotBuilder {
}
/// Creates a new `Bot` with the specified token and your
/// [`reqwest::Client`].
///
/// [`reqwest::Client`]: https://docs.rs/reqwest/0.10.1/reqwest/struct.Client.html
pub fn with_client<S>(token: S, client: Client) -> Arc<Self>
where
S: Into<String>,
{
Arc::new(Bot {
token: token.into(), token: token.into(),
client, client: None,
}
}
}
/// Used to build [`Bot`].
///
/// [`Bot`]: crate::Bot
pub struct BotBuilder {
token: String,
client: Option<Client>,
}
impl BotBuilder {
/// Sets your custom [`reqwest::Client`] (teloxide will make all requests
/// using it).
///
/// [`reqwest::Client`]: https://docs.rs/reqwest/0.10.1/reqwest/struct.Client.html
pub fn client(mut self, client: Client) -> Self {
self.client = Some(client);
self
}
/// Enables logging through [pretty-env-logger].
///
/// A logger will **only** print errors from teloxide and **all** logs from
/// your program.
///
/// [pretty-env-logger]: https://crates.io/crates/pretty_env_logger
pub fn enable_logging(self, crate_name: &'static str) -> Self {
Self::enable_logging_with_filter(self, crate_name, LevelFilter::Trace)
}
/// Enables logging through [pretty-env-logger].
///
/// A logger will **only** print errors from teloxide and restrict logs from
/// your program by the specified filter.
///
/// [pretty-env-logger]: https://crates.io/crates/pretty_env_logger
pub fn enable_logging_with_filter(
self,
crate_name: &'static str,
filter: LevelFilter,
) -> Self {
pretty_env_logger::formatted_builder()
.write_style(WriteStyle::Auto)
.filter(Some(crate_name), filter)
.filter(Some("teloxide"), LevelFilter::Error)
.init();
self
}
/// Builds [`Bot`].
///
/// Sets the default [`request::Client`] if you haven't specified yours.
///
/// [`request::Client`]: https://docs.rs/reqwest/0.10.1/reqwest/struct.Client.html
/// [`Bot`]: crate::Bot
pub fn build(self) -> Arc<Bot> {
Arc::new(Bot {
token: self.token,
client: self.client.unwrap_or(Client::new()),
}) })
} }
} }

View file

@ -4,7 +4,7 @@
)] )]
#![allow(clippy::match_bool)] #![allow(clippy::match_bool)]
pub use bot::Bot; pub use bot::{Bot, BotBuilder};
pub use errors::{ApiErrorKind, DownloadError, RequestError}; pub use errors::{ApiErrorKind, DownloadError, RequestError};
mod errors; mod errors;
@ -18,3 +18,11 @@ pub mod types;
pub mod utils; pub mod utils;
extern crate teloxide_macros; extern crate teloxide_macros;
/// Expands to a name of your crate.
#[macro_export]
macro_rules! crate_name {
() => {
env!("CARGO_PKG_NAME")
};
}

View file

@ -1,6 +1,7 @@
//! Commonly used items. //! Commonly used items.
pub use crate::{ pub use crate::{
crate_name,
dispatching::{ dispatching::{
dialogue::{ dialogue::{
exit, next, DialogueDispatcher, DialogueHandlerCtx, DialogueStage, exit, next, DialogueDispatcher, DialogueHandlerCtx, DialogueStage,