From b335a661962598e31300d9245000c0ff3478b852 Mon Sep 17 00:00:00 2001 From: Liu Xiaoyi Date: Sat, 12 Nov 2022 21:55:44 +0800 Subject: [PATCH] Make hyper and tokio optional dependencies --- lib/Cargo.toml | 8 +++++--- lib/src/api.rs | 15 ++++++++++++--- lib/src/connector/mod.rs | 2 ++ lib/src/errors.rs | 20 +++++++++++++++++++- lib/src/lib.rs | 1 + lib/src/stream.rs | 21 +++++++++++++++++++++ 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/lib/Cargo.toml b/lib/Cargo.toml index eef84bb9ef..b6f6b0fd7a 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -17,10 +17,11 @@ license = "MIT" [features] openssl = ["hyper-tls"] rustls = ["hyper-rustls"] -default = ["openssl"] +runtime-tokio = ["tokio"] +connector-hyper = ["hyper", "runtime-tokio"] +default = ["openssl", "connector-hyper"] [dependencies] bytes = "1.0.1" -tokio = { version = "1.2", features = ["fs", "rt"]} tracing = "0.1.23" tracing-futures = "0.2" @@ -28,7 +29,8 @@ multipart = { version = "0.17", default-features = false, features = ["client"] telegram-bot-raw = { version = "0.9.0", path = "../raw" } -hyper = { version = "0.14", features = ["client", "http1"] } +tokio = { version = "1.2", features = ["fs", "rt"], optional = true } +hyper = { version = "0.14", features = ["client", "http1"], optional = true } hyper-tls = { version = "0.5", optional = true } futures = "0.3" hyper-rustls = { version = "0.22", optional = true } diff --git a/lib/src/api.rs b/lib/src/api.rs index 07c2207664..384d2278a3 100644 --- a/lib/src/api.rs +++ b/lib/src/api.rs @@ -2,18 +2,24 @@ use std::sync::{ atomic::{AtomicUsize, Ordering}, Arc, }; -use std::time::Duration; use futures::{Future, FutureExt}; -use tokio::time::timeout; + use tracing_futures::Instrument; use telegram_bot_raw::{HttpRequest, Request, ResponseType}; -use crate::connector::{default_connector, Connector}; +use crate::connector::Connector; use crate::errors::{Error, ErrorKind}; use crate::stream::UpdatesStream; +#[cfg(feature = "runtime-tokio")] +use tokio::time::timeout; +#[cfg(feature = "runtime-tokio")] +use std::time::Duration; +#[cfg(feature = "connector-hyper")] +use crate::connector::default_connector; + /// Main type for sending requests to the Telegram bot API. #[derive(Clone)] pub struct Api(Arc); @@ -39,6 +45,7 @@ impl Api { /// let api = Api::new(telegram_token); /// # } /// ``` + #[cfg(feature = "connector-hyper")] pub fn new>(token: T) -> Self { Self::with_connector(token, default_connector()) } @@ -91,6 +98,7 @@ impl Api { /// # } /// # } /// ``` + #[cfg(feature = "runtime-tokio")] pub fn spawn(&self, request: Req) { let api = self.clone(); if let Ok(request) = request.serialize() { @@ -119,6 +127,7 @@ impl Api { /// # } /// # } /// ``` + #[cfg(feature = "runtime-tokio")] pub fn send_timeout( &self, request: Req, diff --git a/lib/src/connector/mod.rs b/lib/src/connector/mod.rs index 84bb037184..e0ce4de2a3 100644 --- a/lib/src/connector/mod.rs +++ b/lib/src/connector/mod.rs @@ -1,5 +1,6 @@ //! Connector with hyper backend. +#[cfg(feature = "connector-hyper")] pub mod hyper; use std::fmt::Debug; @@ -18,6 +19,7 @@ pub trait Connector: Debug + Send + Sync { ) -> Pin> + Send>>; } +#[cfg(feature = "hyper")] pub fn default_connector() -> Box { hyper::default_connector().unwrap() } diff --git a/lib/src/errors.rs b/lib/src/errors.rs index 8ee859264e..af97331df6 100644 --- a/lib/src/errors.rs +++ b/lib/src/errors.rs @@ -5,12 +5,25 @@ use std::fmt; pub struct Error(ErrorKind); #[derive(Debug)] -pub(crate) enum ErrorKind { +pub enum ErrorKind { Raw(telegram_bot_raw::Error), + #[cfg(feature = "connector-hyper")] Hyper(hyper::Error), + #[cfg(feature = "connector-hyper")] Http(hyper::http::Error), Io(std::io::Error), InvalidMultipartFilename, + Generic(Box), +} + +impl ErrorKind { + pub fn from_generic(e: E) -> Self { + Self::Generic(Box::new(e)) + } + + pub fn from_generic_boxed(e: Box) -> Self { + Self::Generic(e) + } } impl From for ErrorKind { @@ -19,12 +32,14 @@ impl From for ErrorKind { } } +#[cfg(feature = "connector-hyper")] impl From for ErrorKind { fn from(error: hyper::Error) -> Self { ErrorKind::Hyper(error) } } +#[cfg(feature = "connector-hyper")] impl From for ErrorKind { fn from(error: hyper::http::Error) -> Self { ErrorKind::Http(error) @@ -47,10 +62,13 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.0 { ErrorKind::Raw(error) => write!(f, "{}", error), + #[cfg(feature = "connector-hyper")] ErrorKind::Hyper(error) => write!(f, "{}", error), + #[cfg(feature = "connector-hyper")] ErrorKind::Http(error) => write!(f, "{}", error), ErrorKind::Io(error) => write!(f, "{}", error), ErrorKind::InvalidMultipartFilename => write!(f, "invalid multipart filename"), + ErrorKind::Generic(error) => write!(f, "{}", error), } } } diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 615fa97439..e34543e90b 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -13,6 +13,7 @@ pub mod util; pub use self::api::Api; pub use self::errors::Error; +pub use self::errors::ErrorKind; pub use prelude::*; pub use stream::UpdatesStream; pub use types::*; diff --git a/lib/src/stream.rs b/lib/src/stream.rs index e3ab709609..eb5b9edb48 100644 --- a/lib/src/stream.rs +++ b/lib/src/stream.rs @@ -101,7 +101,18 @@ impl Stream for UpdatesStream { .allowed_updates(&ref_mut.allowed_updates); tracing::trace!(request = ?get_updates, timeout=?timeout, "preparing new request"); + #[cfg(feature = "runtime-tokio")] let request = ref_mut.api.send_timeout(get_updates, timeout); + + #[cfg(not(feature = "runtime-tokio"))] + let request = { + let api = ref_mut.api.clone(); + async move { + let req = api.clone().send(get_updates).await; + Some(req).transpose() + } + }; + ref_mut.current_request = Some(Box::pin(request)); return Poll::Ready(Some(Err(err))); } @@ -115,7 +126,17 @@ impl Stream for UpdatesStream { .allowed_updates(&ref_mut.allowed_updates); tracing::trace!(request = ?get_updates, timeout=?timeout, "preparing new request"); + #[cfg(feature = "runtime-tokio")] let request = ref_mut.api.send_timeout(get_updates, timeout); + + #[cfg(not(feature = "runtime-tokio"))] + let request = { + let api = ref_mut.api.clone(); + async move { + let req = api.send(get_updates).await; + Some(req).transpose() + } + }; ref_mut.current_request = Some(Box::pin(request)); tracing::trace!("executing recursive call");