From 713ff36d7b2152027e1a2f1a59699b0d04ab5de7 Mon Sep 17 00:00:00 2001 From: liveseed Date: Mon, 14 Nov 2022 10:04:27 +0100 Subject: [PATCH] Split crate into a proc-macro and a regular library crate (#214) proc-macro crates are loaded by the compiler instead of by the crate that depends on it. This means it's not possible to use anything else than exported anything else than exported proc-macros. But in some cases we want the generated derives to use structs or traits that are provided by the library. Two examples of this are: 1. An error type that can be used by the `Into` derive ([#173]) 2. Or to support trait objects for the `source` of the `Error` derive ([#122]) This change splits the layout of this crate in two. One crate that only exports proc-macros and is loaded by the compiler. And a second crate that re-exports all these macros but is also able to export different things such as structs and traits. NOTE: This only refactors the code in this repo. No functional changes happen in this change. These will be done in follow-up PRs. [#173]: https://github.com/JelteF/derive_more/issues/173 [#122]: https://github.com/JelteF/derive_more/issues/122 Required for #173 #122 Co-authored-by: tyranron --- .github/workflows/ci.yml | 16 +- CONTRIBUTING.md | 6 +- Cargo.toml | 64 ++++---- ci/test_all_features.sh | 2 +- impl/Cargo.toml | 70 ++++++++ impl/LICENSE | 1 + impl/README.md | 12 ++ build.rs => impl/build.rs | 0 {doc => impl/doc}/add.md | 0 {doc => impl/doc}/add_assign.md | 0 {doc => impl/doc}/as_mut.md | 0 {doc => impl/doc}/as_ref.md | 0 {doc => impl/doc}/constructor.md | 0 {doc => impl/doc}/deref.md | 0 {doc => impl/doc}/deref_mut.md | 0 {doc => impl/doc}/display.md | 0 {doc => impl/doc}/error.md | 6 +- {doc => impl/doc}/from.md | 0 {doc => impl/doc}/from_str.md | 0 {doc => impl/doc}/index.md | 0 {doc => impl/doc}/index_mut.md | 0 {doc => impl/doc}/into.md | 0 {doc => impl/doc}/into_iterator.md | 0 {doc => impl/doc}/is_variant.md | 0 {doc => impl/doc}/mul.md | 0 {doc => impl/doc}/mul_assign.md | 0 {doc => impl/doc}/not.md | 0 {doc => impl/doc}/sum.md | 0 {doc => impl/doc}/try_into.md | 0 {doc => impl/doc}/unwrap.md | 0 {src => impl/src}/add_assign_like.rs | 0 {src => impl/src}/add_helpers.rs | 0 {src => impl/src}/add_like.rs | 0 {src => impl/src}/as_mut.rs | 0 {src => impl/src}/as_ref.rs | 0 {src => impl/src}/constructor.rs | 0 {src => impl/src}/deref.rs | 0 {src => impl/src}/deref_mut.rs | 0 {src => impl/src}/display.rs | 0 {src => impl/src}/error.rs | 0 {src => impl/src}/from.rs | 0 {src => impl/src}/from_str.rs | 0 {src => impl/src}/index.rs | 0 {src => impl/src}/index_mut.rs | 0 {src => impl/src}/into.rs | 0 {src => impl/src}/into_iterator.rs | 0 {src => impl/src}/is_variant.rs | 0 impl/src/lib.rs | 237 +++++++++++++++++++++++++++ {src => impl/src}/mul_assign_like.rs | 0 {src => impl/src}/mul_helpers.rs | 0 {src => impl/src}/mul_like.rs | 0 {src => impl/src}/not_like.rs | 0 {src => impl/src}/parsing.rs | 0 {src => impl/src}/sum_like.rs | 0 {src => impl/src}/try_into.rs | 0 {src => impl/src}/unwrap.rs | 0 {src => impl/src}/utils.rs | 6 +- src/lib.rs | 234 +------------------------- 58 files changed, 370 insertions(+), 284 deletions(-) create mode 100644 impl/Cargo.toml create mode 120000 impl/LICENSE create mode 100644 impl/README.md rename build.rs => impl/build.rs (100%) rename {doc => impl/doc}/add.md (100%) rename {doc => impl/doc}/add_assign.md (100%) rename {doc => impl/doc}/as_mut.md (100%) rename {doc => impl/doc}/as_ref.md (100%) rename {doc => impl/doc}/constructor.md (100%) rename {doc => impl/doc}/deref.md (100%) rename {doc => impl/doc}/deref_mut.md (100%) rename {doc => impl/doc}/display.md (100%) rename {doc => impl/doc}/error.md (96%) rename {doc => impl/doc}/from.md (100%) rename {doc => impl/doc}/from_str.md (100%) rename {doc => impl/doc}/index.md (100%) rename {doc => impl/doc}/index_mut.md (100%) rename {doc => impl/doc}/into.md (100%) rename {doc => impl/doc}/into_iterator.md (100%) rename {doc => impl/doc}/is_variant.md (100%) rename {doc => impl/doc}/mul.md (100%) rename {doc => impl/doc}/mul_assign.md (100%) rename {doc => impl/doc}/not.md (100%) rename {doc => impl/doc}/sum.md (100%) rename {doc => impl/doc}/try_into.md (100%) rename {doc => impl/doc}/unwrap.md (100%) rename {src => impl/src}/add_assign_like.rs (100%) rename {src => impl/src}/add_helpers.rs (100%) rename {src => impl/src}/add_like.rs (100%) rename {src => impl/src}/as_mut.rs (100%) rename {src => impl/src}/as_ref.rs (100%) rename {src => impl/src}/constructor.rs (100%) rename {src => impl/src}/deref.rs (100%) rename {src => impl/src}/deref_mut.rs (100%) rename {src => impl/src}/display.rs (100%) rename {src => impl/src}/error.rs (100%) rename {src => impl/src}/from.rs (100%) rename {src => impl/src}/from_str.rs (100%) rename {src => impl/src}/index.rs (100%) rename {src => impl/src}/index_mut.rs (100%) rename {src => impl/src}/into.rs (100%) rename {src => impl/src}/into_iterator.rs (100%) rename {src => impl/src}/is_variant.rs (100%) create mode 100644 impl/src/lib.rs rename {src => impl/src}/mul_assign_like.rs (100%) rename {src => impl/src}/mul_helpers.rs (100%) rename {src => impl/src}/mul_like.rs (100%) rename {src => impl/src}/not_like.rs (100%) rename {src => impl/src}/parsing.rs (100%) rename {src => impl/src}/sum_like.rs (100%) rename {src => impl/src}/try_into.rs (100%) rename {src => impl/src}/unwrap.rs (100%) rename {src => impl/src}/utils.rs (99%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 140af6a..45fa04d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: toolchain: stable components: clippy - - run: cargo clippy --all-features -- -D warnings + - run: cargo clippy --workspace --all-features -- -D warnings rustfmt: runs-on: ubuntu-latest @@ -73,7 +73,7 @@ jobs: - name: Install minimal dependencies versions run: cargo +nightly update -Z minimal-versions - - run: cargo test --features testing-helpers + - run: cargo test --workspace --features testing-helpers test: strategy: @@ -94,7 +94,7 @@ jobs: toolchain: ${{ matrix.toolchain }} - run: rustup default ${{ matrix.toolchain }} - - run: cargo test --features testing-helpers + - run: cargo test --workspace --features testing-helpers test-features: name: test features @@ -129,7 +129,7 @@ jobs: with: toolchain: nightly - - run: cargo +nightly doc + - run: cargo +nightly doc --workspace env: RUSTDOCFLAGS: --cfg docsrs @@ -156,8 +156,8 @@ jobs: - name: Parse release version id: release - run: echo ::set-output - name=version::${GITHUB_REF#refs/tags/v} + run: echo "version=${GITHUB_REF#refs/tags/v}" + >> $GITHUB_OUTPUT - name: Verify release version matches `derive_more` Cargo manifest run: | test "${{ steps.release.outputs.version }}" \ @@ -165,8 +165,8 @@ jobs: - name: Parse CHANGELOG link id: changelog - run: echo ::set-output - name=link::${{ github.server_url }}/${{ github.repository }}/blob/v${{ steps.release.outputs.version }}/CHANGELOG.md#$(sed -n '/^## ${{ steps.release.outputs.version }}/{s/^## \([^ ]*\) - \([0-9].*\)/\1---\2/;s/[^0-9a-z-]*//g;p;}' CHANGELOG.md) + run: echo "link=${{ github.server_url }}/${{ github.repository }}/blob/v${{ steps.release.outputs.version }}/CHANGELOG.md#$(sed -n '/^## ${{ steps.release.outputs.version }}/{s/^## \([^ ]*\) - \([0-9].*\)/\1---\2/;s/[^0-9a-z-]*//g;p;}' CHANGELOG.md)" + >> $GITHUB_OUTPUT - uses: softprops/action-gh-release@v1 with: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index afe2a6f..46914a1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ If a new behaviour makes sense, that is different from the current behavior, the ### Documentation -Documentation is contained in the `doc/*.md` files and [README]. +Documentation is contained in the `impl/doc/*.md` files and [README]. Documentation should be up-to-date with any [PR] changes visible for library end-users. @@ -51,7 +51,7 @@ The best strategy for writing a new integration test is to look at existing inte #### Documentation tests -These are the [code examples][1] in the `doc/*.md` files and [README]. +These are the [code examples][1] in the `impl/doc/*.md` files and [README]. Writing documentation tests is needed for better illustration of the added/altered capabilities for end-users of the crate. @@ -92,7 +92,7 @@ To produce a new release of the `derive_more` crate, perform the following steps 1. Complete the existing [CHANGELOG] or fill up a new one for the new version. 2. Update [README] installation instructions with the new version. -3. Run `cargo release patch` (or `minor`/`major`). +3. Run `cargo release patch --workspace` (or `minor`/`major`). 4. Wait for the CI pipeline to complete successfully, and the [GitHub release] being created. diff --git a/Cargo.toml b/Cargo.toml index 26b9edd..2baee33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,6 @@ categories = ["development-tools", "development-tools::procedural-macro-helpers" include = [ "src/**/*.rs", - "doc/**/*.md", "Cargo.toml", "LICENSE", "README.md", @@ -23,19 +22,11 @@ include = [ "tests/**/*.rs", # debian packaging wants this ] -[lib] -name = "derive_more" -proc-macro = true +[workspace] +members = ["impl"] [dependencies] -proc-macro2 = "1.0" -quote = "1.0" -syn = "1.0.81" -convert_case = { version = "0.6", optional = true } -unicode-xid = { version = "0.2.2", optional = true } - -[build-dependencies] -rustc_version = { version = "0.4", optional = true } +derive_more-impl = { version = "=0.99.17", path = "impl" } [dev-dependencies] rustversion = "1.0" @@ -48,30 +39,29 @@ github = { repository = "JelteF/derive_more", workflow = "CI" } rustdoc-args = ["--cfg", "docsrs"] [features] -add_assign = [] -add = [] -as_mut = [] -as_ref = [] -constructor = [] -deref = [] -deref_mut = [] -display = ["syn/extra-traits", "unicode-xid"] -error = ["syn/extra-traits"] -from = ["syn/extra-traits"] -from_str = ["convert_case"] -index = [] -index_mut = [] -into = ["syn/extra-traits"] -into_iterator = [] -iterator = [] -mul_assign = ["syn/extra-traits"] -mul = ["syn/extra-traits"] -not = ["syn/extra-traits"] -sum = [] -try_into = ["syn/extra-traits"] -testing-helpers = ["rustc_version"] -is_variant = ["convert_case"] -unwrap = ["convert_case", "rustc_version"] +add_assign = ["derive_more-impl/add_assign"] +add = ["derive_more-impl/add"] +as_mut = ["derive_more-impl/as_mut"] +as_ref = ["derive_more-impl/as_ref"] +constructor = ["derive_more-impl/constructor"] +deref = ["derive_more-impl/deref"] +deref_mut = ["derive_more-impl/deref_mut"] +display = ["derive_more-impl/display"] +error = ["derive_more-impl/error"] +from = ["derive_more-impl/from"] +from_str = ["derive_more-impl/from_str"] +index = ["derive_more-impl/index"] +index_mut = ["derive_more-impl/index_mut"] +into = ["derive_more-impl/into"] +into_iterator = ["derive_more-impl/into_iterator"] +iterator = ["derive_more-impl/iterator"] +mul_assign = ["derive_more-impl/mul_assign"] +mul = ["derive_more-impl/mul"] +not = ["derive_more-impl/not"] +sum = ["derive_more-impl/sum"] +try_into = ["derive_more-impl/try_into"] +is_variant = ["derive_more-impl/is_variant"] +unwrap = ["derive_more-impl/unwrap"] default = [ "add_assign", @@ -99,6 +89,8 @@ default = [ "unwrap" ] +testing-helpers = ["derive_more-impl/testing-helpers"] + [[test]] name = "add_assign" path = "tests/add_assign.rs" diff --git a/ci/test_all_features.sh b/ci/test_all_features.sh index 3ecd5bf..fb3af56 100755 --- a/ci/test_all_features.sh +++ b/ci/test_all_features.sh @@ -2,5 +2,5 @@ set -euxo pipefail for feature in $(tomljson Cargo.toml | jq --raw-output '.features | keys[]' | grep -v 'default\|testing-helpers'); do - cargo test --tests --no-default-features --features "$feature,testing-helpers"; + cargo test -p derive_more --tests --no-default-features --features "$feature,testing-helpers"; done diff --git a/impl/Cargo.toml b/impl/Cargo.toml new file mode 100644 index 0000000..ef75ee6 --- /dev/null +++ b/impl/Cargo.toml @@ -0,0 +1,70 @@ +[package] +name = "derive_more-impl" +version = "0.99.17" # should be the same as main crate version +edition = "2021" +rust-version = "1.56.0" +description = "Internal implementation of `derive_more` crate" +authors = ["Jelte Fennema "] +license = "MIT" +repository = "https://github.com/JelteF/derive_more" +documentation = "https://docs.rs/derive_more" + +# explicitly no keywords or categories so it cannot be found easily + +include = [ + "src/**/*.rs", + "doc/**/*.md", + "Cargo.toml", + "LICENSE", +] + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0" +quote = "1.0" +syn = "1.0.81" +convert_case = { version = "0.6", optional = true } +unicode-xid = { version = "0.2.2", optional = true } + +[build-dependencies] +rustc_version = { version = "0.4", optional = true } + +[dev-dependencies] +derive_more = { path = ".." } + +[badges] +github = { repository = "JelteF/derive_more", workflow = "CI" } + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] + +[features] +add_assign = [] +add = [] +as_mut = [] +as_ref = [] +constructor = [] +deref = [] +deref_mut = [] +display = ["syn/extra-traits", "unicode-xid"] +error = ["syn/extra-traits"] +from = ["syn/extra-traits"] +from_str = ["convert_case"] +index = [] +index_mut = [] +into = ["syn/extra-traits"] +into_iterator = [] +iterator = [] +mul_assign = ["syn/extra-traits"] +mul = ["syn/extra-traits"] +not = ["syn/extra-traits"] +sum = [] +try_into = ["syn/extra-traits"] +is_variant = ["convert_case"] +unwrap = ["convert_case"] + +default = [] + +testing-helpers = ["rustc_version"] diff --git a/impl/LICENSE b/impl/LICENSE new file mode 120000 index 0000000..ea5b606 --- /dev/null +++ b/impl/LICENSE @@ -0,0 +1 @@ +../LICENSE \ No newline at end of file diff --git a/impl/README.md b/impl/README.md new file mode 100644 index 0000000..2a7de75 --- /dev/null +++ b/impl/README.md @@ -0,0 +1,12 @@ +# `derive_more-impl` + +This crate is an implementation detail of the [`derive_more`][crates.io]. If you +found this crate by accident you're probably looking for one of the following +pages of [`derive_more`][crates.io]: +1. [crates.io] +2. [docs.rs] +3. [GitHub] + +[crates.io]: https://crates.io/crates/derive_more +[docs.rs]: https://docs.rs/derive_more/latest/derive_more +[GitHub]: https://github.com/JelteF/derive_more diff --git a/build.rs b/impl/build.rs similarity index 100% rename from build.rs rename to impl/build.rs diff --git a/doc/add.md b/impl/doc/add.md similarity index 100% rename from doc/add.md rename to impl/doc/add.md diff --git a/doc/add_assign.md b/impl/doc/add_assign.md similarity index 100% rename from doc/add_assign.md rename to impl/doc/add_assign.md diff --git a/doc/as_mut.md b/impl/doc/as_mut.md similarity index 100% rename from doc/as_mut.md rename to impl/doc/as_mut.md diff --git a/doc/as_ref.md b/impl/doc/as_ref.md similarity index 100% rename from doc/as_ref.md rename to impl/doc/as_ref.md diff --git a/doc/constructor.md b/impl/doc/constructor.md similarity index 100% rename from doc/constructor.md rename to impl/doc/constructor.md diff --git a/doc/deref.md b/impl/doc/deref.md similarity index 100% rename from doc/deref.md rename to impl/doc/deref.md diff --git a/doc/deref_mut.md b/impl/doc/deref_mut.md similarity index 100% rename from doc/deref_mut.md rename to impl/doc/deref_mut.md diff --git a/doc/display.md b/impl/doc/display.md similarity index 100% rename from doc/display.md rename to impl/doc/display.md diff --git a/doc/error.md b/impl/doc/error.md similarity index 96% rename from doc/error.md rename to impl/doc/error.md index 35bd273..4643cef 100644 --- a/doc/error.md +++ b/impl/doc/error.md @@ -47,11 +47,11 @@ ignored for one of these methods by using `#[error(not(backtrace))]` or ## Example usage ```rust -# #![cfg_attr(feature = "nightly", feature(error_generic_member_access, provide_any))] +# #![cfg_attr(nightly, feature(error_generic_member_access, provide_any))] // Nightly requires enabling this features: // #![feature(error_generic_member_access, provide_any)] -# #[cfg(not(feature = "nightly"))] fn main() {} -# #[cfg(feature = "nightly")] fn main() { +# #[cfg(not(nightly))] fn main() {} +# #[cfg(nightly)] fn main() { # use std::{any, error::Error as _, backtrace::Backtrace}; # # use derive_more::{Display, Error, From}; diff --git a/doc/from.md b/impl/doc/from.md similarity index 100% rename from doc/from.md rename to impl/doc/from.md diff --git a/doc/from_str.md b/impl/doc/from_str.md similarity index 100% rename from doc/from_str.md rename to impl/doc/from_str.md diff --git a/doc/index.md b/impl/doc/index.md similarity index 100% rename from doc/index.md rename to impl/doc/index.md diff --git a/doc/index_mut.md b/impl/doc/index_mut.md similarity index 100% rename from doc/index_mut.md rename to impl/doc/index_mut.md diff --git a/doc/into.md b/impl/doc/into.md similarity index 100% rename from doc/into.md rename to impl/doc/into.md diff --git a/doc/into_iterator.md b/impl/doc/into_iterator.md similarity index 100% rename from doc/into_iterator.md rename to impl/doc/into_iterator.md diff --git a/doc/is_variant.md b/impl/doc/is_variant.md similarity index 100% rename from doc/is_variant.md rename to impl/doc/is_variant.md diff --git a/doc/mul.md b/impl/doc/mul.md similarity index 100% rename from doc/mul.md rename to impl/doc/mul.md diff --git a/doc/mul_assign.md b/impl/doc/mul_assign.md similarity index 100% rename from doc/mul_assign.md rename to impl/doc/mul_assign.md diff --git a/doc/not.md b/impl/doc/not.md similarity index 100% rename from doc/not.md rename to impl/doc/not.md diff --git a/doc/sum.md b/impl/doc/sum.md similarity index 100% rename from doc/sum.md rename to impl/doc/sum.md diff --git a/doc/try_into.md b/impl/doc/try_into.md similarity index 100% rename from doc/try_into.md rename to impl/doc/try_into.md diff --git a/doc/unwrap.md b/impl/doc/unwrap.md similarity index 100% rename from doc/unwrap.md rename to impl/doc/unwrap.md diff --git a/src/add_assign_like.rs b/impl/src/add_assign_like.rs similarity index 100% rename from src/add_assign_like.rs rename to impl/src/add_assign_like.rs diff --git a/src/add_helpers.rs b/impl/src/add_helpers.rs similarity index 100% rename from src/add_helpers.rs rename to impl/src/add_helpers.rs diff --git a/src/add_like.rs b/impl/src/add_like.rs similarity index 100% rename from src/add_like.rs rename to impl/src/add_like.rs diff --git a/src/as_mut.rs b/impl/src/as_mut.rs similarity index 100% rename from src/as_mut.rs rename to impl/src/as_mut.rs diff --git a/src/as_ref.rs b/impl/src/as_ref.rs similarity index 100% rename from src/as_ref.rs rename to impl/src/as_ref.rs diff --git a/src/constructor.rs b/impl/src/constructor.rs similarity index 100% rename from src/constructor.rs rename to impl/src/constructor.rs diff --git a/src/deref.rs b/impl/src/deref.rs similarity index 100% rename from src/deref.rs rename to impl/src/deref.rs diff --git a/src/deref_mut.rs b/impl/src/deref_mut.rs similarity index 100% rename from src/deref_mut.rs rename to impl/src/deref_mut.rs diff --git a/src/display.rs b/impl/src/display.rs similarity index 100% rename from src/display.rs rename to impl/src/display.rs diff --git a/src/error.rs b/impl/src/error.rs similarity index 100% rename from src/error.rs rename to impl/src/error.rs diff --git a/src/from.rs b/impl/src/from.rs similarity index 100% rename from src/from.rs rename to impl/src/from.rs diff --git a/src/from_str.rs b/impl/src/from_str.rs similarity index 100% rename from src/from_str.rs rename to impl/src/from_str.rs diff --git a/src/index.rs b/impl/src/index.rs similarity index 100% rename from src/index.rs rename to impl/src/index.rs diff --git a/src/index_mut.rs b/impl/src/index_mut.rs similarity index 100% rename from src/index_mut.rs rename to impl/src/index_mut.rs diff --git a/src/into.rs b/impl/src/into.rs similarity index 100% rename from src/into.rs rename to impl/src/into.rs diff --git a/src/into_iterator.rs b/impl/src/into_iterator.rs similarity index 100% rename from src/into_iterator.rs rename to impl/src/into_iterator.rs diff --git a/src/is_variant.rs b/impl/src/is_variant.rs similarity index 100% rename from src/is_variant.rs rename to impl/src/is_variant.rs diff --git a/impl/src/lib.rs b/impl/src/lib.rs new file mode 100644 index 0000000..48cc9cd --- /dev/null +++ b/impl/src/lib.rs @@ -0,0 +1,237 @@ +#![doc = include_str!("../README.md")] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![recursion_limit = "128"] +#![deny(rustdoc::broken_intra_doc_links, rustdoc::private_intra_doc_links)] +#![forbid(non_ascii_idents, unsafe_code)] + +use proc_macro::TokenStream; +use syn::parse::Error as ParseError; + +mod utils; + +#[cfg(any(feature = "add_assign", feature = "mul_assign"))] +mod add_assign_like; +#[cfg(any( + feature = "add", + feature = "add_assign", + feature = "mul", + feature = "mul_assign", +))] +mod add_helpers; +#[cfg(any(feature = "add", feature = "mul"))] +mod add_like; +#[cfg(feature = "as_mut")] +mod as_mut; +#[cfg(feature = "as_ref")] +mod as_ref; +#[cfg(feature = "constructor")] +mod constructor; +#[cfg(feature = "deref")] +mod deref; +#[cfg(feature = "deref_mut")] +mod deref_mut; +#[cfg(feature = "display")] +mod display; +#[cfg(feature = "error")] +mod error; +#[cfg(feature = "from")] +mod from; +#[cfg(feature = "from_str")] +mod from_str; +#[cfg(feature = "index")] +mod index; +#[cfg(feature = "index_mut")] +mod index_mut; +#[cfg(feature = "into")] +mod into; +#[cfg(feature = "into_iterator")] +mod into_iterator; +#[cfg(feature = "is_variant")] +mod is_variant; +#[cfg(feature = "mul_assign")] +mod mul_assign_like; +#[cfg(any(feature = "mul", feature = "mul_assign"))] +mod mul_helpers; +#[cfg(feature = "mul")] +mod mul_like; +#[cfg(feature = "not")] +mod not_like; +#[cfg(feature = "display")] +mod parsing; +#[cfg(feature = "sum")] +mod sum_like; +#[cfg(feature = "try_into")] +mod try_into; +#[cfg(feature = "unwrap")] +mod unwrap; + +// This trait describes the possible return types of +// the derives. A derive can generally be infallible and +// return a TokenStream, or it can be fallible and return +// a Result. +trait Output { + fn process(self) -> TokenStream; +} + +impl Output for proc_macro2::TokenStream { + fn process(self) -> TokenStream { + self.into() + } +} + +impl Output for Result { + fn process(self) -> TokenStream { + match self { + Ok(ts) => ts.into(), + Err(e) => e.to_compile_error().into(), + } + } +} + +macro_rules! create_derive( + ($feature:literal, $mod_:ident, $trait_:ident, $fn_name: ident $(,$attribute:ident)* $(,)?) => { + #[cfg(feature = $feature)] + #[proc_macro_derive($trait_, attributes($($attribute),*))] + #[doc = include_str!(concat!("../doc/", $feature, ".md"))] + pub fn $fn_name(input: TokenStream) -> TokenStream { + let ast = syn::parse(input).unwrap(); + Output::process($mod_::expand(&ast, stringify!($trait_))) + } + } +); + +create_derive!("from", from, From, from_derive, from); + +create_derive!("into", into, Into, into_derive, into); + +create_derive!("constructor", constructor, Constructor, constructor_derive); + +create_derive!("not", not_like, Not, not_derive); +create_derive!("not", not_like, Neg, neg_derive); + +create_derive!("add", add_like, Add, add_derive); +create_derive!("add", add_like, Sub, sub_derive); +create_derive!("add", add_like, BitAnd, bit_and_derive); +create_derive!("add", add_like, BitOr, bit_or_derive); +create_derive!("add", add_like, BitXor, bit_xor_derive); + +create_derive!("mul", mul_like, Mul, mul_derive, mul); +create_derive!("mul", mul_like, Div, div_derive, div); +create_derive!("mul", mul_like, Rem, rem_derive, rem); +create_derive!("mul", mul_like, Shr, shr_derive, shr); +create_derive!("mul", mul_like, Shl, shl_derive, shl); + +create_derive!("add_assign", add_assign_like, AddAssign, add_assign_derive,); +create_derive!("add_assign", add_assign_like, SubAssign, sub_assign_derive,); +create_derive!( + "add_assign", + add_assign_like, + BitAndAssign, + bit_and_assign_derive, +); +create_derive!( + "add_assign", + add_assign_like, + BitOrAssign, + bit_or_assign_derive, +); +create_derive!( + "add_assign", + add_assign_like, + BitXorAssign, + bit_xor_assign_derive, +); + +create_derive!( + "mul_assign", + mul_assign_like, + MulAssign, + mul_assign_derive, + mul_assign, +); +create_derive!( + "mul_assign", + mul_assign_like, + DivAssign, + div_assign_derive, + div_assign, +); +create_derive!( + "mul_assign", + mul_assign_like, + RemAssign, + rem_assign_derive, + rem_assign, +); +create_derive!( + "mul_assign", + mul_assign_like, + ShrAssign, + shr_assign_derive, + shr_assign, +); +create_derive!( + "mul_assign", + mul_assign_like, + ShlAssign, + shl_assign_derive, + shl_assign, +); + +create_derive!("sum", sum_like, Sum, sum_derive); +create_derive!("sum", sum_like, Product, product_derive); + +create_derive!("error", error, Error, error_derive, error); + +create_derive!("from_str", from_str, FromStr, from_str_derive); + +create_derive!("display", display, Display, display_derive, display); +create_derive!("display", display, Binary, binary_derive, binary); +create_derive!("display", display, Octal, octal_derive, octal); +create_derive!("display", display, LowerHex, lower_hex_derive, lower_hex); +create_derive!("display", display, UpperHex, upper_hex_derive, upper_hex); +create_derive!("display", display, LowerExp, lower_exp_derive, lower_exp); +create_derive!("display", display, UpperExp, upper_exp_derive, upper_exp); +create_derive!("display", display, Pointer, pointer_derive, pointer); +create_derive!("display", display, DebugCustom, debug_custom_derive, debug); + +create_derive!("index", index, Index, index_derive, index); +create_derive!( + "index_mut", + index_mut, + IndexMut, + index_mut_derive, + index_mut, +); + +create_derive!( + "into_iterator", + into_iterator, + IntoIterator, + into_iterator_derive, + into_iterator, +); + +create_derive!("try_into", try_into, TryInto, try_into_derive, try_into); + +create_derive!("deref", deref, Deref, deref_derive, deref); +create_derive!( + "deref_mut", + deref_mut, + DerefMut, + deref_mut_derive, + deref_mut, +); + +create_derive!("as_ref", as_ref, AsRef, as_ref_derive, as_ref); +create_derive!("as_mut", as_mut, AsMut, as_mut_derive, as_mut); + +create_derive!( + "is_variant", + is_variant, + IsVariant, + is_variant_derive, + is_variant +); + +create_derive!("unwrap", unwrap, Unwrap, unwrap_derive, unwrap); diff --git a/src/mul_assign_like.rs b/impl/src/mul_assign_like.rs similarity index 100% rename from src/mul_assign_like.rs rename to impl/src/mul_assign_like.rs diff --git a/src/mul_helpers.rs b/impl/src/mul_helpers.rs similarity index 100% rename from src/mul_helpers.rs rename to impl/src/mul_helpers.rs diff --git a/src/mul_like.rs b/impl/src/mul_like.rs similarity index 100% rename from src/mul_like.rs rename to impl/src/mul_like.rs diff --git a/src/not_like.rs b/impl/src/not_like.rs similarity index 100% rename from src/not_like.rs rename to impl/src/not_like.rs diff --git a/src/parsing.rs b/impl/src/parsing.rs similarity index 100% rename from src/parsing.rs rename to impl/src/parsing.rs diff --git a/src/sum_like.rs b/impl/src/sum_like.rs similarity index 100% rename from src/sum_like.rs rename to impl/src/sum_like.rs diff --git a/src/try_into.rs b/impl/src/try_into.rs similarity index 100% rename from src/try_into.rs rename to impl/src/try_into.rs diff --git a/src/unwrap.rs b/impl/src/unwrap.rs similarity index 100% rename from src/unwrap.rs rename to impl/src/unwrap.rs diff --git a/src/utils.rs b/impl/src/utils.rs similarity index 99% rename from src/utils.rs rename to impl/src/utils.rs index 2e1635b..7c6135a 100644 --- a/src/utils.rs +++ b/impl/src/utils.rs @@ -1,4 +1,8 @@ -#![cfg_attr(not(feature = "default"), allow(dead_code), allow(unused_mut))] +#![cfg_attr( + not(all(feature = "add", feature = "mul")), + allow(dead_code), + allow(unused_mut) +)] use proc_macro2::{Span, TokenStream}; use quote::{quote, ToTokens}; diff --git a/src/lib.rs b/src/lib.rs index 5a8bc73..9e51ac9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,238 +27,8 @@ //! [`Unwrap`]: crate::Unwrap #![doc = include_str!("../README.md")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![recursion_limit = "128"] #![deny(rustdoc::broken_intra_doc_links, rustdoc::private_intra_doc_links)] #![forbid(non_ascii_idents, unsafe_code)] -use proc_macro::TokenStream; -use syn::parse::Error as ParseError; - -mod utils; - -#[cfg(any(feature = "add_assign", feature = "mul_assign"))] -mod add_assign_like; -#[cfg(any( - feature = "add", - feature = "add_assign", - feature = "mul", - feature = "mul_assign", -))] -mod add_helpers; -#[cfg(any(feature = "add", feature = "mul"))] -mod add_like; -#[cfg(feature = "as_mut")] -mod as_mut; -#[cfg(feature = "as_ref")] -mod as_ref; -#[cfg(feature = "constructor")] -mod constructor; -#[cfg(feature = "deref")] -mod deref; -#[cfg(feature = "deref_mut")] -mod deref_mut; -#[cfg(feature = "display")] -mod display; -#[cfg(feature = "error")] -mod error; -#[cfg(feature = "from")] -mod from; -#[cfg(feature = "from_str")] -mod from_str; -#[cfg(feature = "index")] -mod index; -#[cfg(feature = "index_mut")] -mod index_mut; -#[cfg(feature = "into")] -mod into; -#[cfg(feature = "into_iterator")] -mod into_iterator; -#[cfg(feature = "is_variant")] -mod is_variant; -#[cfg(feature = "mul_assign")] -mod mul_assign_like; -#[cfg(any(feature = "mul", feature = "mul_assign"))] -mod mul_helpers; -#[cfg(feature = "mul")] -mod mul_like; -#[cfg(feature = "not")] -mod not_like; -#[cfg(feature = "display")] -mod parsing; -#[cfg(feature = "sum")] -mod sum_like; -#[cfg(feature = "try_into")] -mod try_into; -#[cfg(feature = "unwrap")] -mod unwrap; - -// This trait describes the possible return types of -// the derives. A derive can generally be infallible and -// return a TokenStream, or it can be fallible and return -// a Result. -trait Output { - fn process(self) -> TokenStream; -} - -impl Output for proc_macro2::TokenStream { - fn process(self) -> TokenStream { - self.into() - } -} - -impl Output for Result { - fn process(self) -> TokenStream { - match self { - Ok(ts) => ts.into(), - Err(e) => e.to_compile_error().into(), - } - } -} - -macro_rules! create_derive( - ($feature:literal, $mod_:ident, $trait_:ident, $fn_name: ident $(,$attribute:ident)* $(,)?) => { - #[cfg(feature = $feature)] - #[proc_macro_derive($trait_, attributes($($attribute),*))] - #[doc = include_str!(concat!("../doc/", $feature, ".md"))] - pub fn $fn_name(input: TokenStream) -> TokenStream { - let ast = syn::parse(input).unwrap(); - Output::process($mod_::expand(&ast, stringify!($trait_))) - } - } -); - -create_derive!("from", from, From, from_derive, from); - -create_derive!("into", into, Into, into_derive, into); - -create_derive!("constructor", constructor, Constructor, constructor_derive); - -create_derive!("not", not_like, Not, not_derive); -create_derive!("not", not_like, Neg, neg_derive); - -create_derive!("add", add_like, Add, add_derive); -create_derive!("add", add_like, Sub, sub_derive); -create_derive!("add", add_like, BitAnd, bit_and_derive); -create_derive!("add", add_like, BitOr, bit_or_derive); -create_derive!("add", add_like, BitXor, bit_xor_derive); - -create_derive!("mul", mul_like, Mul, mul_derive, mul); -create_derive!("mul", mul_like, Div, div_derive, div); -create_derive!("mul", mul_like, Rem, rem_derive, rem); -create_derive!("mul", mul_like, Shr, shr_derive, shr); -create_derive!("mul", mul_like, Shl, shl_derive, shl); - -create_derive!("add_assign", add_assign_like, AddAssign, add_assign_derive,); -create_derive!("add_assign", add_assign_like, SubAssign, sub_assign_derive,); -create_derive!( - "add_assign", - add_assign_like, - BitAndAssign, - bit_and_assign_derive, -); -create_derive!( - "add_assign", - add_assign_like, - BitOrAssign, - bit_or_assign_derive, -); -create_derive!( - "add_assign", - add_assign_like, - BitXorAssign, - bit_xor_assign_derive, -); - -create_derive!( - "mul_assign", - mul_assign_like, - MulAssign, - mul_assign_derive, - mul_assign, -); -create_derive!( - "mul_assign", - mul_assign_like, - DivAssign, - div_assign_derive, - div_assign, -); -create_derive!( - "mul_assign", - mul_assign_like, - RemAssign, - rem_assign_derive, - rem_assign, -); -create_derive!( - "mul_assign", - mul_assign_like, - ShrAssign, - shr_assign_derive, - shr_assign, -); -create_derive!( - "mul_assign", - mul_assign_like, - ShlAssign, - shl_assign_derive, - shl_assign, -); - -create_derive!("sum", sum_like, Sum, sum_derive); -create_derive!("sum", sum_like, Product, product_derive); - -create_derive!("error", error, Error, error_derive, error); - -create_derive!("from_str", from_str, FromStr, from_str_derive); - -create_derive!("display", display, Display, display_derive, display); -create_derive!("display", display, Binary, binary_derive, binary); -create_derive!("display", display, Octal, octal_derive, octal); -create_derive!("display", display, LowerHex, lower_hex_derive, lower_hex); -create_derive!("display", display, UpperHex, upper_hex_derive, upper_hex); -create_derive!("display", display, LowerExp, lower_exp_derive, lower_exp); -create_derive!("display", display, UpperExp, upper_exp_derive, upper_exp); -create_derive!("display", display, Pointer, pointer_derive, pointer); -create_derive!("display", display, DebugCustom, debug_custom_derive, debug); - -create_derive!("index", index, Index, index_derive, index); -create_derive!( - "index_mut", - index_mut, - IndexMut, - index_mut_derive, - index_mut, -); - -create_derive!( - "into_iterator", - into_iterator, - IntoIterator, - into_iterator_derive, - into_iterator, -); - -create_derive!("try_into", try_into, TryInto, try_into_derive, try_into); - -create_derive!("deref", deref, Deref, deref_derive, deref); -create_derive!( - "deref_mut", - deref_mut, - DerefMut, - deref_mut_derive, - deref_mut, -); - -create_derive!("as_ref", as_ref, AsRef, as_ref_derive, as_ref); -create_derive!("as_mut", as_mut, AsMut, as_mut_derive, as_mut); - -create_derive!( - "is_variant", - is_variant, - IsVariant, - is_variant_derive, - is_variant -); - -create_derive!("unwrap", unwrap, Unwrap, unwrap_derive, unwrap); +#[doc(inline)] +pub use derive_more_impl::*;