Conditionally add teloxide-macros crate and reexport macros

This commit adds the feature "macros" which conditionally adds the
teloxide-macros crate and reexports its macros.

All (doc) tests using these macros are also conditionally enabled now.
Also change examples accordingly.

This commit solves https://github.com/teloxide/teloxide/issues/283
This commit is contained in:
Jaslo Ziska 2020-10-02 11:13:27 +02:00
parent 0c6a81e1b6
commit eed1bbb0fc
No known key found for this signature in database
GPG key ID: 632575F1635E0D8B
7 changed files with 45 additions and 5 deletions

View file

@ -30,6 +30,8 @@ bincode-serializer = ["bincode"]
frunk- = ["frunk"]
macros = ["teloxide-macros"]
nightly = [] # currently used only for `README.md` tests
[dependencies]
@ -57,7 +59,7 @@ serde_cbor = { version = "0.11.1", optional = true }
bincode = { version = "1.3.1", optional = true }
frunk = { version = "0.3.1", optional = true }
teloxide-macros = { git = "https://github.com/teloxide/teloxide-macros", branch = "master" }
teloxide-macros = { git = "https://github.com/teloxide/teloxide-macros", branch = "master", optional = true }
[dev-dependencies]
smart-default = "0.6.0"

View file

@ -10,7 +10,7 @@ edition = "2018"
log = "0.4.8"
pretty_env_logger = "0.4.0"
tokio = { version = "0.2.11", features = ["rt-threaded", "macros"] }
teloxide = { path = "../../" }
teloxide = { path = "../../", features = ["macros"] }
[profile.release]
lto = true

View file

@ -10,4 +10,4 @@ edition = "2018"
log = "0.4.8"
pretty_env_logger = "0.4.0"
tokio = { version = "0.2.11", features = ["rt-threaded", "macros"] }
teloxide = { path = "../../" }
teloxide = { path = "../../", features = ["macros"] }

View file

@ -30,10 +30,10 @@
//! skeleton should look like:
//!
//! ```no_run
//! # #[cfg(feature = "macros")] {
//! use std::convert::Infallible;
//!
//! use teloxide::prelude::*;
//! use teloxide_macros::{teloxide, Transition};
//! use teloxide::{dispatching::dialogue::Transition, prelude::*, teloxide};
//!
//! struct _1State;
//! struct _2State;
@ -97,6 +97,7 @@
//! .dispatch()
//! .await;
//! }
//! # }
//! ```
//!
//! - `#[teloxide(subtransition)]` implements [`Subtransition`] for the first
@ -156,6 +157,10 @@ pub use transition::{
Subtransition, SubtransitionOutputType, Transition, TransitionIn, TransitionOut,
};
#[cfg(feature = "macros")]
#[cfg_attr(all(docsrs, feature = "nightly"), doc(cfg(feature = "macros")))]
pub use teloxide_macros::Transition;
#[cfg(feature = "redis-storage")]
pub use storage::{RedisStorage, RedisStorageError};

View file

@ -41,6 +41,7 @@
#![allow(clippy::match_bool)]
#![forbid(unsafe_code)]
#![cfg_attr(all(feature = "nightly", doctest), feature(external_doc))]
#![cfg_attr(all(docsrs, feature = "nightly"), feature(doc_cfg))]
pub use bot::{Bot, BotBuilder};
pub use dispatching::repls::{
@ -61,8 +62,13 @@ pub mod requests;
pub mod types;
pub mod utils;
#[cfg(feature = "macros")]
extern crate teloxide_macros;
#[cfg(feature = "macros")]
#[cfg_attr(all(docsrs, feature = "nightly"), doc(cfg(feature = "macros")))]
pub use teloxide_macros::teloxide;
#[cfg(all(feature = "nightly", doctest))]
#[doc(include = "../README.md")]
enum ReadmeDocTests {}

View file

@ -6,6 +6,7 @@
//!
//! # Using BotCommand
//! ```
//! # #[cfg(feature = "macros")] {
//! use teloxide::utils::command::BotCommand;
//!
//! type UnitOfTime = u8;
@ -19,6 +20,7 @@
//!
//! let command = AdminCommand::parse("/ban 5 h", "bot_name").unwrap();
//! assert_eq!(command, AdminCommand::Ban(5, 'h'));
//! # }
//! ```
//!
//! # Using parse_command
@ -46,12 +48,16 @@
use serde::export::Formatter;
use std::{error::Error, fmt::Display};
#[cfg(feature = "macros")]
#[cfg_attr(all(docsrs, feature = "nightly"), doc(cfg(feature = "macros")))]
pub use teloxide_macros::BotCommand;
/// An enumeration of bot's commands.
///
/// # Example
/// ```
/// # #[cfg(feature = "macros")] {
/// use teloxide::utils::command::BotCommand;
///
/// type UnitOfTime = u8;
@ -65,6 +71,7 @@ pub use teloxide_macros::BotCommand;
///
/// let command = AdminCommand::parse("/ban 5 h", "bot_name").unwrap();
/// assert_eq!(command, AdminCommand::Ban(5, 'h'));
/// # }
/// ```
///
/// ## Enum attributes
@ -86,6 +93,7 @@ pub use teloxide_macros::BotCommand;
///
/// ### Example
/// ```
/// # #[cfg(feature = "macros")] {
/// use teloxide::utils::command::BotCommand;
///
/// #[derive(BotCommand, PartialEq, Debug)]
@ -96,6 +104,7 @@ pub use teloxide_macros::BotCommand;
///
/// let command = Command::parse("/text hello my dear friend!", "").unwrap();
/// assert_eq!(command, Command::Text("hello my dear friend!".to_string()));
/// # }
/// ```
///
/// - `split` - separates a messsage by a given separator (the default is the
@ -104,6 +113,7 @@ pub use teloxide_macros::BotCommand;
///
/// ### Example
/// ```
/// # #[cfg(feature = "macros")] {
/// use teloxide::utils::command::BotCommand;
///
/// #[derive(BotCommand, PartialEq, Debug)]
@ -114,6 +124,7 @@ pub use teloxide_macros::BotCommand;
///
/// let command = Command::parse("/nums 1 32 -5", "").unwrap();
/// assert_eq!(command, Command::Nums(1, 32, -5));
/// # }
/// ```
///
/// 5. `#[command(separator = "sep")]`
@ -122,6 +133,7 @@ pub use teloxide_macros::BotCommand;
///
/// ### Example
/// ```
/// # #[cfg(feature = "macros")] {
/// use teloxide::utils::command::BotCommand;
///
/// #[derive(BotCommand, PartialEq, Debug)]
@ -132,6 +144,7 @@ pub use teloxide_macros::BotCommand;
///
/// let command = Command::parse("/nums 1|32|5", "").unwrap();
/// assert_eq!(command, Command::Nums(1, 32, 5));
/// # }
/// ```
///
/// ## Variant attributes
@ -149,6 +162,7 @@ pub use teloxide_macros::BotCommand;
///
/// ### Example
/// ```
/// # #[cfg(feature = "macros")] {
/// use teloxide::utils::command::{BotCommand, ParseError};
///
/// fn accept_two_digits(input: String) -> Result<(u8,), ParseError> {
@ -172,6 +186,7 @@ pub use teloxide_macros::BotCommand;
/// assert_eq!(command, Command::Num(12));
/// let command = Command::parse("/num 333", "");
/// assert!(command.is_err());
/// # }
/// ```
///
/// 3. `#[command(prefix = "prefix")]`

View file

@ -1,9 +1,11 @@
#[cfg(feature = "macros")]
use teloxide::utils::command::{BotCommand, ParseError};
// We put tests here because macro expand in unit tests in module
// teloxide::utils::command was a failure
#[test]
#[cfg(feature = "macros")]
fn parse_command_with_args() {
#[command(rename = "lowercase")]
#[derive(BotCommand, Debug, PartialEq)]
@ -19,6 +21,7 @@ fn parse_command_with_args() {
}
#[test]
#[cfg(feature = "macros")]
fn parse_command_with_non_string_arg() {
#[command(rename = "lowercase")]
#[derive(BotCommand, Debug, PartialEq)]
@ -34,6 +37,7 @@ fn parse_command_with_non_string_arg() {
}
#[test]
#[cfg(feature = "macros")]
fn attribute_prefix() {
#[command(rename = "lowercase")]
#[derive(BotCommand, Debug, PartialEq)]
@ -50,6 +54,7 @@ fn attribute_prefix() {
}
#[test]
#[cfg(feature = "macros")]
fn many_attributes() {
#[command(rename = "lowercase")]
#[derive(BotCommand, Debug, PartialEq)]
@ -64,6 +69,7 @@ fn many_attributes() {
}
#[test]
#[cfg(feature = "macros")]
fn global_attributes() {
#[command(prefix = "!", rename = "lowercase", description = "Bot commands")]
#[derive(BotCommand, Debug, PartialEq)]
@ -79,6 +85,7 @@ fn global_attributes() {
}
#[test]
#[cfg(feature = "macros")]
fn parse_command_with_bot_name() {
#[command(rename = "lowercase")]
#[derive(BotCommand, Debug, PartialEq)]
@ -95,6 +102,7 @@ fn parse_command_with_bot_name() {
}
#[test]
#[cfg(feature = "macros")]
fn parse_with_split() {
#[command(rename = "lowercase")]
#[command(parse_with = "split")]
@ -111,6 +119,7 @@ fn parse_with_split() {
}
#[test]
#[cfg(feature = "macros")]
fn parse_with_split2() {
#[command(rename = "lowercase")]
#[command(parse_with = "split", separator = "|")]
@ -127,6 +136,7 @@ fn parse_with_split2() {
}
#[test]
#[cfg(feature = "macros")]
fn parse_custom_parser() {
fn custom_parse_function(s: String) -> Result<(u8, String), ParseError> {
let vec = s.split_whitespace().collect::<Vec<_>>();
@ -154,6 +164,7 @@ fn parse_custom_parser() {
}
#[test]
#[cfg(feature = "macros")]
fn parse_named_fields() {
#[command(rename = "lowercase")]
#[command(parse_with = "split")]
@ -170,6 +181,7 @@ fn parse_named_fields() {
}
#[test]
#[cfg(feature = "macros")]
fn descriptions_off() {
#[command(rename = "lowercase")]
#[derive(BotCommand, Debug, PartialEq)]