derive_more/
lib.rs

1// These links overwrite the ones in `README.md`
2// to become proper intra-doc links in Rust docs.
3//! [`From`]: macro@crate::From
4//! [`Into`]: macro@crate::Into
5//! [`FromStr`]: macro@crate::FromStr
6//! [`TryFrom`]: macro@crate::TryFrom
7//! [`TryInto`]: macro@crate::TryInto
8//! [`IntoIterator`]: macro@crate::IntoIterator
9//! [`AsRef`]: macro@crate::AsRef
10//!
11//! [`Debug`]: macro@crate::Debug
12//! [`Display`-like]: macro@crate::Display
13//!
14//! [`Error`]: macro@crate::Error
15//!
16//! [`Index`]: macro@crate::Index
17//! [`Deref`]: macro@crate::Deref
18//! [`Not`-like]: macro@crate::Not
19//! [`Add`-like]: macro@crate::Add
20//! [`Mul`-like]: macro@crate::Mul
21//! [`Sum`-like]: macro@crate::Sum
22//! [`IndexMut`]: macro@crate::IndexMut
23//! [`DerefMut`]: macro@crate::DerefMut
24//! [`AddAssign`-like]: macro@crate::AddAssign
25//! [`MulAssign`-like]: macro@crate::MulAssign
26//! [`Eq`]: macro@crate::Eq
27//! [`PartialEq`]: macro@crate::PartialEq
28//!
29//! [`Constructor`]: macro@crate::Constructor
30//! [`IsVariant`]: macro@crate::IsVariant
31//! [`Unwrap`]: macro@crate::Unwrap
32//! [`TryUnwrap`]: macro@crate::TryUnwrap
33
34// The README includes doctests requiring these features. To make sure that
35// tests pass when not all features are provided we exclude it when the
36// required features are not available.
37#![cfg_attr(
38    all(
39        feature = "add",
40        feature = "display",
41        feature = "from",
42        feature = "into"
43    ),
44    doc = core::include_str!("../README.md")
45)]
46#![cfg_attr(not(feature = "std"), no_std)]
47#![cfg_attr(docsrs, feature(doc_cfg))]
48#![cfg_attr(any(not(docsrs), ci), deny(rustdoc::all))]
49#![forbid(non_ascii_idents, unsafe_code)]
50#![warn(clippy::nonstandard_macro_braces)]
51
52// For macro expansion internals only.
53// Ensures better hygiene in case a local crate `core` is present in workspace of the user code,
54// or some other crate is renamed as `core`.
55#[doc(hidden)]
56pub use core;
57
58// Not public, but exported API. For macro expansion internals only.
59#[doc(hidden)]
60pub mod __private {
61    #[cfg(feature = "as_ref")]
62    pub use crate::r#as::{Conv, ExtractRef};
63
64    #[cfg(feature = "debug")]
65    pub use crate::fmt::{debug_tuple, DebugTuple};
66
67    #[cfg(feature = "eq")]
68    pub use crate::cmp::AssertParamIsEq;
69
70    #[cfg(feature = "error")]
71    pub use crate::vendor::thiserror::aserror::AsDynError;
72}
73
74// The modules containing error types and other helpers.
75
76#[cfg(any(feature = "add", feature = "mul"))]
77mod add;
78#[cfg(any(feature = "add", feature = "mul"))]
79pub use crate::add::{BinaryError, WrongVariantError};
80
81#[cfg(feature = "eq")]
82mod cmp;
83
84#[cfg(any(feature = "add", feature = "not", feature = "mul"))]
85mod ops;
86#[cfg(any(feature = "add", feature = "not", feature = "mul"))]
87pub use crate::ops::UnitError;
88
89#[cfg(feature = "as_ref")]
90mod r#as;
91
92#[cfg(feature = "debug")]
93mod fmt;
94
95#[cfg(feature = "error")]
96mod vendor;
97
98#[cfg(feature = "from_str")]
99mod r#str;
100#[cfg(feature = "from_str")]
101#[doc(inline)]
102pub use crate::r#str::FromStrError;
103
104#[cfg(any(feature = "try_into", feature = "try_from"))]
105mod convert;
106#[cfg(feature = "try_from")]
107#[doc(inline)]
108pub use crate::convert::TryFromReprError;
109#[cfg(feature = "try_into")]
110#[doc(inline)]
111pub use crate::convert::TryIntoError;
112
113#[cfg(feature = "try_unwrap")]
114mod try_unwrap;
115#[cfg(feature = "try_unwrap")]
116#[doc(inline)]
117pub use crate::try_unwrap::TryUnwrapError;
118
119// This can be unused if no feature is enabled. We already error in that case, but this warning
120// distracts from that error. So we suppress the warning.
121#[allow(unused_imports)]
122#[doc(inline)]
123pub use derive_more_impl::*;
124
125/// Module containing derive definitions only, without their corresponding traits.
126///
127/// Use it in your import paths, if you don't want to import traits, but only macros.
128pub mod derive {
129    // This can be unused if no feature is enabled. We already error in that case, but this warning
130    // distracts from that error. So we suppress the warning.
131    #[allow(unused_imports)]
132    #[doc(inline)]
133    pub use derive_more_impl::*;
134}
135
136/// Module containing derive definitions with their corresponding traits along.
137///
138/// Use it in your import paths, if you do want to import derives along with their traits.
139pub mod with_trait {
140    // When re-exporting traits from `std` we need to do a pretty crazy trick, because we ONLY want
141    // to re-export the traits and not derives that are called the same in the `std` module, because
142    // those would conflict with our own ones. The way we do this is by first importing both the
143    // trait and possible derive into a separate module and re-export them. Then, we wildcard-import
144    // all the things from that module into the main module, but we also import our own derive by
145    // its exact name. Due to the way wildcard imports work in Rust, that results in our own derive
146    // taking precedence over any derive from `std`. For some reason the named re-export of our own
147    // derive cannot be in this (or really any) macro too. It will somehow still consider it a
148    // wildcard then and will result in this warning `ambiguous_glob_reexports`, and not actually
149    // exporting of our derive.
150    macro_rules! re_export_traits((
151        $feature:literal, $new_module_name:ident, $module:path $(, $traits:ident)* $(,)?) => {
152            #[cfg(all(feature = $feature, any(not(docsrs), ci)))]
153            mod $new_module_name {
154                #[doc(hidden)]
155                pub use $module::{$($traits),*};
156            }
157
158            #[cfg(all(feature = $feature, any(not(docsrs), ci)))]
159            #[doc(hidden)]
160            pub use crate::with_trait::all_traits_and_derives::$new_module_name::*;
161        }
162    );
163
164    mod all_traits_and_derives {
165        re_export_traits!(
166            "add",
167            add_traits,
168            core::ops,
169            Add,
170            BitAnd,
171            BitOr,
172            BitXor,
173            Sub,
174        );
175        re_export_traits!(
176            "add_assign",
177            add_assign_traits,
178            core::ops,
179            AddAssign,
180            BitAndAssign,
181            BitOrAssign,
182            BitXorAssign,
183            SubAssign,
184        );
185        re_export_traits!("as_ref", as_ref_traits, core::convert, AsMut, AsRef);
186        re_export_traits!("debug", debug_traits, core::fmt, Debug);
187        re_export_traits!("deref", deref_traits, core::ops, Deref);
188        re_export_traits!("deref_mut", deref_mut_traits, core::ops, DerefMut);
189        re_export_traits!(
190            "display",
191            display_traits,
192            core::fmt,
193            Binary,
194            Display,
195            LowerExp,
196            LowerHex,
197            Octal,
198            Pointer,
199            UpperExp,
200            UpperHex,
201        );
202
203        re_export_traits!("eq", eq_traits, core::cmp, Eq, PartialEq);
204
205        re_export_traits!("error", error_traits, core::error, Error);
206
207        re_export_traits!("from", from_traits, core::convert, From);
208
209        re_export_traits!("from_str", from_str_traits, core::str, FromStr);
210
211        re_export_traits!("index", index_traits, core::ops, Index);
212
213        re_export_traits!("index_mut", index_mut_traits, core::ops, IndexMut);
214
215        re_export_traits!("into", into_traits, core::convert, Into);
216
217        re_export_traits!(
218            "into_iterator",
219            into_iterator_traits,
220            core::iter,
221            IntoIterator,
222        );
223
224        re_export_traits!("mul", mul_traits, core::ops, Div, Mul, Rem, Shl, Shr);
225
226        #[cfg(feature = "mul_assign")]
227        re_export_traits!(
228            "mul_assign",
229            mul_assign_traits,
230            core::ops,
231            DivAssign,
232            MulAssign,
233            RemAssign,
234            ShlAssign,
235            ShrAssign,
236        );
237
238        re_export_traits!("not", not_traits, core::ops, Neg, Not);
239
240        re_export_traits!("sum", sum_traits, core::iter, Product, Sum);
241
242        re_export_traits!("try_from", try_from_traits, core::convert, TryFrom);
243
244        re_export_traits!("try_into", try_into_traits, core::convert, TryInto);
245
246        // Now re-export our own derives by their exact name to overwrite any derives that the trait
247        // re-exporting might inadvertently pull into scope.
248        #[cfg(feature = "add")]
249        pub use derive_more_impl::{Add, BitAnd, BitOr, BitXor, Sub};
250
251        #[cfg(feature = "add_assign")]
252        pub use derive_more_impl::{
253            AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign,
254        };
255
256        #[cfg(feature = "as_ref")]
257        pub use derive_more_impl::{AsMut, AsRef};
258
259        #[cfg(feature = "constructor")]
260        pub use derive_more_impl::Constructor;
261
262        #[cfg(feature = "debug")]
263        pub use derive_more_impl::Debug;
264
265        #[cfg(feature = "deref")]
266        pub use derive_more_impl::Deref;
267
268        #[cfg(feature = "deref_mut")]
269        pub use derive_more_impl::DerefMut;
270
271        #[cfg(feature = "display")]
272        pub use derive_more_impl::{
273            Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex,
274        };
275
276        #[cfg(feature = "error")]
277        pub use derive_more_impl::Error;
278
279        #[cfg(feature = "eq")]
280        pub use derive_more_impl::{Eq, PartialEq};
281
282        #[cfg(feature = "from")]
283        pub use derive_more_impl::From;
284
285        #[cfg(feature = "from_str")]
286        pub use derive_more_impl::FromStr;
287
288        #[cfg(feature = "index")]
289        pub use derive_more_impl::Index;
290
291        #[cfg(feature = "index_mut")]
292        pub use derive_more_impl::IndexMut;
293
294        #[cfg(feature = "into")]
295        pub use derive_more_impl::Into;
296
297        #[cfg(feature = "into_iterator")]
298        pub use derive_more_impl::IntoIterator;
299
300        #[cfg(feature = "is_variant")]
301        pub use derive_more_impl::IsVariant;
302
303        #[cfg(feature = "mul")]
304        pub use derive_more_impl::{Div, Mul, Rem, Shl, Shr};
305
306        #[cfg(feature = "mul_assign")]
307        pub use derive_more_impl::{
308            DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign,
309        };
310
311        #[cfg(feature = "not")]
312        pub use derive_more_impl::{Neg, Not};
313
314        #[cfg(feature = "sum")]
315        pub use derive_more_impl::{Product, Sum};
316
317        #[cfg(feature = "try_from")]
318        pub use derive_more_impl::TryFrom;
319
320        #[cfg(feature = "try_into")]
321        pub use derive_more_impl::TryInto;
322
323        #[cfg(feature = "try_unwrap")]
324        pub use derive_more_impl::TryUnwrap;
325
326        #[cfg(feature = "unwrap")]
327        pub use derive_more_impl::Unwrap;
328    }
329
330    // Now re-export our own derives and the std traits by their exact name to make rust-analyzer
331    // recognize the #[doc(hidden)] flag.
332    // See issues:
333    // 1. https://github.com/rust-lang/rust-analyzer/issues/11698
334    // 2. https://github.com/rust-lang/rust-analyzer/issues/14079
335    #[cfg(feature = "add")]
336    #[doc(hidden)]
337    pub use all_traits_and_derives::{Add, BitAnd, BitOr, BitXor, Sub};
338
339    #[cfg(feature = "add_assign")]
340    #[doc(hidden)]
341    pub use all_traits_and_derives::{
342        AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign,
343    };
344
345    #[cfg(feature = "as_ref")]
346    #[doc(hidden)]
347    pub use all_traits_and_derives::{AsMut, AsRef};
348
349    #[cfg(feature = "constructor")]
350    #[doc(hidden)]
351    pub use all_traits_and_derives::Constructor;
352
353    #[cfg(feature = "debug")]
354    #[doc(hidden)]
355    pub use all_traits_and_derives::Debug;
356
357    #[cfg(feature = "deref")]
358    #[doc(hidden)]
359    pub use all_traits_and_derives::Deref;
360
361    #[cfg(feature = "deref_mut")]
362    #[doc(hidden)]
363    pub use all_traits_and_derives::DerefMut;
364
365    #[cfg(feature = "display")]
366    #[doc(hidden)]
367    pub use all_traits_and_derives::{
368        Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex,
369    };
370
371    #[cfg(feature = "eq")]
372    #[doc(hidden)]
373    pub use all_traits_and_derives::{Eq, PartialEq};
374
375    #[cfg(feature = "error")]
376    #[doc(hidden)]
377    pub use all_traits_and_derives::Error;
378
379    #[cfg(feature = "from")]
380    #[doc(hidden)]
381    pub use all_traits_and_derives::From;
382
383    #[cfg(feature = "from_str")]
384    #[doc(hidden)]
385    pub use all_traits_and_derives::FromStr;
386
387    #[cfg(feature = "index")]
388    #[doc(hidden)]
389    pub use all_traits_and_derives::Index;
390
391    #[cfg(feature = "index_mut")]
392    #[doc(hidden)]
393    pub use all_traits_and_derives::IndexMut;
394
395    #[cfg(feature = "into")]
396    #[doc(hidden)]
397    pub use all_traits_and_derives::Into;
398
399    #[cfg(feature = "into_iterator")]
400    #[doc(hidden)]
401    pub use all_traits_and_derives::IntoIterator;
402
403    #[cfg(feature = "is_variant")]
404    #[doc(hidden)]
405    pub use all_traits_and_derives::IsVariant;
406
407    #[cfg(feature = "mul")]
408    #[doc(hidden)]
409    pub use all_traits_and_derives::{Div, Mul, Rem, Shl, Shr};
410
411    #[cfg(feature = "mul_assign")]
412    #[doc(hidden)]
413    pub use all_traits_and_derives::{
414        DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign,
415    };
416
417    #[cfg(feature = "not")]
418    #[doc(hidden)]
419    pub use all_traits_and_derives::{Neg, Not};
420
421    #[cfg(feature = "sum")]
422    #[doc(hidden)]
423    pub use all_traits_and_derives::{Product, Sum};
424
425    #[cfg(feature = "try_from")]
426    #[doc(hidden)]
427    pub use all_traits_and_derives::TryFrom;
428
429    #[cfg(feature = "try_into")]
430    #[doc(hidden)]
431    pub use all_traits_and_derives::TryInto;
432
433    #[cfg(feature = "try_unwrap")]
434    #[doc(hidden)]
435    pub use all_traits_and_derives::TryUnwrap;
436
437    #[cfg(feature = "unwrap")]
438    #[doc(hidden)]
439    pub use all_traits_and_derives::Unwrap;
440
441    // Re-export the derive macros again to show docs for our derives (but not for traits). This is
442    // done using a glob import to not hit E0252.
443    #[allow(unused_imports)]
444    pub use derive_more_impl::*;
445}
446
447// Check if any feature is enabled
448#[cfg(not(any(
449    feature = "full",
450    feature = "add",
451    feature = "add_assign",
452    feature = "as_ref",
453    feature = "constructor",
454    feature = "debug",
455    feature = "deref",
456    feature = "deref_mut",
457    feature = "display",
458    feature = "eq",
459    feature = "error",
460    feature = "from",
461    feature = "from_str",
462    feature = "index",
463    feature = "index_mut",
464    feature = "into",
465    feature = "into_iterator",
466    feature = "is_variant",
467    feature = "mul",
468    feature = "mul_assign",
469    feature = "not",
470    feature = "sum",
471    feature = "try_from",
472    feature = "try_into",
473    feature = "try_unwrap",
474    feature = "unwrap",
475)))]
476compile_error!(
477    "at least one derive feature must be enabled (or the \"full\" feature enabling all the derives)"
478);