From e10b96bfce6dd6f539fcb2d0ec4d2c13d8d644a6 Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Sun, 23 Jul 2023 15:35:41 +0200 Subject: [PATCH] Re-export traits (#273) Re-export traits from `std` for all our derives. This way people don't need to import traits manually when they want to reference them somewhere, such as bounds. Fixes #271 --------- Co-authored-by: tyranron --- CHANGELOG.md | 1 + Cargo.toml | 8 +- README.md | 9 ++ impl/Cargo.toml | 11 +- impl/doc/display.md | 2 - impl/src/add_like.rs | 2 +- impl/src/as_mut.rs | 1 - impl/src/as_ref.rs | 1 - impl/src/deref.rs | 1 - impl/src/deref_mut.rs | 8 +- impl/src/error.rs | 14 +-- impl/src/from_str.rs | 7 +- impl/src/index.rs | 8 +- impl/src/index_mut.rs | 7 +- impl/src/into_iterator.rs | 8 +- impl/src/is_variant.rs | 1 - impl/src/lib.rs | 144 +++++++++++----------- impl/src/mul_assign_like.rs | 1 - impl/src/mul_like.rs | 1 - impl/src/sum_like.rs | 7 +- impl/src/try_into.rs | 1 - impl/src/try_unwrap.rs | 1 - impl/src/unwrap.rs | 1 - impl/src/utils.rs | 38 +----- src/fmt.rs | 2 + src/lib.rs | 231 ++++++++++++++++++++++++++++++++---- tests/display.rs | 1 - tests/error/mod.rs | 5 - 28 files changed, 319 insertions(+), 203 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1105d765..2cf78f30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). and ignores field type itself. - The `Into` derive now uses `#[into()]` instead of `#[into(types())]` and ignores field type itself. +- Importing a derive macro now also import its corresponding trait. ### Added diff --git a/Cargo.toml b/Cargo.toml index 32999fb7..961de47e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,6 @@ 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"] @@ -73,8 +72,8 @@ try_unwrap = ["derive_more-impl/try_unwrap"] std = [] full = [ - "add_assign", "add", + "add_assign", "as_mut", "as_ref", "constructor", @@ -90,14 +89,13 @@ full = [ "into", "into_iterator", "is_variant", - "iterator", - "mul_assign", "mul", + "mul_assign", "not", "sum", "try_into", - "unwrap", "try_unwrap", + "unwrap", ] testing-helpers = ["derive_more-impl/testing-helpers", "dep:rustc_version"] diff --git a/README.md b/README.md index 9ef4be14..c8e80e9b 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,15 @@ extern crate derive_more; # fn main() {} // omit wrapping statements above into `main()` in tests ``` +## Re-exports + +This crate also re-exports all of the standard library traits that it adds +derives for. So both the `Display` derive and the `Display` trait will be in +scope when you add the following code: +```rust +use derive_more::Display; +``` + [`cargo-expand`]: https://github.com/dtolnay/cargo-expand [`derive-new`]: https://github.com/nrc/derive-new diff --git a/impl/Cargo.toml b/impl/Cargo.toml index 51719c39..a1874637 100644 --- a/impl/Cargo.toml +++ b/impl/Cargo.toml @@ -33,7 +33,7 @@ unicode-xid = { version = "0.2.2", optional = true } rustc_version = { version = "0.4", optional = true } [dev-dependencies] -derive_more = { path = "..", features = ["add", "debug", "error", "from_str", "not", "std", "try_into", "try_unwrap"] } +derive_more = { path = "..", features = ["full"] } itertools = "0.11.0" [badges] @@ -45,8 +45,8 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = [] -add_assign = [] add = [] +add_assign = [] as_mut = [] as_ref = [] constructor = [] @@ -61,14 +61,13 @@ index = [] index_mut = [] into = ["syn/extra-traits"] into_iterator = [] -iterator = [] -mul_assign = ["syn/extra-traits"] +is_variant = ["dep:convert_case"] mul = ["syn/extra-traits"] +mul_assign = ["syn/extra-traits"] not = ["syn/extra-traits"] sum = [] try_into = ["syn/extra-traits"] -is_variant = ["dep:convert_case"] -unwrap = ["dep:convert_case"] try_unwrap = ["dep:convert_case"] +unwrap = ["dep:convert_case"] testing-helpers = ["dep:rustc_version"] diff --git a/impl/doc/display.md b/impl/doc/display.md index 64782124..5b616ca4 100644 --- a/impl/doc/display.md +++ b/impl/doc/display.md @@ -86,8 +86,6 @@ Note how we have to bound `U` and `V` by `Display` in the following example, as Not even `Display`. ```rust -# use std::fmt::Display; -# # use derive_more::Display; # # trait MyTrait { fn my_function(&self) -> i32; } diff --git a/impl/src/add_like.rs b/impl/src/add_like.rs index 58296217..58076461 100644 --- a/impl/src/add_like.rs +++ b/impl/src/add_like.rs @@ -42,7 +42,7 @@ pub fn expand(input: &DeriveInput, trait_name: &str) -> TokenStream { quote! { #[automatically_derived] - impl #impl_generics ::core::ops::#trait_ident for #input_type #ty_generics #where_clause { + impl #impl_generics ::derive_more::#trait_ident for #input_type #ty_generics #where_clause { type Output = #output_type; #[inline] diff --git a/impl/src/as_mut.rs b/impl/src/as_mut.rs index 2e6979a7..1d05adc5 100644 --- a/impl/src/as_mut.rs +++ b/impl/src/as_mut.rs @@ -10,7 +10,6 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result Result Result Result { - let state = State::with_field_ignore_and_forward( - input, - trait_name, - quote! { ::core::ops }, - "deref_mut".into(), - )?; + let state = + State::with_field_ignore_and_forward(input, trait_name, "deref_mut".into())?; let SingleFieldData { input_type, trait_path, diff --git a/impl/src/error.rs b/impl/src/error.rs index 4c4ba983..99771b4d 100644 --- a/impl/src/error.rs +++ b/impl/src/error.rs @@ -18,7 +18,6 @@ pub fn expand( let state = State::with_attr_params( input, trait_name, - quote! { ::derive_more::__private::Error }, trait_name.to_lowercase(), allowed_attr_params(), )?; @@ -39,7 +38,7 @@ pub fn expand( let source = source.map(|source| { quote! { - fn source(&self) -> Option<&(dyn ::derive_more::__private::Error + 'static)> { + fn source(&self) -> Option<&(dyn ::derive_more::Error + 'static)> { use ::derive_more::__private::AsDynError; #source } @@ -73,7 +72,7 @@ pub fn expand( &generics, quote! { where - #(#bounds: ::core::fmt::Debug + ::core::fmt::Display + ::derive_more::__private::Error + 'static),* + #(#bounds: ::core::fmt::Debug + ::core::fmt::Display + ::derive_more::Error + 'static),* }, ); } @@ -82,7 +81,7 @@ pub fn expand( let render = quote! { #[automatically_derived] - impl #impl_generics ::derive_more::__private::Error for #ident #ty_generics #where_clause { + impl #impl_generics ::derive_more::Error for #ident #ty_generics #where_clause { #source #provide } @@ -120,7 +119,6 @@ fn render_enum( let state = State::from_variant( state.input, state.trait_name, - state.trait_module.clone(), state.trait_attr.clone(), allowed_attr_params(), variant, @@ -207,7 +205,7 @@ impl<'input, 'state> ParsedFields<'input, 'state> { let source_provider = self.source.map(|source| { let source_expr = &self.data.members[source]; quote! { - ::derive_more::__private::Error::provide(&#source_expr, demand); + ::derive_more::Error::provide(&#source_expr, demand); } }); let backtrace_provider = self @@ -237,7 +235,7 @@ impl<'input, 'state> ParsedFields<'input, 'state> { let pattern = self.data.matcher(&[source], &[quote! { source }]); Some(quote! { #pattern => { - ::derive_more::__private::Error::provide(source, demand); + ::derive_more::Error::provide(source, demand); } }) } @@ -249,7 +247,7 @@ impl<'input, 'state> ParsedFields<'input, 'state> { Some(quote! { #pattern => { demand.provide_ref::<::std::backtrace::Backtrace>(backtrace); - ::derive_more::__private::Error::provide(source, demand); + ::derive_more::Error::provide(source, demand); } }) } diff --git a/impl/src/from_str.rs b/impl/src/from_str.rs index 0d3773dd..bc0ec541 100644 --- a/impl/src/from_str.rs +++ b/impl/src/from_str.rs @@ -6,12 +6,7 @@ use syn::{parse::Result, DeriveInput}; /// Provides the hook to expand `#[derive(FromStr)]` into an implementation of `FromStr` pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { - let state = State::new( - input, - trait_name, - quote! { ::core::str }, - trait_name.to_lowercase(), - )?; + let state = State::new(input, trait_name, trait_name.to_lowercase())?; if state.derive_type == DeriveType::Enum { Ok(enum_from(input, state, trait_name)) diff --git a/impl/src/index.rs b/impl/src/index.rs index 75ab5b33..bf4f0d7b 100644 --- a/impl/src/index.rs +++ b/impl/src/index.rs @@ -6,12 +6,8 @@ use syn::{parse::Result, DeriveInput}; /// Provides the hook to expand `#[derive(Index)]` into an implementation of `Index` pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { let index_type = format_ident!("__IdxT"); - let mut state = State::with_field_ignore( - input, - trait_name, - quote! { ::core::ops }, - trait_name.to_lowercase(), - )?; + let mut state = + State::with_field_ignore(input, trait_name, trait_name.to_lowercase())?; state.add_trait_path_type_param(quote! { #index_type }); let SingleFieldData { field, diff --git a/impl/src/index_mut.rs b/impl/src/index_mut.rs index fdafed15..0e030cf6 100644 --- a/impl/src/index_mut.rs +++ b/impl/src/index_mut.rs @@ -6,12 +6,7 @@ use syn::{parse::Result, DeriveInput}; /// Provides the hook to expand `#[derive(IndexMut)]` into an implementation of `IndexMut` pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { let index_type = format_ident!("__IdxT"); - let mut state = State::with_field_ignore( - input, - trait_name, - quote! { ::core::ops }, - "index_mut".into(), - )?; + let mut state = State::with_field_ignore(input, trait_name, "index_mut".into())?; state.add_trait_path_type_param(quote! { #index_type }); let SingleFieldData { field, diff --git a/impl/src/into_iterator.rs b/impl/src/into_iterator.rs index 346147c7..f10dbf7a 100644 --- a/impl/src/into_iterator.rs +++ b/impl/src/into_iterator.rs @@ -7,12 +7,8 @@ use syn::{parse::Result, DeriveInput}; /// Provides the hook to expand `#[derive(IntoIterator)]` into an implementation of `IntoIterator` pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { - let state = State::with_field_ignore_and_refs( - input, - trait_name, - quote! { ::core::iter }, - "into_iterator".into(), - )?; + let state = + State::with_field_ignore_and_refs(input, trait_name, "into_iterator".into())?; let SingleFieldData { input_type, info, diff --git a/impl/src/is_variant.rs b/impl/src/is_variant.rs index b6c074fc..123e3fb7 100644 --- a/impl/src/is_variant.rs +++ b/impl/src/is_variant.rs @@ -8,7 +8,6 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result Result Result Result { - let state = State::new( - input, - trait_name, - quote! { ::core::iter }, - trait_name.to_lowercase(), - )?; + let state = State::new(input, trait_name, trait_name.to_lowercase())?; let multi_field_data = state.enabled_fields_data(); let MultiFieldData { input_type, diff --git a/impl/src/try_into.rs b/impl/src/try_into.rs index c978fe30..f3066c1d 100644 --- a/impl/src/try_into.rs +++ b/impl/src/try_into.rs @@ -14,7 +14,6 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result Result Result { pub trait_name: &'static str, pub trait_ident: Ident, pub method_ident: Ident, - pub trait_module: TokenStream, pub trait_path: TokenStream, pub trait_path_params: Vec, pub trait_attr: String, @@ -314,29 +313,19 @@ impl<'input> State<'input> { pub fn new<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, ) -> Result> { - State::new_impl( - input, - trait_name, - trait_module, - trait_attr, - AttrParams::default(), - true, - ) + State::new_impl(input, trait_name, trait_attr, AttrParams::default(), true) } pub fn with_field_ignore<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, ) -> Result> { State::new_impl( input, trait_name, - trait_module, trait_attr, AttrParams::new(vec!["ignore"]), true, @@ -346,13 +335,11 @@ impl<'input> State<'input> { pub fn with_field_ignore_and_forward<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, ) -> Result> { State::new_impl( input, trait_name, - trait_module, trait_attr, AttrParams::new(vec!["ignore", "forward"]), true, @@ -362,13 +349,11 @@ impl<'input> State<'input> { pub fn with_field_ignore_and_refs<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, ) -> Result> { State::new_impl( input, trait_name, - trait_module, trait_attr, AttrParams::new(vec!["ignore", "owned", "ref", "ref_mut"]), true, @@ -378,24 +363,15 @@ impl<'input> State<'input> { pub fn with_attr_params<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, allowed_attr_params: AttrParams, ) -> Result> { - State::new_impl( - input, - trait_name, - trait_module, - trait_attr, - allowed_attr_params, - true, - ) + State::new_impl(input, trait_name, trait_attr, allowed_attr_params, true) } pub fn with_type_bound<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, allowed_attr_params: AttrParams, add_type_bound: bool, @@ -403,7 +379,6 @@ impl<'input> State<'input> { Self::new_impl( input, trait_name, - trait_module, trait_attr, allowed_attr_params, add_type_bound, @@ -413,7 +388,6 @@ impl<'input> State<'input> { fn new_impl<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, allowed_attr_params: AttrParams, add_type_bound: bool, @@ -421,7 +395,7 @@ impl<'input> State<'input> { let trait_name = trait_name.trim_end_matches("ToInner"); let trait_ident = format_ident!("{trait_name}"); let method_ident = format_ident!("{trait_attr}"); - let trait_path = quote! { #trait_module::#trait_ident }; + let trait_path = quote! { ::derive_more::#trait_ident }; let (derive_type, fields, variants): (_, Vec<_>, Vec<_>) = match input.data { Data::Struct(ref data_struct) => match data_struct.fields { Fields::Unnamed(ref fields) => { @@ -516,7 +490,6 @@ impl<'input> State<'input> { State::from_variant( input, trait_name, - trait_module.clone(), trait_attr.clone(), allowed_attr_params.clone(), variant, @@ -539,7 +512,6 @@ impl<'input> State<'input> { trait_name, trait_ident, method_ident, - trait_module, trait_path, trait_path_params: vec![], trait_attr, @@ -558,7 +530,6 @@ impl<'input> State<'input> { pub fn from_variant<'arg_input>( input: &'arg_input DeriveInput, trait_name: &'static str, - trait_module: TokenStream, trait_attr: String, allowed_attr_params: AttrParams, variant: &'arg_input Variant, @@ -567,7 +538,7 @@ impl<'input> State<'input> { let trait_name = trait_name.trim_end_matches("ToInner"); let trait_ident = format_ident!("{trait_name}"); let method_ident = format_ident!("{trait_attr}"); - let trait_path = quote! { #trait_module::#trait_ident }; + let trait_path = quote! { ::derive_more::#trait_ident }; let (derive_type, fields): (_, Vec<_>) = match variant.fields { Fields::Unnamed(ref fields) => { (DeriveType::Unnamed, unnamed_to_vec(fields)) @@ -593,7 +564,6 @@ impl<'input> State<'input> { Ok(State { input, trait_name, - trait_module, trait_path, trait_path_params: vec![], trait_attr, diff --git a/src/fmt.rs b/src/fmt.rs index 311bfb77..0acd4ca2 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -1,7 +1,9 @@ //! [`core::fmt::DebugTuple`] reimplementation with //! [`DebugTuple::finish_non_exhaustive()`] method. +use ::core; use core::fmt::{Debug, Formatter, Result, Write}; +use core::prelude::v1::*; /// Same as [`core::fmt::DebugTuple`], but with /// [`DebugTuple::finish_non_exhaustive()`] method. diff --git a/src/lib.rs b/src/lib.rs index 19b642a8..57d677b4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,52 +47,232 @@ #![forbid(non_ascii_idents, unsafe_code)] #![warn(clippy::nonstandard_macro_braces)] +// Not public, but exported API. For macro expansion internals only. +#[doc(hidden)] +pub mod __private { + #[cfg(feature = "debug")] + pub use crate::fmt::{debug_tuple, DebugTuple}; + + #[cfg(feature = "error")] + pub use crate::vendor::thiserror::aserror::AsDynError; +} + +// The modules containing error types and other helpers +#[cfg(any(feature = "add", feature = "not"))] +pub mod ops; + +#[cfg(feature = "debug")] +mod fmt; + +#[cfg(feature = "error")] +mod vendor; + +#[cfg(feature = "from_str")] +mod r#str; +#[cfg(feature = "from_str")] #[doc(inline)] -pub use derive_more_impl::*; +pub use crate::r#str::FromStrError; #[cfg(feature = "try_into")] mod convert; #[cfg(feature = "try_into")] -pub use self::convert::TryIntoError; +#[doc(inline)] +pub use crate::convert::TryIntoError; #[cfg(feature = "try_unwrap")] mod try_unwrap; #[cfg(feature = "try_unwrap")] +#[doc(inline)] pub use self::try_unwrap::TryUnwrapError; +// When re-exporting traits from std we need to do a pretty crazy trick, because we ONLY want +// to re-export the traits and not derives that are called the same in the std module, +// because those would conflict with our own. The way we do this is by first importing both +// the trait and possible derive into a separate module and re-export them. Then we wildcard import +// all the things from that module into the main module, but we also import our own derive by its +// exact name. Due to the way wildcard imports work in rust, that results in our own derive taking +// precedence over any derive from std. For some reason the named re-export of our own derive +// cannot be in in this (or really any) macro too. It will somehow still consider it a wildcard +// then and will result in this warning ambiguous_glob_reexports, and not actually exporting of our +// derive. +macro_rules! re_export_traits(( + $feature:literal, $new_module_name:ident, $module:path $(, $traits:ident)* $(,)?) => { + #[cfg(feature = $feature)] + mod $new_module_name { + pub use $module::{$($traits),*}; + } + + #[cfg(feature = $feature)] + #[doc(hidden)] + pub use crate::$new_module_name::*; + + } +); + +re_export_traits!( + "add", + add_traits, + core::ops, + Add, + BitAnd, + BitOr, + BitXor, + Sub, +); +re_export_traits!( + "add_assign", + add_assign_traits, + core::ops, + AddAssign, + BitAndAssign, + BitOrAssign, + BitXorAssign, + SubAssign, +); +re_export_traits!("as_mut", as_mut_traits, core::convert, AsMut); +re_export_traits!("as_ref", as_ref_traits, core::convert, AsRef); +re_export_traits!("debug", debug_traits, core::fmt, Debug); +re_export_traits!("deref", deref_traits, core::ops, Deref); +re_export_traits!("deref_mut", deref_mut_traits, core::ops, DerefMut); +re_export_traits!( + "display", + display_traits, + core::fmt, + Binary, + Display, + LowerExp, + LowerHex, + Octal, + Pointer, + UpperExp, + UpperHex, +); + +#[cfg(not(feature = "std"))] +re_export_traits!("error", error_traits, core::error, Error); +#[cfg(feature = "std")] +re_export_traits!("error", error_traits, std::error, Error); + +re_export_traits!("from", from_traits, core::convert, From); + +re_export_traits!("from_str", from_str_traits, core::str, FromStr); + +re_export_traits!("index", index_traits, core::ops, Index); + +re_export_traits!("index_mut", index_mut_traits, core::ops, IndexMut); + +re_export_traits!("into", into_traits, core::convert, Into); + +re_export_traits!( + "into_iterator", + into_iterator_traits, + core::iter, + IntoIterator, +); + +re_export_traits!("mul", mul_traits, core::ops, Div, Mul, Rem, Shl, Shr); + +#[cfg(feature = "mul_assign")] +re_export_traits!( + "mul_assign", + mul_assign_traits, + core::ops, + DivAssign, + MulAssign, + RemAssign, + ShlAssign, + ShrAssign, +); + +re_export_traits!("not", not_traits, core::ops, Neg, Not); + +re_export_traits!("sum", sum_traits, core::iter, Product, Sum); + +re_export_traits!("try_into", try_into_traits, core::convert, TryInto); + +// Now re-export our own derives by their exact name to overwrite any derives that the trait +// re-exporting might inadvertently pull into scope. +#[cfg(feature = "add")] +pub use derive_more_impl::{Add, BitAnd, BitOr, BitXor, Sub}; + +#[cfg(feature = "add_assign")] +pub use derive_more_impl::{ + AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign, +}; + +#[cfg(feature = "as_mut")] +pub use derive_more_impl::AsMut; + +#[cfg(feature = "as_ref")] +pub use derive_more_impl::AsRef; + +#[cfg(feature = "constructor")] +pub use derive_more_impl::Constructor; + #[cfg(feature = "debug")] -mod fmt; +pub use derive_more_impl::Debug; -#[cfg(any(feature = "add", feature = "not"))] -pub mod ops; +#[cfg(feature = "deref")] +pub use derive_more_impl::Deref; -#[cfg(feature = "from_str")] -mod r#str; -#[cfg(feature = "from_str")] -pub use self::r#str::FromStrError; +#[cfg(feature = "deref_mut")] +pub use derive_more_impl::DerefMut; + +#[cfg(feature = "display")] +pub use derive_more_impl::{ + Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, +}; #[cfg(feature = "error")] -mod vendor; +pub use derive_more_impl::Error; -// Not public API. -#[doc(hidden)] -pub mod __private { - #[cfg(all(feature = "error", not(feature = "std")))] - pub use ::core::error::Error; - #[cfg(all(feature = "error", feature = "std"))] - pub use ::std::error::Error; +#[cfg(feature = "from")] +pub use derive_more_impl::From; - #[cfg(feature = "error")] - pub use crate::vendor::thiserror::aserror::AsDynError; +#[cfg(feature = "from_str")] +pub use derive_more_impl::FromStr; - #[cfg(feature = "debug")] - pub use crate::fmt::{debug_tuple, DebugTuple}; -} +#[cfg(feature = "index")] +pub use derive_more_impl::Index; + +#[cfg(feature = "index_mut")] +pub use derive_more_impl::IndexMut; + +#[cfg(feature = "into")] +pub use derive_more_impl::Into; + +#[cfg(feature = "into_iterator")] +pub use derive_more_impl::IntoIterator; + +#[cfg(feature = "is_variant")] +pub use derive_more_impl::IsVariant; +#[cfg(feature = "mul")] +pub use derive_more_impl::{Div, Mul, Rem, Shl, Shr}; + +#[cfg(feature = "mul_assign")] +pub use derive_more_impl::{DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign}; + +#[cfg(feature = "not")] +pub use derive_more_impl::{Neg, Not}; + +#[cfg(feature = "sum")] +pub use derive_more_impl::{Product, Sum}; + +#[cfg(feature = "try_into")] +pub use derive_more_impl::TryInto; + +#[cfg(feature = "try_unwrap")] +pub use derive_more_impl::TryUnwrap; + +#[cfg(feature = "unwrap")] +pub use derive_more_impl::Unwrap; + +// Check if any feature is enabled #[cfg(not(any( feature = "full", - feature = "add_assign", feature = "add", + feature = "add_assign", feature = "as_mut", feature = "as_ref", feature = "constructor", @@ -108,14 +288,13 @@ pub mod __private { feature = "into", feature = "into_iterator", feature = "is_variant", - feature = "iterator", - feature = "mul_assign", feature = "mul", + feature = "mul_assign", feature = "not", feature = "sum", feature = "try_into", - feature = "unwrap", feature = "try_unwrap", + feature = "unwrap", )))] compile_error!( "at least one derive feature must be enabled (or the \"full\" one enabling all the derives)" diff --git a/tests/display.rs b/tests/display.rs index 8683c8c3..cab2c047 100644 --- a/tests/display.rs +++ b/tests/display.rs @@ -11,7 +11,6 @@ use alloc::{ string::{String, ToString}, vec::Vec, }; -use core::fmt::{Binary, Display}; use derive_more::{Binary, Display, Octal, UpperHex}; diff --git a/tests/error/mod.rs b/tests/error/mod.rs index a041ec17..352d40aa 100644 --- a/tests/error/mod.rs +++ b/tests/error/mod.rs @@ -1,8 +1,3 @@ -#[cfg(not(feature = "std"))] -use core::error::Error; -#[cfg(feature = "std")] -use std::error::Error; - use derive_more::Error; /// Derives `std::fmt::Display` for structs/enums.