diff --git a/.cargo/config.toml b/.cargo/config.toml index d6e070ff..a16645bb 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,12 +1,14 @@ [alias] -# We pass "--cfg docsrs" when building docs to turn on nightly-only rustdoc features like -# `This is supported on feature="..." only.` +# Using `--features=full --features=nightly` instead of `--all-features` because of +# https://github.com/rust-lang/cargo/issues/10333 # -# "--cfg dep_docsrs" is used for the same reason, but for `teloxide-core`. -docs = """ -doc - --all-features - --config build.rustflags=["--cfg=dep_docsrs"] - --config build.rustdocflags=["--cfg=docsrs","-Znormalize-docs"] - -Zrustdoc-scrape-examples=examples +# "tokio/macros" and "tokio/rt-multi-thread" are required for examples +docs = """doc +-Zrustdoc-scrape-examples=examples +--features=full --features=nightly +--features=tokio/macros --features=tokio/rt-multi-thread """ + +[build] +# We pass "--cfg docsrs" when building docs to add `This is supported on feature="..." only.` +rustdocflags = ["--cfg", "docsrs", "-Znormalize-docs"] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8396993..053bf592 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,13 +15,18 @@ env: CARGO_NET_RETRY: 10 RUSTUP_MAX_RETRIES: 10 - rust_nightly: nightly-2022-09-01 # When updating this, also update: - # - README.md - # - src/lib.rs + # - crates/teloxide-core/src/codegen.rs + # - rust-toolchain.toml + rust_nightly: nightly-2022-09-23 + # When updating this, also update: + # - **/README.md + # - **/src/lib.rs # - down below in a matrix rust_msrv: 1.64.0 + CI: 1 + jobs: # Depends on all action that are required for a "successful" CI run. ci-pass: diff --git a/crates/teloxide-core/.cargo/config.toml b/crates/teloxide-core/.cargo/config.toml deleted file mode 100644 index a16645bb..00000000 --- a/crates/teloxide-core/.cargo/config.toml +++ /dev/null @@ -1,14 +0,0 @@ -[alias] -# Using `--features=full --features=nightly` instead of `--all-features` because of -# https://github.com/rust-lang/cargo/issues/10333 -# -# "tokio/macros" and "tokio/rt-multi-thread" are required for examples -docs = """doc --Zrustdoc-scrape-examples=examples ---features=full --features=nightly ---features=tokio/macros --features=tokio/rt-multi-thread -""" - -[build] -# We pass "--cfg docsrs" when building docs to add `This is supported on feature="..." only.` -rustdocflags = ["--cfg", "docsrs", "-Znormalize-docs"] diff --git a/crates/teloxide-core/.github/workflows/ci.yml b/crates/teloxide-core/.github/workflows/ci.yml deleted file mode 100644 index f05f9948..00000000 --- a/crates/teloxide-core/.github/workflows/ci.yml +++ /dev/null @@ -1,191 +0,0 @@ -name: Continuous integration - -on: - push: - branches: - - master - pull_request: - branches: - - master - -env: - RUSTFLAGS: -Dwarnings - RUSTDOCFLAGS: -Dwarnings - RUST_BACKTRACE: short - - CARGO_INCREMENTAL: 0 - CARGO_NET_RETRY: 10 - RUSTUP_MAX_RETRIES: 10 - - rust_nightly: nightly-2022-09-23 - # When updating this, also update: - # - README.md - # - src/lib.rs - # - down below in a matrix - rust_msrv: 1.64.0 - - CI: 1 - -jobs: - # Depends on all action that are required for a "successful" CI run. - ci-pass: - name: CI succeeded - runs-on: ubuntu-latest - - needs: - - fmt - - test - - check-examples - - clippy - - doc - - steps: - - run: exit 0 - - fmt: - name: fmt - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install Rust ${{ env.rust_nightly }} - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ env.rust_nightly }} - override: true - components: rustfmt - - - name: Cache Dependencies - uses: Swatinem/rust-cache@v1 - - - name: Check formatting - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - test: - name: Test - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - stable - - beta - - nightly - - msrv - - include: - - rust: stable - toolchain: stable - features: "--features full" - - rust: beta - toolchain: beta - features: "--features full" - - rust: nightly - toolchain: nightly-2022-09-23 - features: "--all-features" - - rust: msrv - toolchain: 1.64.0 - features: "--features full" - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install Rust ${{ matrix.toolchain }} - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.toolchain }} - override: true - components: rustfmt # required by codegen - - - name: Cache Dependencies - uses: Swatinem/rust-cache@v1 - - - name: Compile - uses: actions-rs/cargo@v1 - with: - command: test - args: --no-run --verbose ${{ matrix.features }} - - - name: Test - uses: actions-rs/cargo@v1 - with: - command: test - args: --verbose ${{ matrix.features }} - - check-examples: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install Rust stable - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - - name: Cache Dependencies - uses: Swatinem/rust-cache@v1 - - - name: Check examples - uses: actions-rs/cargo@v1 - with: - command: check - args: --examples --features full - - clippy: - name: Run linter - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install Rust ${{ env.rust_nightly }} - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ env.rust_nightly }} - override: true - components: clippy - - - name: Cache Dependencies - uses: Swatinem/rust-cache@v1 - - - name: clippy - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --all-targets --all-features - - doc: - name: check docs - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install Rust ${{ env.rust_nightly }} - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ env.rust_nightly }} - override: true - - - name: Cache Dependencies - uses: Swatinem/rust-cache@v1 - - - name: rustdoc - uses: actions-rs/cargo@v1 - with: - command: docs # from .cargo/config.toml diff --git a/crates/teloxide-macros/.github/workflows/rust.yml b/crates/teloxide-macros/.github/workflows/rust.yml deleted file mode 100644 index 0ec2a488..00000000 --- a/crates/teloxide-macros/.github/workflows/rust.yml +++ /dev/null @@ -1,72 +0,0 @@ -on: [push, pull_request] - -name: Continuous integration - -jobs: - ci: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - stable - - beta - - nightly - - steps: - - uses: actions/checkout@v1 - - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - override: true - components: rustfmt, clippy - - - name: stable/beta build - uses: actions-rs/cargo@v1 - if: matrix.rust == 'stable' || matrix.rust == 'beta' - with: - command: build - args: --verbose --features "" - - - name: nightly build - uses: actions-rs/cargo@v1 - if: matrix.rust == 'nightly' - with: - command: build - args: --verbose --all-features - - - name: stable/beta test - uses: actions-rs/cargo@v1 - if: matrix.rust == 'stable' || matrix.rust == 'beta' - with: - command: test - args: --verbose --features "" - - - name: nightly test - uses: actions-rs/cargo@v1 - if: matrix.rust == 'nightly' - with: - command: test - args: --verbose --all-features - - - name: fmt - uses: actions-rs/cargo@v1 - if: matrix.rust == 'nightly' - with: - command: fmt - args: --all -- --check - - - name: stable/beta clippy - uses: actions-rs/cargo@v1 - if: matrix.rust == 'stable' || matrix.rust == 'beta' - with: - command: clippy - args: --all-targets --features "" -- -D warnings - - - name: nightly clippy - uses: actions-rs/cargo@v1 - if: matrix.rust == 'nightly' - with: - command: clippy - args: --all-targets --all-features -- -D warnings diff --git a/crates/teloxide-macros/Cargo.toml b/crates/teloxide-macros/Cargo.toml index 9ac9b1f8..c6ea1d39 100644 --- a/crates/teloxide-macros/Cargo.toml +++ b/crates/teloxide-macros/Cargo.toml @@ -15,7 +15,3 @@ quote = "1.0.7" proc-macro2 = "1.0.19" syn = { version = "1.0.13", features = ["full"] } heck = "0.4.0" - -[dev-dependencies] -# XXX: Do not enable `macros` feature -teloxide = { path = "../teloxide" } diff --git a/crates/teloxide-macros/tests/command.rs b/crates/teloxide-macros/tests/command.rs deleted file mode 100644 index b627aa65..00000000 --- a/crates/teloxide-macros/tests/command.rs +++ /dev/null @@ -1,241 +0,0 @@ -//! Test for `teloxide-macros` - -use teloxide_macros::BotCommands; - -// Import only trait _methods_, such that we can call `parse`, but we also test -// that proc macros work without the trait being imported. -use teloxide::utils::command::BotCommands as _; - -#[test] -fn parse_command_with_args() { - #[derive(BotCommands, Debug, PartialEq)] - #[command(rename_rule = "lowercase")] - enum DefaultCommands { - Start(String), - Help, - } - - let data = "/start arg1 arg2"; - let expected = DefaultCommands::Start("arg1 arg2".to_string()); - let actual = DefaultCommands::parse(data, "").unwrap(); - assert_eq!(actual, expected) -} - -#[test] -fn parse_command_with_non_string_arg() { - #[derive(BotCommands, Debug, PartialEq)] - #[command(rename_rule = "lowercase")] - enum DefaultCommands { - Start(i32), - Help, - } - - let data = "/start -50"; - let expected = DefaultCommands::Start("-50".parse().unwrap()); - let actual = DefaultCommands::parse(data, "").unwrap(); - assert_eq!(actual, expected) -} - -#[test] -fn attribute_prefix() { - #[derive(BotCommands, Debug, PartialEq)] - #[command(rename_rule = "lowercase")] - enum DefaultCommands { - #[command(prefix = "!")] - Start(String), - Help, - } - - let data = "!start arg1 arg2"; - let expected = DefaultCommands::Start("arg1 arg2".to_string()); - let actual = DefaultCommands::parse(data, "").unwrap(); - assert_eq!(actual, expected) -} - -#[test] -fn many_attributes() { - #[derive(BotCommands, Debug, PartialEq)] - #[command(rename_rule = "lowercase")] - enum DefaultCommands { - #[command(prefix = "!", description = "desc")] - Start, - Help, - } - - assert_eq!(DefaultCommands::Start, DefaultCommands::parse("!start", "").unwrap()); - assert_eq!(DefaultCommands::descriptions().to_string(), "!start — desc\n/help"); -} - -#[test] -fn global_attributes() { - #[derive(BotCommands, Debug, PartialEq)] - #[command(prefix = "!", rename_rule = "lowercase", description = "Bot commands")] - enum DefaultCommands { - #[command(prefix = "/")] - Start, - Help, - } - - assert_eq!(DefaultCommands::Start, DefaultCommands::parse("/start", "MyNameBot").unwrap()); - assert_eq!(DefaultCommands::Help, DefaultCommands::parse("!help", "MyNameBot").unwrap()); - assert_eq!(DefaultCommands::descriptions().to_string(), "Bot commands\n\n/start\n!help"); -} - -#[test] -fn parse_command_with_bot_name() { - #[derive(BotCommands, Debug, PartialEq)] - #[command(rename_rule = "lowercase")] - enum DefaultCommands { - #[command(prefix = "/")] - Start, - Help, - } - - assert_eq!( - DefaultCommands::Start, - DefaultCommands::parse("/start@MyNameBot", "MyNameBot").unwrap() - ); -} - -#[test] -fn parse_with_split() { - #[derive(BotCommands, Debug, PartialEq)] - #[command(rename_rule = "lowercase")] - #[command(parse_with = "split")] - enum DefaultCommands { - Start(u8, String), - Help, - } - - assert_eq!( - DefaultCommands::Start(10, "hello".to_string()), - DefaultCommands::parse("/start 10 hello", "").unwrap() - ); -} - -#[test] -fn parse_with_split2() { - #[derive(BotCommands, Debug, PartialEq)] - #[command(rename_rule = "lowercase")] - #[command(parse_with = "split", separator = "|")] - enum DefaultCommands { - Start(u8, String), - Help, - } - - assert_eq!( - DefaultCommands::Start(10, "hello".to_string()), - DefaultCommands::parse("/start 10|hello", "").unwrap() - ); -} - -#[test] -fn parse_custom_parser() { - mod parser { - use teloxide::utils::command::ParseError; - - pub fn custom_parse_function(s: String) -> Result<(u8, String), ParseError> { - let vec = s.split_whitespace().collect::>(); - let (left, right) = match vec.as_slice() { - [l, r] => (l, r), - _ => return Err(ParseError::IncorrectFormat("might be 2 arguments!".into())), - }; - left.parse::().map(|res| (res, (*right).to_string())).map_err(|_| { - ParseError::Custom("First argument must be a integer!".to_owned().into()) - }) - } - } - - use parser::custom_parse_function; - - #[derive(BotCommands, Debug, PartialEq)] - #[command(rename_rule = "lowercase")] - enum DefaultCommands { - #[command(parse_with = custom_parse_function)] - Start(u8, String), - - // Test . - #[command(parse_with = parser::custom_parse_function)] - TestPath(u8, String), - - Help, - } - - assert_eq!( - DefaultCommands::Start(10, "hello".to_string()), - DefaultCommands::parse("/start 10 hello", "").unwrap() - ); - assert_eq!( - DefaultCommands::TestPath(10, "hello".to_string()), - DefaultCommands::parse("/testpath 10 hello", "").unwrap() - ); -} - -#[test] -fn parse_named_fields() { - #[derive(BotCommands, Debug, PartialEq)] - #[command(rename_rule = "lowercase")] - #[command(parse_with = "split")] - enum DefaultCommands { - Start { num: u8, data: String }, - Help, - } - - assert_eq!( - DefaultCommands::Start { num: 10, data: "hello".to_string() }, - DefaultCommands::parse("/start 10 hello", "").unwrap() - ); -} - -#[test] -fn descriptions_off() { - #[derive(BotCommands, Debug, PartialEq)] - #[command(rename_rule = "lowercase")] - enum DefaultCommands { - #[command(description = "off")] - Start, - Help, - } - - assert_eq!(DefaultCommands::descriptions().to_string(), "/help".to_owned()); -} - -#[test] -fn rename_rules() { - #[derive(BotCommands, Debug, PartialEq)] - enum DefaultCommands { - #[command(rename_rule = "lowercase")] - AaaAaa, - #[command(rename_rule = "UPPERCASE")] - BbbBbb, - #[command(rename_rule = "PascalCase")] - CccCcc, - #[command(rename_rule = "camelCase")] - DddDdd, - #[command(rename_rule = "snake_case")] - EeeEee, - #[command(rename_rule = "SCREAMING_SNAKE_CASE")] - FffFff, - #[command(rename_rule = "kebab-case")] - GggGgg, - #[command(rename_rule = "SCREAMING-KEBAB-CASE")] - HhhHhh, - #[command(rename = "Bar")] - Foo, - } - - assert_eq!(DefaultCommands::AaaAaa, DefaultCommands::parse("/aaaaaa", "").unwrap()); - assert_eq!(DefaultCommands::BbbBbb, DefaultCommands::parse("/BBBBBB", "").unwrap()); - assert_eq!(DefaultCommands::CccCcc, DefaultCommands::parse("/CccCcc", "").unwrap()); - assert_eq!(DefaultCommands::DddDdd, DefaultCommands::parse("/dddDdd", "").unwrap()); - assert_eq!(DefaultCommands::EeeEee, DefaultCommands::parse("/eee_eee", "").unwrap()); - assert_eq!(DefaultCommands::FffFff, DefaultCommands::parse("/FFF_FFF", "").unwrap()); - assert_eq!(DefaultCommands::GggGgg, DefaultCommands::parse("/ggg-ggg", "").unwrap()); - assert_eq!(DefaultCommands::HhhHhh, DefaultCommands::parse("/HHH-HHH", "").unwrap()); - assert_eq!(DefaultCommands::Foo, DefaultCommands::parse("/Bar", "").unwrap()); - - assert_eq!( - "/aaaaaa\n/BBBBBB\n/CccCcc\n/dddDdd\n/eee_eee\n/FFF_FFF\n/ggg-ggg\n/HHH-HHH\n/Bar", - DefaultCommands::descriptions().to_string() - ); -}