derive_more-1.0.0/.cargo_vcs_info.json0000644000000001360000000000100133320ustar { "git": { "sha1": "d7f5b9e94d024790682f6fc4dcca13941cce64c8" }, "path_in_vcs": "" }derive_more-1.0.0/CHANGELOG.md000064400000000000000000000322711046102023000137400ustar 00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## 1.0.1 - Unreleased ## 1.0.0 - 2024-08-07 More than 8 years after the first commit and almost 5 years after the 0.99.0 release, `derive_more` has finally reached its 1.0.0 release. This release contains a lot of changes (including some breaking ones) to make it easier to use the derives and make it possible to extend them without having to breaking backwards compatibility again. There are five major changes that I would like to call out, but there are many more changes that are documented below: 1. There is a new `Debug` derive that can be used to easily customize `Debug` formatting. 2. A greatly improved `Display` derive, which allows you to do anything that [`thiserror`](https://github.com/dtolnay/thiserror) provides, but it works for any type not just errors. And by combining the `Display` derive with the `Error` and `From` derives, there shouldn't really be any need to use `thiserror` anymore (if you are missing a feature/behaviour from `thiserror` please report an issue). 3. Traits that can return errors now return a type that implements `Error` when an error occurs instead of a `&'static str`. 4. When using `use derive_more::SomeTrait` the actual trait is also imported not just the derive macro. This is especially useful for `Error` and `Display` 5. The docs are now rendered on docs.rs and are much better overall. ### Breaking changes - The minimum supported Rust version (MSRV) is now Rust 1.75. - Add the `std` feature which should be disabled in `no_std` environments. - All Cargo features, except `std`, are now disabled by default. The `full` feature can be used to get the old behavior of supporting all possible derives. - The `TryFrom`, `Add`, `Sub`, `BitAnd`, `BitOr`, `BitXor`, `Not` and `Neg` derives now return a dedicated error type instead of a `&'static str` on error. - The `FromStr` derive now uses a dedicated `FromStrError` error type instead of generating unique one each time. - The `Display` derive (and other `fmt`-like ones) now uses `#[display("...", (),*)]` syntax instead of `#[display(fmt = "...", (""),*)]`, and `#[display(bound())]` instead of `#[display(bound = "")]`. So without the double quotes around the expressions and bounds. - The `Debug` and `Display` derives (and other `fmt`-like ones) now transparently delegate to the inner type when `#[display("...", (),*)]` attribute is trivially substitutable with a transparent call. ([#322](https://github.com/JelteF/derive_more/pull/322)) - The `DebugCustom` derive is renamed to just `Debug` (gated now under a separate `debug` feature), and its semantics were changed to be a superset of `std` variant of `Debug`. - The `From` derive doesn't derive `From<()>` for enum variants without any fields anymore. This feature was removed because it was considered useless in practice. - The `From` derive now uses `#[from()]` instead of `#[from(types())]` and ignores field type itself. - The `Into` derive now uses `#[into()]` instead of `#[into(types())]` and ignores field type itself. - The `Into` derive now generates separate impls for each field whenever the `#[into(...)]` attribute is applied to it. ([#291](https://github.com/JelteF/derive_more/pull/291)) - Importing a derive macro now also imports its corresponding trait. - The `Error` derive is updated with changes to the `error_generic_member_access` unstable feature for nightly users. ([#200](https://github.com/JelteF/derive_more/pull/200), [#294](https://github.com/JelteF/derive_more/pull/294)) - The `as_mut` feature is removed, and the `AsMut` derive is now gated by the `as_ref` feature. ([#295](https://github.com/JelteF/derive_more/pull/295)) - A top level `#[display("...")]` attribute on an enum now requires the usage of `{_variant}` to include the variant instead of including it at `{}`. The reason is that `{}` now references the first argument to the format string, just like in all other format strings. ([#377](https://github.com/JelteF/derive_more/pull/377)) ### Added - Add support captured identifiers in `Display` derives. So now you can use: `#[display(fmt = "Prefix: {field}")]` instead of needing to use `#[display(fmt = "Prefix: {}", field)]` - Add `FromStr` derive support for enums that contain variants without fields. If you pass the name of the variant to `from_str` it will create the matching variant. - Add `#[unwrap(owned, ref, ref_mut)]` attribute for the `Unwrap` derive. By using them, it is possible to derive implementations for the reference types as well. ([#206](https://github.com/JelteF/derive_more/pull/206)) - Add `TryUnwrap` derive similar to the `Unwrap` derive. This one returns a `Result` and does not panic. ([#206](https://github.com/JelteF/derive_more/pull/206)) - Add support for container format in `Debug` derive with the same syntax as `Display` derives. ([#279](https://github.com/JelteF/derive_more/pull/279)) - `derive_more::derive` module exporting only macros, without traits. ([#290](https://github.com/JelteF/derive_more/pull/290)) - Add support for specifying concrete types to `AsRef`/`AsMut` derives. ([#298](https://github.com/JelteF/derive_more/pull/298)) - Add `TryFrom` derive for enums to convert from their discriminant. ([#300](https://github.com/JelteF/derive_more/pull/300)) - `#[inline]` attributes to `IsVariant` and `Debug` implementations. ([#334](https://github.com/JelteF/derive_more/pull/334) - Add `#[track_caller]` to `Add`, `Mul`, `AddAssign` and `MulAssign` derives ([#378](https://github.com/JelteF/derive_more/pull/378) ### Changed - The `Constructor` and `IsVariant` derives now generate `const fn` functions. - Static methods derived by `IsVariant` are now marked `#[must_use]`. ([#350](https://github.com/JelteF/derive_more/pull/350)) - The `Unwrap` and `IsVariant` derives now generate doc comments. - `#[automatically_derived]` is now emitted from all macro expansions. This should prevent code style linters from attempting to modify the generated code. - Upgrade to `syn` 2.0. - The `Error` derive now works in nightly `no_std` environments ### Fixed - Use a deterministic `HashSet` in all derives, this is needed for rust analyzer to work correctly. - Use `Provider` API for backtraces in `Error` derive. - Fix `Error` derive not working with `const` generics. - Support trait objects for source in Error, e.g. `Box` - Fix bounds on derived `IntoIterator` impls for generic structs. ([#284](https://github.com/JelteF/derive_more/pull/284)) - Fix documentation of generated bounds in `Display` derive. ([#297](https://github.com/JelteF/derive_more/pull/297)) - Hygiene of macro expansions in presence of custom `core` crate. ([#327](https://github.com/JelteF/derive_more/pull/327)) - Fix documentation of generated methods in `IsVariant` derive. - Make `{field:p}` do the expected thing in format strings for `Display` and `Debug`. Also document weirdness around `Pointer` formatting when using expressions, due to field variables being references. ([#381](https://github.com/JelteF/derive_more/pull/381)) ## 0.99.10 - 2020-09-11 ### Added - `From` supports additional types for conversion: `#[from(types(u8, u16))]`. ## 0.99.7 - 2020-05-16 ### Changed - When specifying specific features of the crate to only enable specific derives, the `extra-traits` feature of `syn` is not always enabled when those the specified features do not require it. This should speed up compile time of `syn` when this feature is not needed. ### Fixed - Fix generic derives for `MulAssign` ## 0.99.6 - 2020-05-13 ### Changed - Make sure output of derives is deterministic, for better support in rust-analyzer ## 0.99.5 - 2020-03-28 ### Added - Support for deriving `Error`!!! (many thanks to @ffuugoo and @tyranron) ### Fixed - Fix generic bounds for `Deref` and `DerefMut` with `forward`, i.e. put `Deref` bound on whole type, so on `where Box: Deref` instead of on `T: Deref`. ([#107](https://github.com/JelteF/derive_more/issues/114)) - The `tests` directory is now correctly included in the crate (requested by Debian package maintainers) ## 0.99.4 - 2020-03-28 [YANKED] Note: This version is yanked, because quickly after release it was found out tests did not run in CI. ## 0.99.3 - 2020-02-19 ### Fixed - Fix generic bounds for `Deref` and `DerefMut` with no `forward`, i.e. no bounds are necessary. ([#107](https://github.com/JelteF/derive_more/issues/114)) ## 0.99.2 - 2019-11-17 ### Fixed - Hotfix for a regression in allowed `Display` derives using `#` flag, such as `{:#b}` ([#107](https://github.com/JelteF/derive_more/issues/107)) ## 0.99.1 - 2019-11-12 ### Fixed - Hotfix for a regression in allowed `From` derives ([#105](https://github.com/JelteF/derive_more/issues/105)) ## 0.99.0 - 2019-11-11 This release is a huge milestone for this library. Lot's of new derives are implemented and a ton of attributes are added for configuration purposes. These attributes will allow future releases to add features/options without breaking backwards compatibility. This is why the next release with breaking changes is planned to be 1.0.0. ### Breaking changes - The minimum supported rust version (MSRV) is now Rust 1.36. - When using in a Rust 2015 crate, you should add `extern crate core` to your code. - `no_std` feature is removed, the library now supports `no_std` without having to configure any features. ### Added - `Deref` derives now dereference to the type in the newtype. So if you have `MyBox(Box)`, dereferencing it will result in a `Box` not an `i32`. To get the old behaviour of forwarding the dereference you can add the `#[deref(forward)]` attribute on the struct or field. - Derives for `AsRef`, `AsMut`, `Sum`, `Product`, `IntoIterator`. - Choosing the field of a struct for which to derive the newtype derive. - Ignoring variants of enums when deriving `From`, by using `#[from(ignore)]`. - Add `#[from(forward)]` attribute for `From` derives. This forwards the `from` calls to the fields themselves. So if your field is an `i64` you can call from on an `i32` and it will work. - Add `#[mul(forward)]` and `#[mul_assign(forward)]`, which implement `Mul` and `MulAssign` with the semantics as if they were `Add`/`AddAssign`. - You can use features to cut down compile time of the crate by only compiling the code needed for the derives that you use. (see Cargo.toml for the features, by default they are all on) - Add `#[into(owned, ref, ref_mut)]` and `#[try_into(owned, ref, ref_mut)]` attributes. These cause the `Into` and `TryInto` derives to also implement derives that return references to the inner fields. - Allow `#[display(fmt="some shared display text for all enum variants {}")]` attribute on enum. - Better bounds inference of `Display` trait. ### Changed - Remove dependency on `regex` to cut down compile time. - Use `syn` 1.0 ## 0.15.0 - 2019-06-08 ### Fixed - Automatic detection of traits needed for `Display` format strings ## 0.14.0 - 2019-02-02 ### Added - Added `no_std` support ### Changed - Suppress `unused_variables` warnings in derives ## 0.13.0 - 2018-10-19 ### Added - Extended Display-like derives to support custom formats ### Changed - Updated to `syn` v0.15 ## 0.12.0 - 2018-09-19 ### Changed - Updated to `syn` v0.14, `quote` v0.6 and `proc-macro2` v0.4 ## 0.11.0 - 2018-05-12 ### Changed - Updated to latest version of `syn` and `quote` ### Fixed - Changed some URLs in the docs so they were correct on crates.io and docs.rs - The `Result` type is now referenced in the derives using its absolute path (`::std::result::Result`) to make sure that the derives don't accidentally use another `Result` type that is in scope. ## 0.10.0 - 2018-03-29 ### Added - Allow deriving of `TryInto` - Allow deriving of `Deref` - Allow deriving of `DerefMut` ## 0.9.0 - 2018-03-18 ### Added - Allow deriving of `Display`, `Binary`, `Octal`, `LowerHex`, `UpperHex`, `LowerExp`, `UpperExp`, `Pointer` - Allow deriving of `Index` - Allow deriving of `IndexMut` ### Fixed - Allow cross crate inlining of derived methods ## 0.8.0 - 2018-03-10 ### Added - Allow deriving of `FromStr` ### Changed - Updated to latest version of `syn` and `quote` ## 0.7.1 - 2018-01-25 ### Fixed - Add `#[allow(missing_docs)]` to the Constructor definition ## 0.7.0 - 2017-07-25 ### Changed - Changed code to work with newer version of the `syn` library. ## 0.6.2 - 2017-04-23 ### Changed - Deriving `From`, `Into` and `Constructor` now works for empty structs. ## 0.6.1 - 2017-03-08 ### Changed - The `new()` method that is created when deriving `Constructor` is now public. This makes it a lot more useful. ## 0.6.0 - 2017-02-20 ### Added - Derives for `Into`, `Constructor` and `MulAssign`-like ### Changed - `From` is now derived for enum variants with multiple fields. ### Fixed - Derivations now support generics. ## 0.5.0 - 2017-02-02 ### Added - Lots of docs. - Derives for `Neg`-like and `AddAssign`-like. ### Changed - `From` can now be derived for structs with multiple fields. derive_more-1.0.0/Cargo.lock0000644000000221060000000000100113060ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "convert_case" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" dependencies = [ "unicode-segmentation", ] [[package]] name = "derive_more" version = "1.0.0" dependencies = [ "derive_more-impl", "rustc_version", "rustversion", "static_assertions", "trybuild", ] [[package]] name = "derive_more-impl" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", "syn", "unicode-xid", ] [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "indexmap" version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "itoa" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "proc-macro2" version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ "semver", ] [[package]] name = "rustversion" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "semver" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", "serde", ] [[package]] name = "serde_spanned" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" version = "2.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "termcolor" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "toml" version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" dependencies = [ "serde", "serde_spanned", "toml_datetime", "toml_edit", ] [[package]] name = "toml_datetime" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] [[package]] name = "toml_edit" version = "0.22.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", "winnow", ] [[package]] name = "trybuild" version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b1e5645f2ee8025c2f1d75e1138f2dd034d74e6ba54620f3c569ba2a2a1ea06" dependencies = [ "glob", "serde", "serde_derive", "serde_json", "termcolor", "toml", ] [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-segmentation" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-xid" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "winapi-util" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ "windows-sys", ] [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "374ec40a2d767a3c1b4972d9475ecd557356637be906f2cb3f7fe17a6eb5e22f" dependencies = [ "memchr", ] derive_more-1.0.0/Cargo.toml0000644000000136220000000000100113340ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.75.0" name = "derive_more" version = "1.0.0" authors = ["Jelte Fennema "] build = false include = [ "src/**/*.rs", "Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md", "tests/**/*.rs", "examples/**/*.rs", ] autobins = false autoexamples = false autotests = false autobenches = false description = "Adds #[derive(x)] macros for more traits" documentation = "https://docs.rs/derive_more" readme = "README.md" keywords = [ "derive", "Add", "From", "Display", "IntoIterator", ] categories = [ "development-tools", "development-tools::procedural-macro-helpers", "no-std", "rust-patterns", ] license = "MIT" repository = "https://github.com/JelteF/derive_more" [package.metadata.docs.rs] features = ["full"] rustdoc-args = [ "--cfg", "docsrs", ] [lib] name = "derive_more" path = "src/lib.rs" [[example]] name = "deny_missing_docs" path = "examples/deny_missing_docs.rs" required-features = ["full"] [[test]] name = "add" path = "tests/add.rs" required-features = ["add"] [[test]] name = "add_assign" path = "tests/add_assign.rs" required-features = ["add_assign"] [[test]] name = "as_mut" path = "tests/as_mut.rs" required-features = ["as_ref"] [[test]] name = "as_ref" path = "tests/as_ref.rs" required-features = ["as_ref"] [[test]] name = "boats_display_derive" path = "tests/boats_display_derive.rs" required-features = ["display"] [[test]] name = "compile_fail" path = "tests/compile_fail/mod.rs" required-features = [ "as_ref", "debug", "display", "from", "into", "is_variant", "try_from", ] [[test]] name = "constructor" path = "tests/constructor.rs" required-features = ["constructor"] [[test]] name = "debug" path = "tests/debug.rs" required-features = ["debug"] [[test]] name = "deref" path = "tests/deref.rs" required-features = ["deref"] [[test]] name = "deref_mut" path = "tests/deref_mut.rs" required-features = ["deref_mut"] [[test]] name = "display" path = "tests/display.rs" required-features = ["display"] [[test]] name = "error" path = "tests/error_tests.rs" required-features = ["error"] [[test]] name = "from" path = "tests/from.rs" required-features = ["from"] [[test]] name = "from_str" path = "tests/from_str.rs" required-features = ["from_str"] [[test]] name = "generics" path = "tests/generics.rs" required-features = ["full"] [[test]] name = "index" path = "tests/index.rs" required-features = ["index"] [[test]] name = "index_mut" path = "tests/index_mut.rs" required-features = ["index_mut"] [[test]] name = "into" path = "tests/into.rs" required-features = ["into"] [[test]] name = "into_iterator" path = "tests/into_iterator.rs" required-features = ["into_iterator"] [[test]] name = "is_variant" path = "tests/is_variant.rs" required-features = ["is_variant"] [[test]] name = "lib" path = "tests/lib.rs" required-features = ["full"] [[test]] name = "mul" path = "tests/mul.rs" required-features = ["mul"] [[test]] name = "mul_assign" path = "tests/mul_assign.rs" required-features = ["mul_assign"] [[test]] name = "no_std" path = "tests/no_std.rs" required-features = ["full"] [[test]] name = "not" path = "tests/not.rs" required-features = ["not"] [[test]] name = "sum" path = "tests/sum.rs" required-features = ["sum"] [[test]] name = "try_from" path = "tests/try_from.rs" required-features = ["try_from"] [[test]] name = "try_into" path = "tests/try_into.rs" required-features = ["try_into"] [[test]] name = "try_unwrap" path = "tests/try_unwrap.rs" required-features = ["try_unwrap"] [[test]] name = "unwrap" path = "tests/unwrap.rs" required-features = ["unwrap"] [dependencies.derive_more-impl] version = "=1.0.0" [dev-dependencies.rustversion] version = "1.0" [dev-dependencies.static_assertions] version = "1.1" [dev-dependencies.trybuild] version = "1.0.56" [build-dependencies.rustc_version] version = "0.4" optional = true [features] add = ["derive_more-impl/add"] add_assign = ["derive_more-impl/add_assign"] as_ref = ["derive_more-impl/as_ref"] constructor = ["derive_more-impl/constructor"] debug = ["derive_more-impl/debug"] default = ["std"] 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"] full = [ "add", "add_assign", "as_ref", "constructor", "debug", "deref", "deref_mut", "display", "error", "from", "from_str", "index", "index_mut", "into", "into_iterator", "is_variant", "mul", "mul_assign", "not", "sum", "try_from", "try_into", "try_unwrap", "unwrap", ] index = ["derive_more-impl/index"] index_mut = ["derive_more-impl/index_mut"] into = ["derive_more-impl/into"] into_iterator = ["derive_more-impl/into_iterator"] is_variant = ["derive_more-impl/is_variant"] mul = ["derive_more-impl/mul"] mul_assign = ["derive_more-impl/mul_assign"] not = ["derive_more-impl/not"] std = [] sum = ["derive_more-impl/sum"] testing-helpers = [ "derive_more-impl/testing-helpers", "dep:rustc_version", ] try_from = ["derive_more-impl/try_from"] try_into = ["derive_more-impl/try_into"] try_unwrap = ["derive_more-impl/try_unwrap"] unwrap = ["derive_more-impl/unwrap"] [badges.github] repository = "JelteF/derive_more" workflow = "CI" [lints.rust.unexpected_cfgs] level = "warn" priority = 0 check-cfg = [ "cfg(ci)", "cfg(nightly)", ] derive_more-1.0.0/Cargo.toml.orig000064400000000000000000000123521046102023000150140ustar 00000000000000[package] name = "derive_more" version = "1.0.0" edition = "2021" rust-version = "1.75.0" description = "Adds #[derive(x)] macros for more traits" authors = ["Jelte Fennema "] license = "MIT" repository = "https://github.com/JelteF/derive_more" documentation = "https://docs.rs/derive_more" readme = "README.md" keywords = ["derive", "Add", "From", "Display", "IntoIterator"] categories = ["development-tools", "development-tools::procedural-macro-helpers", "no-std", "rust-patterns"] include = [ "src/**/*.rs", "Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md", "tests/**/*.rs", # debian packaging wants this "examples/**/*.rs" ] [workspace] members = ["impl"] [dependencies] derive_more-impl = { version = "=1.0.0", path = "impl" } [build-dependencies] rustc_version = { version = "0.4", optional = true } [dev-dependencies] rustversion = "1.0" static_assertions = "1.1" trybuild = "1.0.56" [badges] github = { repository = "JelteF/derive_more", workflow = "CI" } [package.metadata.docs.rs] features = ["full"] rustdoc-args = ["--cfg", "docsrs"] [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ["cfg(ci)", "cfg(nightly)"] } [features] default = ["std"] add = ["derive_more-impl/add"] add_assign = ["derive_more-impl/add_assign"] as_ref = ["derive_more-impl/as_ref"] constructor = ["derive_more-impl/constructor"] debug = ["derive_more-impl/debug"] 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"] is_variant = ["derive_more-impl/is_variant"] mul = ["derive_more-impl/mul"] mul_assign = ["derive_more-impl/mul_assign"] not = ["derive_more-impl/not"] sum = ["derive_more-impl/sum"] try_from = ["derive_more-impl/try_from"] try_into = ["derive_more-impl/try_into"] try_unwrap = ["derive_more-impl/try_unwrap"] unwrap = ["derive_more-impl/unwrap"] std = [] full = [ "add", "add_assign", "as_ref", "constructor", "debug", "deref", "deref_mut", "display", "error", "from", "from_str", "index", "index_mut", "into", "into_iterator", "is_variant", "mul", "mul_assign", "not", "sum", "try_from", "try_into", "try_unwrap", "unwrap", ] testing-helpers = ["derive_more-impl/testing-helpers", "dep:rustc_version"] [[test]] name = "add" path = "tests/add.rs" required-features = ["add"] [[test]] name = "add_assign" path = "tests/add_assign.rs" required-features = ["add_assign"] [[test]] name = "as_mut" path = "tests/as_mut.rs" required-features = ["as_ref"] [[test]] name = "as_ref" path = "tests/as_ref.rs" required-features = ["as_ref"] [[test]] name = "boats_display_derive" path = "tests/boats_display_derive.rs" required-features = ["display"] [[test]] name = "constructor" path = "tests/constructor.rs" required-features = ["constructor"] [[test]] name = "debug" path = "tests/debug.rs" required-features = ["debug"] [[test]] name = "deref" path = "tests/deref.rs" required-features = ["deref"] [[test]] name = "deref_mut" path = "tests/deref_mut.rs" required-features = ["deref_mut"] [[test]] name = "display" path = "tests/display.rs" required-features = ["display"] [[test]] name = "error" path = "tests/error_tests.rs" required-features = ["error"] [[test]] name = "from" path = "tests/from.rs" required-features = ["from"] [[test]] name = "from_str" path = "tests/from_str.rs" required-features = ["from_str"] [[test]] name = "index_mut" path = "tests/index_mut.rs" required-features = ["index_mut"] [[test]] name = "index" path = "tests/index.rs" required-features = ["index"] [[test]] name = "into" path = "tests/into.rs" required-features = ["into"] [[test]] name = "into_iterator" path = "tests/into_iterator.rs" required-features = ["into_iterator"] [[test]] name = "is_variant" path = "tests/is_variant.rs" required-features = ["is_variant"] [[test]] name = "mul" path = "tests/mul.rs" required-features = ["mul"] [[test]] name = "mul_assign" path = "tests/mul_assign.rs" required-features = ["mul_assign"] [[test]] name = "not" path = "tests/not.rs" required-features = ["not"] [[test]] name = "sum" path = "tests/sum.rs" required-features = ["sum"] [[test]] name = "try_from" path = "tests/try_from.rs" required-features = ["try_from"] [[test]] name = "try_into" path = "tests/try_into.rs" required-features = ["try_into"] [[test]] name = "try_unwrap" path = "tests/try_unwrap.rs" required-features = ["try_unwrap"] [[test]] name = "unwrap" path = "tests/unwrap.rs" required-features = ["unwrap"] [[test]] name = "compile_fail" path = "tests/compile_fail/mod.rs" required-features = ["as_ref", "debug", "display", "from", "into", "is_variant", "try_from"] [[test]] name = "no_std" path = "tests/no_std.rs" required-features = ["full"] [[test]] name = "generics" path = "tests/generics.rs" required-features = ["full"] [[test]] name = "lib" path = "tests/lib.rs" required-features = ["full"] [[example]] name = "deny_missing_docs" path = "examples/deny_missing_docs.rs" required-features = ["full"] derive_more-1.0.0/LICENSE000064400000000000000000000020701046102023000131260ustar 00000000000000The MIT License (MIT) Copyright (c) 2016 Jelte Fennema Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. derive_more-1.0.0/README.md000064400000000000000000000236241046102023000134100ustar 00000000000000# `derive_more` [![Build Status](https://github.com/JelteF/derive_more/workflows/CI/badge.svg)](https://github.com/JelteF/derive_more/actions) [![Latest Version](https://img.shields.io/crates/v/derive_more.svg)](https://crates.io/crates/derive_more) [![Rust Documentation](https://docs.rs/derive_more/badge.svg)](https://docs.rs/derive_more) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/JelteF/derive_more/master/LICENSE) [![Rust 1.75+](https://img.shields.io/badge/rustc-1.75+-lightgray.svg)](https://blog.rust-lang.org/2023/12/28/Rust-1.75.0.html) [![Unsafe Forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance) Rust has lots of builtin traits that are implemented for its basic types, such as `Add`, `Not`, `From` or `Display`. However, when wrapping these types inside your own structs or enums you lose the implementations of these traits and are required to recreate them. This is especially annoying when your own structures are very simple, such as when using the commonly advised newtype pattern (e.g. `MyInt(i32)`). This library tries to remove these annoyances and the corresponding boilerplate code. It does this by allowing you to derive lots of commonly used traits for both structs and enums. ## Example code By using this library the following code just works: ```rust use derive_more::{Add, Display, From, Into}; #[derive(PartialEq, From, Add)] struct MyInt(i32); #[derive(PartialEq, From, Into)] struct Point2D { x: i32, y: i32, } #[derive(PartialEq, From, Add, Display)] enum MyEnum { #[display("int: {_0}")] Int(i32), Uint(u32), #[display("nothing")] Nothing, } assert!(MyInt(11) == MyInt(5) + 6.into()); assert!((5, 6) == Point2D { x: 5, y: 6 }.into()); assert!(MyEnum::Int(15) == (MyEnum::Int(8) + 7.into()).unwrap()); assert!(MyEnum::Int(15).to_string() == "int: 15"); assert!(MyEnum::Uint(42).to_string() == "42"); assert!(MyEnum::Nothing.to_string() == "nothing"); ``` ## The derivable traits Below are all the traits that you can derive using this library. Some trait derivations are so similar that the further documentation will only show a single one of them. You can recognize these by the "-like" suffix in their name. The trait name before that will be the only one that is used throughout the further documentation. It is important to understand what code gets generated when using one of the derives from this crate. That is why the links below explain what code gets generated for a trait for each group from before. You can use the [`cargo-expand`] utility to see the exact code that is generated for your specific type. This will show you your code with all macros and derives expanded. **NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]` ### Conversion traits These are traits that are used to convert automatically between types. 1. [`From`] 2. [`Into`] 3. [`FromStr`] 4. [`TryFrom`] 5. [`TryInto`] 6. [`IntoIterator`] 7. [`AsRef`], [`AsMut`] ### Formatting traits These traits are used for converting a struct to a string in different ways. 1. [`Debug`] 2. [`Display`-like], contains `Display`, `Binary`, `Octal`, `LowerHex`, `UpperHex`, `LowerExp`, `UpperExp`, `Pointer` ### Error-handling traits These traits are used to define error-types. 1. [`Error`] ### Operators These are traits that can be used for operator overloading. 1. [`Index`] 2. [`Deref`] 3. [`Not`-like], contains `Not` and `Neg` 4. [`Add`-like], contains `Add`, `Sub`, `BitAnd`, `BitOr`, `BitXor` 5. [`Mul`-like], contains `Mul`, `Div`, `Rem`, `Shr` and `Shl` 6. [`Sum`-like], contains `Sum` and `Product` 7. [`IndexMut`] 8. [`DerefMut`] 9. [`AddAssign`-like], contains `AddAssign`, `SubAssign`, `BitAndAssign`, `BitOrAssign` and `BitXorAssign` 10. [`MulAssign`-like], contains `MulAssign`, `DivAssign`, `RemAssign`, `ShrAssign` and `ShlAssign` ### Static methods These don't derive traits, but derive static methods instead. 1. [`Constructor`], this derives a `new` method that can be used as a constructor. This is very basic if you need more customization for your constructor, check out the [`derive-new`] crate. 2. [`IsVariant`], for each variant `foo` of an enum type, derives a `is_foo` method. 3. [`Unwrap`], for each variant `foo` of an enum type, derives an `unwrap_foo` method. 4. [`TryUnwrap`], for each variant `foo` of an enum type, derives an `try_unwrap_foo` method. ### Re-exports This crate also re-exports all 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; // also imports `core::fmt::Display` ``` For derive macros only, without the corresponding traits, do import them from the `derive` module: ```rust use derive_more::derive::Display; // imports macro only ``` #### Hygiene For hygiene purposes, macros use `derive_more::*` absolute paths in their expansions. This might introduce a trouble, if you want to re-export `derive_more` macros in your own crate without using the `derive_more` as a direct dependency in downstream crates: ```rust,ignore use my_lib::Display; // re-exported in `my_lib` crate #[derive(Display)] // error: could not find `derive_more` in the list of imported crates struct MyInt(i32); ``` In such case, you should re-export the `derive_more` module too: ```rust,ignore use my_lib::{derive_more, Display}; // re-exported in `my_lib` crate #[derive(Display)] // works fine now! struct MyInt(i32); ``` ## Installation To avoid redundant compilation times, by default no derives are supported. You have to enable each type of derive as a feature in `Cargo.toml`: ```toml [dependencies] # You can specify the types of derives that you need for less time spent # compiling. For the full list of features see this crate its `Cargo.toml`. derive_more = { version = "1", features = ["from", "add", "iterator"] } ``` ```toml [dependencies] # If you don't care much about compilation times and simply want to have # support for all the possible derives, you can use the "full" feature. derive_more = { version = "1", features = ["full"] } ``` ```toml [dependencies] # If you run in a `no_std` environment you should disable the default features, # because the only default feature is the "std" feature. # NOTE: You can combine this with "full" feature to get support for all the # possible derives in a `no_std` environment. derive_more = { version = "1", default-features = false } ``` And this to the top of your Rust file: ```rust // use the derives that you want in the file use derive_more::{Add, Display, From}; ``` If you're still using Rust 2015, add this instead: ```rust,edition2015 extern crate core; #[macro_use] extern crate derive_more; # fn main() {} // omit wrapping statements above into `main()` in tests ``` ## [MSRV] policy This library requires Rust 1.75 or higher. Changing [MSRV] (minimum supported Rust version) of this crate is treated as a **minor version change** in terms of [Semantic Versioning]. - So, if [MSRV] changes are **NOT concerning** for your project, just use the default [caret requirement]: ```toml [dependencies] derive_more = "1" # or "1.0", or "^1.0" ``` - However, if [MSRV] changes are concerning for your project, then use the [tilde requirement] to **pin to a specific minor version**: ```toml [dependencies] derive_more = "~1.0" # or "~1.0.0" ``` [`cargo-expand`]: https://github.com/dtolnay/cargo-expand [`derive-new`]: https://github.com/nrc/derive-new [`From`]: https://docs.rs/derive_more/latest/derive_more/derive.From.html [`Into`]: https://docs.rs/derive_more/latest/derive_more/derive.Into.html [`FromStr`]: https://docs.rs/derive_more/latest/derive_more/derive.FromStr.html [`TryFrom`]: https://docs.rs/derive_more/latest/derive_more/derive.TryFrom.html [`TryInto`]: https://docs.rs/derive_more/latest/derive_more/derive.TryInto.html [`IntoIterator`]: https://docs.rs/derive_more/latest/derive_more/derive.IntoIterator.html [`AsRef`]: https://docs.rs/derive_more/latest/derive_more/derive.AsRef.html [`AsMut`]: https://docs.rs/derive_more/latest/derive_more/derive.AsMut.html [`Debug`]: https://docs.rs/derive_more/latest/derive_more/derive.Debug.html [`Display`-like]: https://docs.rs/derive_more/latest/derive_more/derive.Display.html [`Error`]: https://docs.rs/derive_more/latest/derive_more/derive.Error.html [`Index`]: https://docs.rs/derive_more/latest/derive_more/derive.Index.html [`Deref`]: https://docs.rs/derive_more/latest/derive_more/derive.Deref.html [`Not`-like]: https://docs.rs/derive_more/latest/derive_more/derive.Not.html [`Add`-like]: https://docs.rs/derive_more/latest/derive_more/derive.Add.html [`Mul`-like]: https://docs.rs/derive_more/latest/derive_more/derive.Mul.html [`Sum`-like]: https://docs.rs/derive_more/latest/derive_more/derive.Sum.html [`IndexMut`]: https://docs.rs/derive_more/latest/derive_more/derive.IndexMut.html [`DerefMut`]: https://docs.rs/derive_more/latest/derive_more/derive.DerefMut.html [`AddAssign`-like]: https://docs.rs/derive_more/latest/derive_more/derive.AddAssign.html [`MulAssign`-like]: https://docs.rs/derive_more/latest/derive_more/derive.MulAssign.html [`Constructor`]: https://docs.rs/derive_more/latest/derive_more/derive.Constructor.html [`IsVariant`]: https://docs.rs/derive_more/latest/derive_more/derive.IsVariant.html [`Unwrap`]: https://docs.rs/derive_more/latest/derive_more/derive.Unwrap.html [`TryUnwrap`]: https://docs.rs/derive_more/latest/derive_more/derive.TryUnwrap.html [caret requirement]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#caret-requirements [tilde requirement]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#tilde-requirements [MSRV]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field [Semantic Versioning]: http://semver.org derive_more-1.0.0/examples/deny_missing_docs.rs000064400000000000000000000013161046102023000200070ustar 00000000000000//! Some docs #![deny(missing_docs)] #![allow(dead_code)] // for illustration purposes use derive_more::{ Add, AddAssign, Constructor, Deref, DerefMut, Display, From, FromStr, Index, IndexMut, Into, IsVariant, Mul, MulAssign, Not, TryInto, }; fn main() {} /// Some docs #[derive( Add, AddAssign, Constructor, Display, From, FromStr, Into, Mul, MulAssign, Not )] pub struct MyInt(i32); /// Some docs #[derive(Deref, DerefMut)] pub struct MyBoxedInt(Box); /// Some docs #[derive(Index, IndexMut)] pub struct MyVec(Vec); /// Some docs #[derive(Clone, Copy, TryInto)] #[derive(IsVariant)] enum MixedInts { SmallInt(i32), NamedBigInt { int: i64 }, } derive_more-1.0.0/src/add.rs000064400000000000000000000032221046102023000140060ustar 00000000000000//! Definitions used in derived implementations of [`core::ops::Add`]-like traits. use core::fmt; use crate::UnitError; /// Error returned by the derived implementations when an arithmetic or logic /// operation is invoked on mismatched enum variants. #[derive(Clone, Copy, Debug)] pub struct WrongVariantError { operation_name: &'static str, } impl WrongVariantError { #[doc(hidden)] #[must_use] #[inline] pub const fn new(operation_name: &'static str) -> Self { Self { operation_name } } } impl fmt::Display for WrongVariantError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "Trying to {}() mismatched enum variants", self.operation_name, ) } } #[cfg(feature = "std")] impl std::error::Error for WrongVariantError {} /// Possible errors returned by the derived implementations of binary /// arithmetic or logic operations. #[derive(Clone, Copy, Debug)] pub enum BinaryError { /// Operation is attempted between mismatched enum variants. Mismatch(WrongVariantError), /// Operation is attempted on unit-like enum variants. Unit(UnitError), } impl fmt::Display for BinaryError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Mismatch(e) => write!(f, "{e}"), Self::Unit(e) => write!(f, "{e}"), } } } #[cfg(feature = "std")] impl std::error::Error for BinaryError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { Self::Mismatch(e) => e.source(), Self::Unit(e) => e.source(), } } } derive_more-1.0.0/src/as.rs000064400000000000000000000033471046102023000136710ustar 00000000000000//! Type glue for [autoref-based specialization][0], used in [`AsRef`]/[`AsMut`] macro expansion. //! //! Allows tp specialize the `impl AsRef for T` case over the default //! `impl, B> AsRef for Outer` one. //! //! [0]: https://lukaskalbertodt.github.io/2019/12/05/generalized-autoref-based-specialization.html use core::marker::PhantomData; /// Container to specialize over. pub struct Conv(PhantomData<(*const Frm, *const To)>); impl Default for Conv { fn default() -> Self { Self(PhantomData) } } /// Trait performing the specialization. pub trait ExtractRef { /// Input reference type. type Frm; /// Output reference type. type To; /// Extracts the output type from the input one. fn __extract_ref(&self, frm: Self::Frm) -> Self::To; } impl<'a, T> ExtractRef for &Conv<&'a T, T> where T: ?Sized, { type Frm = &'a T; type To = &'a T; fn __extract_ref(&self, frm: Self::Frm) -> Self::To { frm } } impl<'a, Frm, To> ExtractRef for Conv<&'a Frm, To> where Frm: AsRef + ?Sized, To: ?Sized + 'a, { type Frm = &'a Frm; type To = &'a To; fn __extract_ref(&self, frm: Self::Frm) -> Self::To { frm.as_ref() } } impl<'a, T> ExtractRef for &Conv<&'a mut T, T> where T: ?Sized, { type Frm = &'a mut T; type To = &'a mut T; fn __extract_ref(&self, frm: Self::Frm) -> Self::To { frm } } impl<'a, Frm, To> ExtractRef for Conv<&'a mut Frm, To> where Frm: AsMut + ?Sized, To: ?Sized + 'a, { type Frm = &'a mut Frm; type To = &'a mut To; fn __extract_ref(&self, frm: Self::Frm) -> Self::To { frm.as_mut() } } derive_more-1.0.0/src/convert.rs000064400000000000000000000052331046102023000147420ustar 00000000000000//! Definitions used in derived implementations of [`core::convert`] traits. #[cfg(feature = "try_from")] pub use self::try_from::TryFromReprError; #[cfg(feature = "try_into")] pub use self::try_into::TryIntoError; #[cfg(feature = "try_from")] mod try_from { use core::fmt; /// Error returned by the derived [`TryFrom`] implementation on enums to /// convert from their repr. /// /// [`TryFrom`]: macro@crate::TryFrom #[derive(Clone, Copy, Debug)] pub struct TryFromReprError { /// Original input value which failed to convert via the derived /// [`TryFrom`] implementation. /// /// [`TryFrom`]: macro@crate::TryFrom pub input: T, } impl TryFromReprError { #[doc(hidden)] #[must_use] #[inline] pub const fn new(input: T) -> Self { Self { input } } } // `T`, as a discriminant, should only be an integer type, and therefore be `Debug`. impl fmt::Display for TryFromReprError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "`{:?}` does not correspond to a unit variant", self.input ) } } #[cfg(feature = "std")] // `T` should only be an integer type and therefore be debug impl std::error::Error for TryFromReprError {} } #[cfg(feature = "try_into")] mod try_into { use core::fmt; /// Error returned by the derived [`TryInto`] implementation. /// /// [`TryInto`]: macro@crate::TryInto #[derive(Clone, Copy, Debug)] pub struct TryIntoError { /// Original input value which failed to convert via the derived /// [`TryInto`] implementation. /// /// [`TryInto`]: macro@crate::TryInto pub input: T, variant_names: &'static str, output_type: &'static str, } impl TryIntoError { #[doc(hidden)] #[must_use] #[inline] pub const fn new( input: T, variant_names: &'static str, output_type: &'static str, ) -> Self { Self { input, variant_names, output_type, } } } impl fmt::Display for TryIntoError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "Only {} can be converted to {}", self.variant_names, self.output_type, ) } } #[cfg(feature = "std")] impl std::error::Error for TryIntoError {} } derive_more-1.0.0/src/fmt.rs000064400000000000000000000125771046102023000140610ustar 00000000000000//! [`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. #[must_use = "must eventually call `finish()` or `finish_non_exhaustive()` on \ Debug builders"] pub struct DebugTuple<'a, 'b: 'a> { fmt: &'a mut Formatter<'b>, result: Result, fields: usize, empty_name: bool, } /// Creates a new [`DebugTuple`]. pub fn debug_tuple<'a, 'b>( fmt: &'a mut Formatter<'b>, name: &str, ) -> DebugTuple<'a, 'b> { let result = fmt.write_str(name); DebugTuple { fmt, result, fields: 0, empty_name: name.is_empty(), } } impl<'a, 'b: 'a> DebugTuple<'a, 'b> { /// Adds a new field to the generated tuple struct output. /// /// # Example /// /// ```rust /// use core::fmt; /// use derive_more::__private::debug_tuple; /// /// struct Foo(i32, String); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// debug_tuple(fmt, "Foo") /// .field(&self.0) // We add the first field. /// .field(&self.1) // We add the second field. /// .finish() // We're good to go! /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(10, "Hello World".to_string())), /// "Foo(10, \"Hello World\")", /// ); /// ``` pub fn field(&mut self, value: &dyn Debug) -> &mut Self { self.result = self.result.and_then(|_| { if self.is_pretty() { if self.fields == 0 { self.fmt.write_str("(\n")?; } let mut padded_formatter = Padded::new(self.fmt); padded_formatter.write_fmt(format_args!("{value:#?}"))?; padded_formatter.write_str(",\n") } else { let prefix = if self.fields == 0 { "(" } else { ", " }; self.fmt.write_str(prefix)?; value.fmt(self.fmt) } }); self.fields += 1; self } /// Finishes output and returns any error encountered. /// /// # Example /// /// ``` /// use core::fmt; /// use derive_more::__private::debug_tuple; /// /// struct Foo(i32, String); /// /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// debug_tuple(fmt, "Foo") /// .field(&self.0) /// .field(&self.1) /// .finish() // You need to call it to "finish" the /// // tuple formatting. /// } /// } /// /// assert_eq!( /// format!("{:?}", Foo(10, "Hello World".to_string())), /// "Foo(10, \"Hello World\")", /// ); /// ``` pub fn finish(&mut self) -> Result { if self.fields > 0 { self.result = self.result.and_then(|_| { if self.fields == 1 && self.empty_name && !self.is_pretty() { self.fmt.write_str(",")?; } self.fmt.write_str(")") }); } self.result } /// Marks the struct as non-exhaustive, indicating to the reader that there are some other /// fields that are not shown in the debug representation, and finishes output, returning any /// error encountered. /// /// # Example /// /// ```rust /// use core::fmt; /// use derive_more::__private::debug_tuple; /// /// struct Bar(i32, f32); /// /// impl fmt::Debug for Bar { /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// debug_tuple(fmt, "Bar") /// .field(&self.0) /// .finish_non_exhaustive() // Show that some other field(s) exist. /// } /// } /// /// assert_eq!(format!("{:?}", Bar(10, 1.0)), "Bar(10, ..)"); /// ``` pub fn finish_non_exhaustive(&mut self) -> Result { self.result = self.result.and_then(|_| { if self.fields > 0 { if self.is_pretty() { let mut padded_formatter = Padded::new(self.fmt); padded_formatter.write_str("..\n")?; self.fmt.write_str(")") } else { self.fmt.write_str(", ..)") } } else { self.fmt.write_str("(..)") } }); self.result } fn is_pretty(&self) -> bool { self.fmt.alternate() } } /// Wrapper for a [`Formatter`] adding 4 spaces on newlines for inner pretty /// printed [`Debug`] values. struct Padded<'a, 'b> { formatter: &'a mut Formatter<'b>, on_newline: bool, } impl<'a, 'b> Padded<'a, 'b> { fn new(formatter: &'a mut Formatter<'b>) -> Self { Self { formatter, on_newline: true, } } } impl<'a, 'b> Write for Padded<'a, 'b> { fn write_str(&mut self, s: &str) -> Result { for s in s.split_inclusive('\n') { if self.on_newline { self.formatter.write_str(" ")?; } self.on_newline = s.ends_with('\n'); self.formatter.write_str(s)?; } Ok(()) } } derive_more-1.0.0/src/lib.rs000064400000000000000000000306571046102023000140400ustar 00000000000000// These links overwrite the ones in `README.md` // to become proper intra-doc links in Rust docs. //! [`From`]: macro@crate::From //! [`Into`]: macro@crate::Into //! [`FromStr`]: macro@crate::FromStr //! [`TryFrom`]: macro@crate::TryFrom //! [`TryInto`]: macro@crate::TryInto //! [`IntoIterator`]: macro@crate::IntoIterator //! [`AsRef`]: macro@crate::AsRef //! //! [`Debug`]: macro@crate::Debug //! [`Display`-like]: macro@crate::Display //! //! [`Error`]: macro@crate::Error //! //! [`Index`]: macro@crate::Index //! [`Deref`]: macro@crate::Deref //! [`Not`-like]: macro@crate::Not //! [`Add`-like]: macro@crate::Add //! [`Mul`-like]: macro@crate::Mul //! [`Sum`-like]: macro@crate::Sum //! [`IndexMut`]: macro@crate::IndexMut //! [`DerefMut`]: macro@crate::DerefMut //! [`AddAssign`-like]: macro@crate::AddAssign //! [`MulAssign`-like]: macro@crate::MulAssign //! //! [`Constructor`]: macro@crate::Constructor //! [`IsVariant`]: macro@crate::IsVariant //! [`Unwrap`]: macro@crate::Unwrap //! [`TryUnwrap`]: macro@crate::TryUnwrap // The README includes doctests requiring these features. To make sure that // tests pass when not all features are provided we exclude it when the // required features are not available. #![cfg_attr( all( feature = "add", feature = "display", feature = "from", feature = "into" ), doc = include_str!("../README.md") )] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(any(not(docsrs), ci), deny(rustdoc::all))] #![forbid(non_ascii_idents, unsafe_code)] #![warn(clippy::nonstandard_macro_braces)] // For macro expansion internals only. // Ensures better hygiene in case a local crate `core` is present in workspace of the user code, // or some other crate is renamed as `core`. #[doc(hidden)] pub use core; // Not public, but exported API. For macro expansion internals only. #[doc(hidden)] pub mod __private { #[cfg(feature = "as_ref")] pub use crate::r#as::{Conv, ExtractRef}; #[cfg(feature = "debug")] pub use crate::fmt::{debug_tuple, DebugTuple}; #[cfg(feature = "error")] pub use crate::vendor::thiserror::aserror::AsDynError; } /// Module containing macro definitions only, without corresponding traits. /// /// Use it in your import paths, if you don't want to import traits, but only macros. pub mod derive { // This can be unused if no feature is enabled. We already error in that case, but this warning // distracts from that error. So we suppress the warning. #[allow(unused_imports)] #[doc(inline)] pub use derive_more_impl::*; } // The modules containing error types and other helpers. #[cfg(feature = "add")] mod add; #[cfg(feature = "add")] pub use crate::add::{BinaryError, WrongVariantError}; #[cfg(any(feature = "add", feature = "not"))] mod ops; #[cfg(any(feature = "add", feature = "not"))] pub use crate::ops::UnitError; #[cfg(feature = "as_ref")] mod r#as; #[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 crate::r#str::FromStrError; #[cfg(any(feature = "try_into", feature = "try_from"))] mod convert; #[cfg(feature = "try_from")] #[doc(inline)] pub use crate::convert::TryFromReprError; #[cfg(feature = "try_into")] #[doc(inline)] pub use crate::convert::TryIntoError; #[cfg(feature = "try_unwrap")] mod try_unwrap; #[cfg(feature = "try_unwrap")] #[doc(inline)] pub use crate::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(all(feature = $feature, any(not(docsrs), ci)))] mod $new_module_name { #[doc(hidden)] pub use $module::{$($traits),*}; } #[cfg(all(feature = $feature, any(not(docsrs), ci)))] #[doc(hidden)] pub use crate::all_traits_and_derives::$new_module_name::*; } ); mod all_traits_and_derives { 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_ref", as_ref_traits, core::convert, AsMut, 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_from", try_from_traits, core::convert, TryFrom); 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_ref")] pub use derive_more_impl::{AsMut, AsRef}; #[cfg(feature = "constructor")] pub use derive_more_impl::Constructor; #[cfg(feature = "debug")] pub use derive_more_impl::Debug; #[cfg(feature = "deref")] pub use derive_more_impl::Deref; #[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")] pub use derive_more_impl::Error; #[cfg(feature = "from")] pub use derive_more_impl::From; #[cfg(feature = "from_str")] pub use derive_more_impl::FromStr; #[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_from")] pub use derive_more_impl::TryFrom; #[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; } // Now re-export our own derives and the std traits by their exact name to make rust-analyzer // recognize the #[doc(hidden)] flag. // See issues: // 1. https://github.com/rust-lang/rust-analyzer/issues/11698 // 2. https://github.com/rust-lang/rust-analyzer/issues/14079 #[cfg(feature = "add")] #[doc(hidden)] pub use all_traits_and_derives::{Add, BitAnd, BitOr, BitXor, Sub}; #[cfg(feature = "add_assign")] #[doc(hidden)] pub use all_traits_and_derives::{ AddAssign, BitAndAssign, BitOrAssign, BitXorAssign, SubAssign, }; #[cfg(feature = "as_ref")] #[doc(hidden)] pub use all_traits_and_derives::{AsMut, AsRef}; #[cfg(feature = "constructor")] #[doc(hidden)] pub use all_traits_and_derives::Constructor; #[cfg(feature = "debug")] #[doc(hidden)] pub use all_traits_and_derives::Debug; #[cfg(feature = "deref")] #[doc(hidden)] pub use all_traits_and_derives::Deref; #[cfg(feature = "deref_mut")] #[doc(hidden)] pub use all_traits_and_derives::DerefMut; #[cfg(feature = "display")] #[doc(hidden)] pub use all_traits_and_derives::{ Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, }; #[cfg(feature = "error")] #[doc(hidden)] pub use all_traits_and_derives::Error; #[cfg(feature = "from")] #[doc(hidden)] pub use all_traits_and_derives::From; #[cfg(feature = "from_str")] #[doc(hidden)] pub use all_traits_and_derives::FromStr; #[cfg(feature = "index")] #[doc(hidden)] pub use all_traits_and_derives::Index; #[cfg(feature = "index_mut")] #[doc(hidden)] pub use all_traits_and_derives::IndexMut; #[cfg(feature = "into")] #[doc(hidden)] pub use all_traits_and_derives::Into; #[cfg(feature = "into_iterator")] #[doc(hidden)] pub use all_traits_and_derives::IntoIterator; #[cfg(feature = "is_variant")] #[doc(hidden)] pub use all_traits_and_derives::IsVariant; #[cfg(feature = "mul")] #[doc(hidden)] pub use all_traits_and_derives::{Div, Mul, Rem, Shl, Shr}; #[cfg(feature = "mul_assign")] #[doc(hidden)] pub use all_traits_and_derives::{ DivAssign, MulAssign, RemAssign, ShlAssign, ShrAssign, }; #[cfg(feature = "not")] #[doc(hidden)] pub use all_traits_and_derives::{Neg, Not}; #[cfg(feature = "sum")] #[doc(hidden)] pub use all_traits_and_derives::{Product, Sum}; #[cfg(feature = "try_from")] #[doc(hidden)] pub use all_traits_and_derives::TryFrom; #[cfg(feature = "try_into")] #[doc(hidden)] pub use all_traits_and_derives::TryInto; #[cfg(feature = "try_unwrap")] #[doc(hidden)] pub use all_traits_and_derives::TryUnwrap; #[cfg(feature = "unwrap")] #[doc(hidden)] pub use all_traits_and_derives::Unwrap; // Re-export the derive macros again to show docs for our derives (but not for traits). This is // done using a glob import to not hit E0252. #[allow(unused_imports)] pub use derive_more_impl::*; // Check if any feature is enabled #[cfg(not(any( feature = "full", feature = "add", feature = "add_assign", feature = "as_ref", feature = "constructor", feature = "debug", feature = "deref", feature = "deref_mut", feature = "display", feature = "error", feature = "from", feature = "from_str", feature = "index", feature = "index_mut", feature = "into", feature = "into_iterator", feature = "is_variant", feature = "mul", feature = "mul_assign", feature = "not", feature = "sum", feature = "try_from", feature = "try_into", feature = "try_unwrap", feature = "unwrap", )))] compile_error!( "at least one derive feature must be enabled (or the \"full\" feature enabling all the derives)" ); derive_more-1.0.0/src/ops.rs000064400000000000000000000013241046102023000140600ustar 00000000000000//! Definitions used in derived implementations of [`core::ops`] traits. use core::fmt; /// Error returned by the derived implementations when an arithmetic or logic /// operation is invoked on a unit-like variant of an enum. #[derive(Clone, Copy, Debug)] pub struct UnitError { operation_name: &'static str, } impl UnitError { #[doc(hidden)] #[must_use] #[inline] pub const fn new(operation_name: &'static str) -> Self { Self { operation_name } } } impl fmt::Display for UnitError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Cannot {}() unit variants", self.operation_name) } } #[cfg(feature = "std")] impl std::error::Error for UnitError {} derive_more-1.0.0/src/str.rs000064400000000000000000000011161046102023000140660ustar 00000000000000use core::fmt; /// Error of parsing an enum value its string representation. #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub struct FromStrError { type_name: &'static str, } impl FromStrError { #[doc(hidden)] #[must_use] #[inline] pub const fn new(type_name: &'static str) -> Self { Self { type_name } } } impl fmt::Display for FromStrError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Invalid `{}` string representation", self.type_name) } } #[cfg(feature = "std")] impl std::error::Error for FromStrError {} derive_more-1.0.0/src/try_unwrap.rs000064400000000000000000000024361046102023000154760ustar 00000000000000/// Error returned by the derived [`TryUnwrap`] implementation. /// /// [`TryUnwrap`]: macro@crate::TryUnwrap #[derive(Clone, Copy, Debug, PartialEq)] pub struct TryUnwrapError { /// Original input value which failed to convert via the derived /// [`TryUnwrap`] implementation. /// /// [`TryUnwrap`]: macro@crate::TryUnwrap pub input: T, enum_name: &'static str, variant_name: &'static str, func_name: &'static str, } impl TryUnwrapError { #[doc(hidden)] #[must_use] #[inline] pub const fn new( input: T, enum_name: &'static str, variant_name: &'static str, func_name: &'static str, ) -> Self { Self { input, enum_name, variant_name, func_name, } } } impl core::fmt::Display for TryUnwrapError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "Attempt to call `{enum_name}::{func_name}()` on a `{enum_name}::{variant_name}` value", enum_name = self.enum_name, variant_name = self.variant_name, func_name = self.func_name, ) } } #[cfg(feature = "std")] impl std::error::Error for TryUnwrapError {} derive_more-1.0.0/src/vendor/mod.rs000064400000000000000000000000551046102023000153330ustar 00000000000000#[cfg(feature = "error")] pub mod thiserror; derive_more-1.0.0/src/vendor/thiserror/README.md000064400000000000000000000003621046102023000175070ustar 00000000000000# Vendored files from `thiserror` These are vendored files from the [`thiserror`] crate. The license files in this directory only apply to the files in this subdirectory of `derive_more`. [`thiserror`]: https://github.com/dtolnay/thiserror derive_more-1.0.0/src/vendor/thiserror/aserror.rs000064400000000000000000000022371046102023000202560ustar 00000000000000#[cfg(not(feature = "std"))] use core::error::Error; #[cfg(feature = "std")] use std::error::Error; use core::panic::UnwindSafe; pub trait AsDynError<'a>: Sealed { fn as_dyn_error(&self) -> &(dyn Error + 'a); } impl<'a, T: Error + 'a> AsDynError<'a> for T { #[inline] fn as_dyn_error(&self) -> &(dyn Error + 'a) { self } } impl<'a> AsDynError<'a> for dyn Error + 'a { #[inline] fn as_dyn_error(&self) -> &(dyn Error + 'a) { self } } impl<'a> AsDynError<'a> for dyn Error + Send + 'a { #[inline] fn as_dyn_error(&self) -> &(dyn Error + 'a) { self } } impl<'a> AsDynError<'a> for dyn Error + Send + Sync + 'a { #[inline] fn as_dyn_error(&self) -> &(dyn Error + 'a) { self } } impl<'a> AsDynError<'a> for dyn Error + Send + Sync + UnwindSafe + 'a { #[inline] fn as_dyn_error(&self) -> &(dyn Error + 'a) { self } } pub trait Sealed {} impl<'a, T: Error + 'a> Sealed for T {} impl<'a> Sealed for dyn Error + 'a {} impl<'a> Sealed for dyn Error + Send + 'a {} impl<'a> Sealed for dyn Error + Send + Sync + 'a {} impl<'a> Sealed for dyn Error + Send + Sync + UnwindSafe + 'a {} derive_more-1.0.0/src/vendor/thiserror/mod.rs000064400000000000000000000000211046102023000173450ustar 00000000000000pub mod aserror; derive_more-1.0.0/tests/add.rs000064400000000000000000000006511046102023000143640ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use derive_more::Add; #[derive(Add)] struct MyInts(i32, i32); #[derive(Add)] struct Point2D { x: i32, y: i32, } #[derive(Add)] enum MixedInts { SmallInt(i32), BigInt(i64), TwoSmallInts(i32, i32), NamedSmallInts { x: i32, y: i32 }, UnsignedOne(u32), UnsignedTwo(u32), Unit, } derive_more-1.0.0/tests/add_assign.rs000064400000000000000000000003731046102023000157310ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use derive_more::AddAssign; #[derive(AddAssign)] struct MyInts(i32, i32); #[derive(AddAssign)] struct Point2D { x: i32, y: i32, } derive_more-1.0.0/tests/as_mut.rs000064400000000000000000001143261046102023000151310ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::unnecessary_mut_passed)] // testing correct signatures rather than actual code #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::{borrow::ToOwned, collections::VecDeque, string::String, vec, vec::Vec}; #[cfg(feature = "std")] use std::collections::VecDeque; use core::{marker::PhantomData, ptr}; use derive_more::AsMut; struct Helper(i32, f64, bool); impl AsMut for Helper { fn as_mut(&mut self) -> &mut i32 { &mut self.0 } } impl AsMut for Helper { fn as_mut(&mut self) -> &mut f64 { &mut self.1 } } impl AsMut for Helper { fn as_mut(&mut self) -> &mut bool { &mut self.2 } } struct LifetimeHelper<'a>(i32, PhantomData<&'a ()>); impl LifetimeHelper<'static> { fn new(val: i32) -> Self { Self(val, PhantomData) } } impl AsMut for LifetimeHelper<'static> { fn as_mut(&mut self) -> &mut i32 { &mut self.0 } } struct ConstParamHelper([i32; N]); impl AsMut<[i32]> for ConstParamHelper<0> { fn as_mut(&mut self) -> &mut [i32] { self.0.as_mut() } } mod single_field { use super::*; mod tuple { use super::*; #[derive(AsMut)] struct Nothing(String); #[test] fn nothing() { let mut item = Nothing("test".to_owned()); assert!(ptr::eq(item.as_mut(), &mut item.0)); } #[derive(AsMut)] #[as_mut(forward)] struct Forward(String); #[test] fn forward() { let mut item = Forward("test".to_owned()); let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); } #[derive(AsMut)] struct Field(#[as_mut] String); #[test] fn field() { let mut item = Field("test".to_owned()); assert!(ptr::eq(item.as_mut(), &mut item.0)); } #[derive(AsMut)] struct FieldForward(#[as_mut(forward)] String); #[test] fn field_forward() { let mut item = FieldForward("test".to_owned()); let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); } #[derive(AsMut)] #[as_mut(i32, f64)] struct Types(Helper); // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for Types { fn as_mut(&mut self) -> &mut bool { self.0.as_mut() } } // Asserts that the macro expansion doesn't generate an `AsMut` impl for the field type, by // producing a trait implementations conflict error during compilation, if it does. impl AsMut for Types { fn as_mut(&mut self) -> &mut Helper { &mut self.0 } } #[test] fn types() { let mut item = Types(Helper(1, 2.0, false)); let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut f64 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); } #[derive(AsMut)] #[as_mut(i32, Helper)] struct TypesWithInner(Helper); // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for TypesWithInner { fn as_mut(&mut self) -> &mut bool { self.0.as_mut() } } #[test] fn types_with_inner() { let mut item = TypesWithInner(Helper(1, 2.0, false)); let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut Helper = item.as_mut(); assert!(ptr::eq(rf, &mut item.0)); } type RenamedFoo = Helper; #[derive(AsMut)] #[as_mut(i32, RenamedFoo)] struct TypesWithRenamedInner(Helper); // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for TypesWithRenamedInner { fn as_mut(&mut self) -> &mut bool { self.0.as_mut() } } #[test] fn types_with_renamed_inner() { let mut item = TypesWithRenamedInner(Helper(1, 2.0, false)); let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut Helper = item.as_mut(); assert!(ptr::eq(rf, &mut item.0)); } #[derive(AsMut)] struct FieldTypes(#[as_mut(i32, f64)] Helper); // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for FieldTypes { fn as_mut(&mut self) -> &mut bool { self.0.as_mut() } } // Asserts that the macro expansion doesn't generate an `AsMut` impl for the field type, by // producing a trait implementations conflict error during compilation, if it does. impl AsMut for FieldTypes { fn as_mut(&mut self) -> &mut Helper { &mut self.0 } } #[test] fn field_types() { let mut item = FieldTypes(Helper(1, 2.0, false)); let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut f64 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); } #[derive(AsMut)] struct FieldTypesWithInner(#[as_mut(i32, Helper)] Helper); // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for FieldTypesWithInner { fn as_mut(&mut self) -> &mut bool { self.0.as_mut() } } #[test] fn field_types_with_inner() { let mut item = FieldTypesWithInner(Helper(1, 2.0, false)); let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut Helper = item.as_mut(); assert!(ptr::eq(rf, &mut item.0)); } #[derive(AsMut)] struct FieldTypesWithRenamedInner(#[as_mut(i32, RenamedFoo)] Helper); // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for FieldTypesWithRenamedInner { fn as_mut(&mut self) -> &mut bool { self.0.as_mut() } } #[test] fn field_types_with_renamed_inner() { let mut item = FieldTypesWithRenamedInner(Helper(1, 2.0, false)); let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut Helper = item.as_mut(); assert!(ptr::eq(rf, &mut item.0)); } mod generic { use super::*; #[derive(AsMut)] struct Nothing(T); #[test] fn nothing() { let mut item = Nothing("test".to_owned()); assert!(ptr::eq(item.as_mut(), &mut item.0)); } #[derive(AsMut)] #[as_mut(forward)] struct Forward(T); #[test] fn forward() { let mut item = Forward("test".to_owned()); let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); } #[derive(AsMut)] struct Field(#[as_mut] T); #[test] fn field() { let mut item = Field("test".to_owned()); assert!(ptr::eq(item.as_mut(), &mut item.0)); } #[derive(AsMut)] struct FieldForward(#[as_mut(forward)] T); #[test] fn field_forward() { let mut item = FieldForward("test".to_owned()); let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); } #[derive(AsMut)] #[as_mut(i32, f64)] struct Types(T); // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding // to the field type, by producing a trait implementations conflict error during // compilation, if it does. impl> AsMut for Types { fn as_mut(&mut self) -> &mut bool { self.0.as_mut() } } #[test] fn types() { let mut item = Types(Helper(1, 2.0, false)); let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut f64 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); } #[derive(AsMut)] #[as_mut(Vec)] struct TypesInner(Vec); #[test] fn types_inner() { let mut item = TypesInner(vec![1i32]); assert!(ptr::eq(item.as_mut(), &mut item.0)); } #[derive(AsMut)] struct FieldTypes(#[as_mut(i32, f64)] T); // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding // to the field type, by producing a trait implementations conflict error during // compilation, if it does. impl> AsMut for FieldTypes { fn as_mut(&mut self) -> &mut bool { self.0.as_mut() } } #[test] fn field_types() { let mut item = FieldTypes(Helper(1, 2.0, false)); let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut f64 = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); } #[derive(AsMut)] struct FieldTypesInner(#[as_mut(Vec)] Vec); #[test] fn field_types_inner() { let mut item = FieldTypesInner(vec![1i32]); assert!(ptr::eq(item.as_mut(), &mut item.0)); } #[derive(AsMut)] #[as_mut(i32)] struct Lifetime<'a>(LifetimeHelper<'a>); #[test] fn lifetime() { let mut item = Lifetime(LifetimeHelper::new(0)); assert!(ptr::eq(item.as_mut(), item.0.as_mut())); } #[derive(AsMut)] struct FieldLifetime<'a>(#[as_mut(i32)] LifetimeHelper<'a>); #[test] fn field_lifetime() { let mut item = FieldLifetime(LifetimeHelper::new(0)); assert!(ptr::eq(item.as_mut(), item.0.as_mut())); } #[derive(AsMut)] #[as_mut([i32])] struct ConstParam(ConstParamHelper); #[test] fn const_param() { let mut item = ConstParam(ConstParamHelper([])); assert!(ptr::eq(item.as_mut(), item.0.as_mut())); } #[derive(AsMut)] struct FieldConstParam( #[as_mut([i32])] ConstParamHelper, ); #[test] fn field_const_param() { let mut item = FieldConstParam(ConstParamHelper([])); assert!(ptr::eq(item.as_mut(), item.0.as_mut())); } } } mod named { use super::*; #[derive(AsMut)] struct Nothing { first: String, } #[test] fn nothing() { let mut item = Nothing { first: "test".to_owned(), }; assert!(ptr::eq(item.as_mut(), &mut item.first)); } #[derive(AsMut)] #[as_mut(forward)] struct Forward { first: String, } #[test] fn forward() { let mut item = Forward { first: "test".to_owned(), }; let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); } #[derive(AsMut)] struct Field { #[as_mut] first: String, } #[test] fn field() { let mut item = Field { first: "test".to_owned(), }; assert!(ptr::eq(item.as_mut(), &mut item.first)); } #[derive(AsMut)] struct FieldForward { #[as_mut(forward)] first: String, } #[test] fn field_forward() { let mut item = FieldForward { first: "test".to_owned(), }; let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); } #[derive(AsMut)] #[as_mut(i32, f64)] struct Types { first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for Types { fn as_mut(&mut self) -> &mut bool { self.first.as_mut() } } // Asserts that the macro expansion doesn't generate an `AsMut` impl for the field type, by // producing a trait implementations conflict error during compilation, if it does. impl AsMut for Types { fn as_mut(&mut self) -> &mut Helper { &mut self.first } } #[test] fn types() { let mut item = Types { first: Helper(1, 2.0, false), }; let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut f64 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); } #[derive(AsMut)] #[as_mut(i32, Helper)] struct TypesWithInner { first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for TypesWithInner { fn as_mut(&mut self) -> &mut bool { self.first.as_mut() } } #[test] fn types_with_inner() { let mut item = TypesWithInner { first: Helper(1, 2.0, false), }; let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut Helper = item.as_mut(); assert!(ptr::eq(rf, &mut item.first)); } type RenamedFoo = Helper; #[derive(AsMut)] #[as_mut(i32, RenamedFoo)] struct TypesWithRenamedInner { first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for TypesWithRenamedInner { fn as_mut(&mut self) -> &mut bool { self.first.as_mut() } } #[test] fn types_with_renamed_inner() { let mut item = TypesWithRenamedInner { first: Helper(1, 2.0, false), }; let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut Helper = item.as_mut(); assert!(ptr::eq(rf, &mut item.first)); } #[derive(AsMut)] struct FieldTypes { #[as_mut(i32, f64)] first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for FieldTypes { fn as_mut(&mut self) -> &mut bool { self.first.as_mut() } } // Asserts that the macro expansion doesn't generate an `AsMut` impl for the field type, by // producing a trait implementations conflict error during compilation, if it does. impl AsMut for FieldTypes { fn as_mut(&mut self) -> &mut Helper { &mut self.first } } #[test] fn field_types() { let mut item = FieldTypes { first: Helper(1, 2.0, false), }; let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut f64 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); } #[derive(AsMut)] struct FieldTypesWithInner { #[as_mut(i32, Helper)] first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for FieldTypesWithInner { fn as_mut(&mut self) -> &mut bool { self.first.as_mut() } } #[test] fn field_types_with_inner() { let mut item = FieldTypesWithInner { first: Helper(1, 2.0, false), }; let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut Helper = item.as_mut(); assert!(ptr::eq(rf, &mut item.first)); } #[derive(AsMut)] struct FieldTypesWithRenamedInner { #[as_mut(i32, RenamedFoo)] first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsMut for FieldTypesWithRenamedInner { fn as_mut(&mut self) -> &mut bool { self.first.as_mut() } } #[test] fn field_types_with_renamed_inner() { let mut item = FieldTypesWithRenamedInner { first: Helper(1, 2.0, false), }; let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut Helper = item.as_mut(); assert!(ptr::eq(rf, &mut item.first)); } mod generic { use super::*; #[derive(AsMut)] struct Nothing { first: T, } #[test] fn nothing() { let mut item = Nothing { first: "test".to_owned(), }; assert!(ptr::eq(item.as_mut(), &mut item.first)); } #[derive(AsMut)] #[as_mut(forward)] struct Forward { first: T, } #[test] fn struct_forward() { let mut item = Forward { first: "test".to_owned(), }; let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); } #[derive(AsMut)] struct Field { #[as_mut] first: T, } #[test] fn field() { let mut item = Field { first: "test".to_owned(), }; assert!(ptr::eq(item.as_mut(), &mut item.first)); } #[derive(AsMut)] struct FieldForward { #[as_mut(forward)] first: T, } #[test] fn field_forward() { let mut item = FieldForward { first: "test".to_owned(), }; let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); } #[derive(AsMut)] #[as_mut(i32, f64)] struct Types { first: T, } // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding // to the field type, by producing a trait implementations conflict error during // compilation, if it does. impl> AsMut for Types { fn as_mut(&mut self) -> &mut bool { self.first.as_mut() } } #[test] fn types() { let mut item = Types { first: Helper(1, 2.0, false), }; let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut f64 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); } #[derive(AsMut)] #[as_mut(Vec)] struct TypesInner { first: Vec, } #[test] fn types_inner() { let mut item = TypesInner { first: vec![1i32] }; assert!(ptr::eq(item.as_mut(), &mut item.first)); } #[derive(AsMut)] struct FieldTypes { #[as_mut(i32, f64)] first: T, } // Asserts that the macro expansion doesn't generate a blanket `AsMut` impl forwarding // to the field type, by producing a trait implementations conflict error during // compilation, if it does. impl> AsMut for FieldTypes { fn as_mut(&mut self) -> &mut bool { self.first.as_mut() } } #[test] fn field_types() { let mut item = FieldTypes { first: Helper(1, 2.0, false), }; let rf: &mut i32 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut f64 = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); } #[derive(AsMut)] struct FieldTypesInner { #[as_mut(Vec)] first: Vec, } #[test] fn field_types_inner() { let mut item = FieldTypesInner { first: vec![1i32] }; assert!(ptr::eq(item.as_mut(), &mut item.first)); } #[derive(AsMut)] #[as_mut(i32)] struct Lifetime<'a> { first: LifetimeHelper<'a>, } #[test] fn lifetime() { let mut item = Lifetime { first: LifetimeHelper::new(0), }; assert!(ptr::eq(item.as_mut(), item.first.as_mut())); } #[derive(AsMut)] struct FieldLifetime<'a> { #[as_mut(i32)] first: LifetimeHelper<'a>, } #[test] fn field_lifetime() { let mut item = FieldLifetime { first: LifetimeHelper::new(0), }; assert!(ptr::eq(item.as_mut(), item.first.as_mut())); } #[derive(AsMut)] #[as_mut([i32])] struct ConstParam { first: ConstParamHelper, } #[test] fn const_param() { let mut item = ConstParam { first: ConstParamHelper([]), }; assert!(ptr::eq(item.as_mut(), item.first.as_mut())); } #[derive(AsMut)] struct FieldConstParam { #[as_mut([i32])] first: ConstParamHelper, } #[test] fn field_const_param() { let mut item = FieldConstParam { first: ConstParamHelper([]), }; assert!(ptr::eq(item.as_mut(), item.first.as_mut())); } } } } mod multi_field { use super::*; mod tuple { use super::*; #[derive(AsMut)] struct Nothing(String, i32); #[test] fn nothing() { let mut item = Nothing("test".to_owned(), 0); assert!(ptr::eq(item.as_mut(), &mut item.0)); assert!(ptr::eq(item.as_mut(), &mut item.1)); } #[derive(AsMut)] struct Skip(String, i32, #[as_mut(skip)] f64); // Asserts that the macro expansion doesn't generate `AsMut` impl for the skipped field, by // producing trait implementations conflict error during compilation, if it does. impl AsMut for Skip { fn as_mut(&mut self) -> &mut f64 { &mut self.2 } } #[test] fn skip() { let mut item = Skip("test".to_owned(), 0, 0.0); assert!(ptr::eq(item.as_mut(), &mut item.0)); assert!(ptr::eq(item.as_mut(), &mut item.1)); } #[derive(AsMut)] struct Field(#[as_mut] String, #[as_mut] i32, f64); // Asserts that the macro expansion doesn't generate `AsMut` impl for the third field, by // producing trait implementations conflict error during compilation, if it does. impl AsMut for Field { fn as_mut(&mut self) -> &mut f64 { &mut self.2 } } #[test] fn field() { let mut item = Field("test".to_owned(), 0, 0.0); assert!(ptr::eq(item.as_mut(), &mut item.0)); assert!(ptr::eq(item.as_mut(), &mut item.1)); } #[derive(AsMut)] struct FieldForward(#[as_mut(forward)] String, i32); #[test] fn field_forward() { let mut item = FieldForward("test".to_owned(), 0); let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); } type RenamedString = String; #[derive(AsMut)] struct Types( #[as_mut(str, RenamedString)] String, #[as_mut([u8])] Vec, ); // Asserts that the macro expansion doesn't generate `AsMut` impl for the field type, by // producing trait implementations conflict error during compilation, if it does. impl AsMut> for Types { fn as_mut(&mut self) -> &mut Vec { &mut self.1 } } #[test] fn types() { let mut item = Types("test".to_owned(), vec![0]); let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut String = item.as_mut(); assert!(ptr::eq(rf, &mut item.0)); let rf: &mut [u8] = item.as_mut(); assert!(ptr::eq(rf, item.1.as_mut())); } mod generic { use super::*; #[derive(AsMut)] struct Nothing(Vec, VecDeque); #[test] fn nothing() { let mut item = Nothing(vec![1], VecDeque::from([2])); assert!(ptr::eq(item.as_mut(), &mut item.0)); assert!(ptr::eq(item.as_mut(), &mut item.1)); } #[derive(AsMut)] struct Skip(Vec, VecDeque, #[as_mut(skip)] V); #[test] fn skip() { let mut item = Skip(vec![1], VecDeque::from([2]), 0); assert!(ptr::eq(item.as_mut(), &mut item.0)); assert!(ptr::eq(item.as_mut(), &mut item.1)); } #[derive(AsMut)] struct Field(#[as_mut] Vec, #[as_mut] VecDeque, V); #[test] fn field() { let mut item = Field(vec![1], VecDeque::from([2]), 0); assert!(ptr::eq(item.as_mut(), &mut item.0)); assert!(ptr::eq(item.as_mut(), &mut item.1)); } #[derive(AsMut)] struct FieldForward(#[as_mut(forward)] T, U); #[test] fn field_forward() { let mut item = FieldForward("test".to_owned(), 0); let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); } #[derive(AsMut)] struct Types(#[as_mut(str)] T, #[as_mut([u8])] U); #[test] fn types() { let mut item = Types("test".to_owned(), vec![0]); let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut [u8] = item.as_mut(); assert!(ptr::eq(rf, item.1.as_mut())); } #[derive(AsMut)] struct TypesWithInner( #[as_mut(Vec, [T])] Vec, #[as_mut(str)] U, ); #[test] fn types_with_inner() { let mut item = TypesWithInner(vec![1i32], "a".to_owned()); let rf: &mut Vec = item.as_mut(); assert!(ptr::eq(rf, &mut item.0)); let rf: &mut [i32] = item.as_mut(); assert!(ptr::eq(rf, item.0.as_mut())); let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.1.as_mut())); } #[derive(AsMut)] struct FieldNonGeneric(#[as_mut([T])] Vec, T); #[test] fn field_non_generic() { let mut item = FieldNonGeneric(vec![], 2i32); assert!(ptr::eq(item.as_mut(), item.0.as_mut())); } } } mod named { use super::*; #[derive(AsMut)] struct Nothing { first: String, second: i32, } #[test] fn nothing() { let mut item = Nothing { first: "test".to_owned(), second: 0, }; assert!(ptr::eq(item.as_mut(), &mut item.first)); assert!(ptr::eq(item.as_mut(), &mut item.second)); } #[derive(AsMut)] struct Skip { first: String, second: i32, #[as_mut(skip)] third: f64, } // Asserts that the macro expansion doesn't generate `AsMut` impl for the skipped field, by // producing trait implementations conflict error during compilation, if it does. impl AsMut for Skip { fn as_mut(&mut self) -> &mut f64 { &mut self.third } } #[test] fn skip() { let mut item = Skip { first: "test".to_owned(), second: 0, third: 0.0, }; assert!(ptr::eq(item.as_mut(), &mut item.first)); assert!(ptr::eq(item.as_mut(), &mut item.second)); } #[derive(AsMut)] struct Field { #[as_mut] first: String, #[as_mut] second: i32, third: f64, } // Asserts that the macro expansion doesn't generate `AsMut` impl for the `third` field, by // producing trait implementations conflict error during compilation, if it does. impl AsMut for Field { fn as_mut(&mut self) -> &mut f64 { &mut self.third } } #[test] fn field() { let mut item = Field { first: "test".to_owned(), second: 0, third: 0.0, }; assert!(ptr::eq(item.as_mut(), &mut item.first)); assert!(ptr::eq(item.as_mut(), &mut item.second)); } #[derive(AsMut)] struct FieldForward { #[as_mut(forward)] first: String, second: i32, } #[test] fn field_forward() { let mut item = FieldForward { first: "test".to_owned(), second: 0, }; let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); } type RenamedString = String; #[derive(AsMut)] struct Types { #[as_mut(str, RenamedString)] first: String, #[as_mut([u8])] second: Vec, } // Asserts that the macro expansion doesn't generate `AsMut` impl for unmentioned type, by // producing trait implementations conflict error during compilation, if it does. impl AsMut> for Types { fn as_mut(&mut self) -> &mut Vec { &mut self.second } } #[test] fn types() { let mut item = Types { first: "test".to_owned(), second: vec![0], }; let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut String = item.as_mut(); assert!(ptr::eq(rf, &mut item.first)); let rf: &mut [u8] = item.as_mut(); assert!(ptr::eq(rf, item.second.as_mut())); } mod generic { use super::*; #[derive(AsMut)] struct Nothing { first: Vec, second: VecDeque, } #[test] fn nothing() { let mut item = Nothing { first: vec![1], second: VecDeque::from([2]), }; assert!(ptr::eq(item.as_mut(), &mut item.first)); assert!(ptr::eq(item.as_mut(), &mut item.second)); } #[derive(AsMut)] struct Skip { first: Vec, second: VecDeque, #[as_mut(skip)] third: V, } #[test] fn skip() { let mut item = Skip { first: vec![1], second: VecDeque::from([2]), third: 0, }; assert!(ptr::eq(item.as_mut(), &mut item.first)); assert!(ptr::eq(item.as_mut(), &mut item.second)); } #[derive(AsMut)] struct Field { #[as_mut] first: Vec, #[as_mut] second: VecDeque, third: V, } #[test] fn field() { let mut item = Field { first: vec![1], second: VecDeque::from([2]), third: 0, }; assert!(ptr::eq(item.as_mut(), &mut item.first)); assert!(ptr::eq(item.as_mut(), &mut item.second)); } #[derive(AsMut)] struct FieldForward { #[as_mut(forward)] first: T, second: U, } #[test] fn field_forward() { let mut item = FieldForward { first: "test".to_owned(), second: 0, }; let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); } #[derive(AsMut)] struct Types { #[as_mut(str)] first: T, #[as_mut([u8])] second: U, } #[test] fn types() { let mut item = Types { first: "test".to_owned(), second: vec![0], }; let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut [u8] = item.as_mut(); assert!(ptr::eq(rf, item.second.as_mut())); } #[derive(AsMut)] struct TypesWithInner { #[as_mut(Vec, [T])] first: Vec, #[as_mut(str)] second: U, } #[test] fn types_inner() { let mut item = TypesWithInner { first: vec![1i32], second: "a".to_owned(), }; let rf: &mut Vec = item.as_mut(); assert!(ptr::eq(rf, &mut item.first)); let rf: &mut [i32] = item.as_mut(); assert!(ptr::eq(rf, item.first.as_mut())); let rf: &mut str = item.as_mut(); assert!(ptr::eq(rf, item.second.as_mut())); } #[derive(AsMut)] struct FieldNonGeneric { #[as_mut([T])] first: Vec, second: T, } #[test] fn field_non_generic() { let mut item = FieldNonGeneric { first: vec![], second: 2i32, }; assert!(ptr::eq(item.as_mut(), item.first.as_mut())); } } } } derive_more-1.0.0/tests/as_ref.rs000064400000000000000000001117521046102023000151000ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::{borrow::ToOwned, collections::VecDeque, string::String, vec, vec::Vec}; #[cfg(feature = "std")] use std::collections::VecDeque; use core::ptr; use derive_more::AsRef; struct Helper(i32, f64, bool); impl AsRef for Helper { fn as_ref(&self) -> &i32 { &self.0 } } impl AsRef for Helper { fn as_ref(&self) -> &f64 { &self.1 } } impl AsRef for Helper { fn as_ref(&self) -> &bool { &self.2 } } struct LifetimeHelper<'a>(&'a i32); impl AsRef for LifetimeHelper<'static> { fn as_ref(&self) -> &i32 { self.0 } } struct ConstParamHelper([i32; N]); impl AsRef<[i32]> for ConstParamHelper<0> { fn as_ref(&self) -> &[i32] { self.0.as_ref() } } mod single_field { use super::*; mod tuple { use super::*; #[derive(AsRef)] struct Nothing(String); #[test] fn nothing() { let item = Nothing("test".to_owned()); assert!(ptr::eq(item.as_ref(), &item.0)); } #[derive(AsRef)] #[as_ref(forward)] struct Forward(String); #[test] fn forward() { let item = Forward("test".to_owned()); let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); } #[derive(AsRef)] struct Field(#[as_ref] String); #[test] fn field() { let item = Field("test".to_owned()); assert!(ptr::eq(item.as_ref(), &item.0)); } #[derive(AsRef)] struct FieldForward(#[as_ref(forward)] String); #[test] fn field_forward() { let item = FieldForward("test".to_owned()); let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); } #[derive(AsRef)] #[as_ref(i32, f64)] struct Types(Helper); // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for Types { fn as_ref(&self) -> &bool { self.0.as_ref() } } // Asserts that the macro expansion doesn't generate an `AsRef` impl for the field type, by // producing a trait implementations conflict error during compilation, if it does. impl AsRef for Types { fn as_ref(&self) -> &Helper { &self.0 } } #[test] fn types() { let item = Types(Helper(1, 2.0, false)); let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &f64 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); } #[derive(AsRef)] #[as_ref(i32, Helper)] struct TypesWithInner(Helper); // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for TypesWithInner { fn as_ref(&self) -> &bool { self.0.as_ref() } } #[test] fn types_with_inner() { let item = TypesWithInner(Helper(1, 2.0, false)); let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &Helper = item.as_ref(); assert!(ptr::eq(rf, &item.0)); } type RenamedFoo = Helper; #[derive(AsRef)] #[as_ref(i32, RenamedFoo)] struct TypesWithRenamedInner(Helper); // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for TypesWithRenamedInner { fn as_ref(&self) -> &bool { self.0.as_ref() } } #[test] fn types_with_renamed_inner() { let item = TypesWithRenamedInner(Helper(1, 2.0, false)); let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &Helper = item.as_ref(); assert!(ptr::eq(rf, &item.0)); } #[derive(AsRef)] struct FieldTypes(#[as_ref(i32, f64)] Helper); // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for FieldTypes { fn as_ref(&self) -> &bool { self.0.as_ref() } } // Asserts that the macro expansion doesn't generate an `AsRef` impl for the field type, by // producing a trait implementations conflict error during compilation, if it does. impl AsRef for FieldTypes { fn as_ref(&self) -> &Helper { &self.0 } } #[test] fn field_types() { let item = FieldTypes(Helper(1, 2.0, false)); let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &f64 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); } #[derive(AsRef)] struct FieldTypesWithInner(#[as_ref(i32, Helper)] Helper); // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for FieldTypesWithInner { fn as_ref(&self) -> &bool { self.0.as_ref() } } #[test] fn field_types_with_inner() { let item = FieldTypesWithInner(Helper(1, 2.0, false)); let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &Helper = item.as_ref(); assert!(ptr::eq(rf, &item.0)); } #[derive(AsRef)] struct FieldTypesWithRenamedInner(#[as_ref(i32, RenamedFoo)] Helper); // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for FieldTypesWithRenamedInner { fn as_ref(&self) -> &bool { self.0.as_ref() } } #[test] fn field_types_with_renamed_inner() { let item = FieldTypesWithRenamedInner(Helper(1, 2.0, false)); let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &Helper = item.as_ref(); assert!(ptr::eq(rf, &item.0)); } mod generic { use super::*; #[derive(AsRef)] struct Nothing(T); #[test] fn nothing() { let item = Nothing("test".to_owned()); assert!(ptr::eq(item.as_ref(), &item.0)); } #[derive(AsRef)] #[as_ref(forward)] struct Forward(T); #[test] fn forward() { let item = Forward("test".to_owned()); let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); } #[derive(AsRef)] struct Field(#[as_ref] T); #[test] fn field() { let item = Field("test".to_owned()); assert!(ptr::eq(item.as_ref(), &item.0)); } #[derive(AsRef)] struct FieldForward(#[as_ref(forward)] T); #[test] fn field_forward() { let item = FieldForward("test".to_owned()); let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); } #[derive(AsRef)] #[as_ref(i32, f64)] struct Types(T); // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding // to the field type, by producing a trait implementations conflict error during // compilation, if it does. impl> AsRef for Types { fn as_ref(&self) -> &bool { self.0.as_ref() } } #[test] fn types() { let item = Types(Helper(1, 2.0, false)); let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &f64 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); } #[derive(AsRef)] #[as_ref(Vec)] struct TypesInner(Vec); #[test] fn types_inner() { let item = TypesInner(vec![1i32]); assert!(ptr::eq(item.as_ref(), &item.0)); } #[derive(AsRef)] struct FieldTypes(#[as_ref(i32, f64)] T); // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding // to the field type, by producing a trait implementations conflict error during // compilation, if it does. impl> AsRef for FieldTypes { fn as_ref(&self) -> &bool { self.0.as_ref() } } #[test] fn field_types() { let item = FieldTypes(Helper(1, 2.0, false)); let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &f64 = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); } #[derive(AsRef)] struct FieldTypesInner(#[as_ref(Vec)] Vec); #[test] fn field_types_inner() { let item = FieldTypesInner(vec![1i32]); assert!(ptr::eq(item.as_ref(), &item.0)); } #[derive(AsRef)] #[as_ref(i32)] struct Lifetime<'a>(LifetimeHelper<'a>); #[test] fn lifetime() { let item = Lifetime(LifetimeHelper(&0)); assert!(ptr::eq(item.as_ref(), item.0.as_ref())); } #[derive(AsRef)] struct FieldLifetime<'a>(#[as_ref(i32)] LifetimeHelper<'a>); #[test] fn field_lifetime() { let item = FieldLifetime(LifetimeHelper(&0)); assert!(ptr::eq(item.as_ref(), item.0.as_ref())); } #[derive(AsRef)] #[as_ref([i32])] struct ConstParam(ConstParamHelper); #[test] fn const_param() { let item = ConstParam(ConstParamHelper([])); assert!(ptr::eq(item.as_ref(), item.0.as_ref())); } #[derive(AsRef)] struct FieldConstParam( #[as_ref([i32])] ConstParamHelper, ); #[test] fn field_const_param() { let item = FieldConstParam(ConstParamHelper([])); assert!(ptr::eq(item.as_ref(), item.0.as_ref())); } } } mod named { use super::*; #[derive(AsRef)] struct Nothing { first: String, } #[test] fn nothing() { let item = Nothing { first: "test".to_owned(), }; assert!(ptr::eq(item.as_ref(), &item.first)); } #[derive(AsRef)] #[as_ref(forward)] struct Forward { first: String, } #[test] fn forward() { let item = Forward { first: "test".to_owned(), }; let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); } #[derive(AsRef)] struct Field { #[as_ref] first: String, } #[test] fn field() { let item = Field { first: "test".to_owned(), }; assert!(ptr::eq(item.as_ref(), &item.first)); } #[derive(AsRef)] struct FieldForward { #[as_ref(forward)] first: String, } #[test] fn field_forward() { let item = FieldForward { first: "test".to_owned(), }; let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); } #[derive(AsRef)] #[as_ref(i32, f64)] struct Types { first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for Types { fn as_ref(&self) -> &bool { self.first.as_ref() } } // Asserts that the macro expansion doesn't generate an `AsRef` impl for the field type, by // producing a trait implementations conflict error during compilation, if it does. impl AsRef for Types { fn as_ref(&self) -> &Helper { &self.first } } #[test] fn types() { let item = Types { first: Helper(1, 2.0, false), }; let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &f64 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); } #[derive(AsRef)] #[as_ref(i32, Helper)] struct TypesWithInner { first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for TypesWithInner { fn as_ref(&self) -> &bool { self.first.as_ref() } } #[test] fn types_with_inner() { let item = TypesWithInner { first: Helper(1, 2.0, false), }; let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &Helper = item.as_ref(); assert!(ptr::eq(rf, &item.first)); } type RenamedFoo = Helper; #[derive(AsRef)] #[as_ref(i32, RenamedFoo)] struct TypesWithRenamedInner { first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for TypesWithRenamedInner { fn as_ref(&self) -> &bool { self.first.as_ref() } } #[test] fn types_with_renamed_inner() { let item = TypesWithRenamedInner { first: Helper(1, 2.0, false), }; let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &Helper = item.as_ref(); assert!(ptr::eq(rf, &item.first)); } #[derive(AsRef)] struct FieldTypes { #[as_ref(i32, f64)] first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for FieldTypes { fn as_ref(&self) -> &bool { self.first.as_ref() } } // Asserts that the macro expansion doesn't generate an `AsRef` impl for the field type, by // producing a trait implementations conflict error during compilation, if it does. impl AsRef for FieldTypes { fn as_ref(&self) -> &Helper { &self.first } } #[test] fn field_types() { let item = FieldTypes { first: Helper(1, 2.0, false), }; let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &f64 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); } #[derive(AsRef)] struct FieldTypesWithInner { #[as_ref(i32, Helper)] first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for FieldTypesWithInner { fn as_ref(&self) -> &bool { self.first.as_ref() } } #[test] fn field_types_with_inner() { let item = FieldTypesWithInner { first: Helper(1, 2.0, false), }; let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &Helper = item.as_ref(); assert!(ptr::eq(rf, &item.first)); } #[derive(AsRef)] struct FieldTypesWithRenamedInner { #[as_ref(i32, RenamedFoo)] first: Helper, } // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding to // the field type, by producing a trait implementations conflict error during compilation, // if it does. impl AsRef for FieldTypesWithRenamedInner { fn as_ref(&self) -> &bool { self.first.as_ref() } } #[test] fn field_types_with_renamed_inner() { let item = FieldTypesWithRenamedInner { first: Helper(1, 2.0, false), }; let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &Helper = item.as_ref(); assert!(ptr::eq(rf, &item.first)); } mod generic { use super::*; #[derive(AsRef)] struct Nothing { first: T, } #[test] fn nothing() { let item = Nothing { first: "test".to_owned(), }; assert!(ptr::eq(item.as_ref(), &item.first)); } #[derive(AsRef)] #[as_ref(forward)] struct Forward { first: T, } #[test] fn forward() { let item = Forward { first: "test".to_owned(), }; let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); } #[derive(AsRef)] struct Field { #[as_ref] first: T, } #[test] fn field() { let item = Field { first: "test".to_owned(), }; assert!(ptr::eq(item.as_ref(), &item.first)); } #[derive(AsRef)] struct FieldForward { #[as_ref(forward)] first: T, } #[test] fn field_forward() { let item = FieldForward { first: "test".to_owned(), }; let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); } #[derive(AsRef)] #[as_ref(i32, f64)] struct Types { first: T, } // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding // to the field type, by producing a trait implementations conflict error during // compilation, if it does. impl> AsRef for Types { fn as_ref(&self) -> &bool { self.first.as_ref() } } #[test] fn types() { let item = Types { first: Helper(1, 2.0, false), }; let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &f64 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); } #[derive(AsRef)] #[as_ref(Vec)] struct TypesInner { first: Vec, } #[test] fn types_inner() { let item = TypesInner { first: vec![1i32] }; assert!(ptr::eq(item.as_ref(), &item.first)); } #[derive(AsRef)] struct FieldTypes { #[as_ref(i32, f64)] first: T, } // Asserts that the macro expansion doesn't generate a blanket `AsRef` impl forwarding // to the field type, by producing a trait implementations conflict error during // compilation, if it does. impl> AsRef for FieldTypes { fn as_ref(&self) -> &bool { self.first.as_ref() } } #[test] fn field_types() { let item = FieldTypes { first: Helper(1, 2.0, false), }; let rf: &i32 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &f64 = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); } #[derive(AsRef)] struct FieldTypesInner { #[as_ref(Vec)] first: Vec, } #[test] fn field_types_inner() { let item = FieldTypesInner { first: vec![1i32] }; assert!(ptr::eq(item.as_ref(), &item.first)); } #[derive(AsRef)] #[as_ref(i32)] struct Lifetime<'a> { first: LifetimeHelper<'a>, } #[test] fn lifetime() { let item = Lifetime { first: LifetimeHelper(&0), }; assert!(ptr::eq(item.as_ref(), item.first.as_ref())); } #[derive(AsRef)] struct FieldLifetime<'a> { #[as_ref(i32)] first: LifetimeHelper<'a>, } #[test] fn field_lifetime() { let item = FieldLifetime { first: LifetimeHelper(&0), }; assert!(ptr::eq(item.as_ref(), item.first.as_ref())); } #[derive(AsRef)] #[as_ref([i32])] struct ConstParam { first: ConstParamHelper, } #[test] fn const_param() { let item = ConstParam { first: ConstParamHelper([]), }; assert!(ptr::eq(item.as_ref(), item.first.as_ref())); } #[derive(AsRef)] struct FieldConstParam { #[as_ref([i32])] first: ConstParamHelper, } #[test] fn field_const_param() { let item = FieldConstParam { first: ConstParamHelper([]), }; assert!(ptr::eq(item.as_ref(), item.first.as_ref())); } } } } mod multi_field { use super::*; mod tuple { use super::*; #[derive(AsRef)] struct Nothing(String, i32); #[test] fn nothing() { let item = Nothing("test".to_owned(), 0); assert!(ptr::eq(item.as_ref(), &item.0)); assert!(ptr::eq(item.as_ref(), &item.1)); } #[derive(AsRef)] struct Skip(String, i32, #[as_ref(skip)] f64); // Asserts that the macro expansion doesn't generate `AsRef` impl for the skipped field, by // producing trait implementations conflict error during compilation, if it does. impl AsRef for Skip { fn as_ref(&self) -> &f64 { &self.2 } } #[test] fn skip() { let item = Skip("test".to_owned(), 0, 0.0); assert!(ptr::eq(item.as_ref(), &item.0)); assert!(ptr::eq(item.as_ref(), &item.1)); } #[derive(AsRef)] struct Field(#[as_ref] String, #[as_ref] i32, f64); // Asserts that the macro expansion doesn't generate `AsRef` impl for the third field, by // producing trait implementations conflict error during compilation, if it does. impl AsRef for Field { fn as_ref(&self) -> &f64 { &self.2 } } #[test] fn field() { let item = Field("test".to_owned(), 0, 0.0); assert!(ptr::eq(item.as_ref(), &item.0)); assert!(ptr::eq(item.as_ref(), &item.1)); } #[derive(AsRef)] struct FieldForward(#[as_ref(forward)] String, i32); #[test] fn field_forward() { let item = FieldForward("test".to_owned(), 0); let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); } type RenamedString = String; #[derive(AsRef)] struct Types( #[as_ref(str, RenamedString)] String, #[as_ref([u8])] Vec, ); // Asserts that the macro expansion doesn't generate `AsRef` impl for the field type, by // producing trait implementations conflict error during compilation, if it does. impl AsRef> for Types { fn as_ref(&self) -> &Vec { &self.1 } } #[test] fn types() { let item = Types("test".to_owned(), vec![0]); let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &String = item.as_ref(); assert!(ptr::eq(rf, &item.0)); let rf: &[u8] = item.as_ref(); assert!(ptr::eq(rf, item.1.as_ref())); } mod generic { use super::*; #[derive(AsRef)] struct Nothing(Vec, VecDeque); #[test] fn nothing() { let item = Nothing(vec![1], VecDeque::from([2])); assert!(ptr::eq(item.as_ref(), &item.0)); assert!(ptr::eq(item.as_ref(), &item.1)); } #[derive(AsRef)] struct Skip(Vec, VecDeque, #[as_ref(skip)] V); #[test] fn skip() { let item = Skip(vec![1], VecDeque::from([2]), 0); assert!(ptr::eq(item.as_ref(), &item.0)); assert!(ptr::eq(item.as_ref(), &item.1)); } #[derive(AsRef)] struct Field(#[as_ref] Vec, #[as_ref] VecDeque, V); #[test] fn field() { let item = Field(vec![1], VecDeque::from([2]), 0); assert!(ptr::eq(item.as_ref(), &item.0)); assert!(ptr::eq(item.as_ref(), &item.1)); } #[derive(AsRef)] struct FieldForward(#[as_ref(forward)] T, U); #[test] fn field_forward() { let item = FieldForward("test".to_owned(), 0); let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); } #[derive(AsRef)] struct Types(#[as_ref(str)] T, #[as_ref([u8])] U); #[test] fn types() { let item = Types("test".to_owned(), vec![0u8]); let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &[u8] = item.as_ref(); assert!(ptr::eq(rf, item.1.as_ref())); } #[derive(AsRef)] struct TypesWithInner( #[as_ref(Vec, [T])] Vec, #[as_ref(str)] U, ); #[test] fn types_with_inner() { let item = TypesWithInner(vec![1i32], "a".to_owned()); let rf: &Vec = item.as_ref(); assert!(ptr::eq(rf, &item.0)); let rf: &[i32] = item.as_ref(); assert!(ptr::eq(rf, item.0.as_ref())); let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.1.as_ref())); } #[derive(AsRef)] struct FieldNonGeneric(#[as_ref([T])] Vec, T); #[test] fn field_non_generic() { let item = FieldNonGeneric(vec![], 2i32); assert!(ptr::eq(item.as_ref(), item.0.as_ref())); } } } mod named { use super::*; #[derive(AsRef)] struct Nothing { first: String, second: i32, } #[test] fn nothing() { let item = Nothing { first: "test".to_owned(), second: 0, }; assert!(ptr::eq(item.as_ref(), &item.first)); assert!(ptr::eq(item.as_ref(), &item.second)); } #[derive(AsRef)] struct Skip { first: String, second: i32, #[as_ref(skip)] third: f64, } // Asserts that the macro expansion doesn't generate `AsRef` impl for the skipped field, by // producing trait implementations conflict error during compilation, if it does. impl AsRef for Skip { fn as_ref(&self) -> &f64 { &self.third } } #[test] fn skip() { let item = Skip { first: "test".to_owned(), second: 0, third: 0.0, }; assert!(ptr::eq(item.as_ref(), &item.first)); assert!(ptr::eq(item.as_ref(), &item.second)); } #[derive(AsRef)] struct Field { #[as_ref] first: String, #[as_ref] second: i32, third: f64, } // Asserts that the macro expansion doesn't generate `AsRef` impl for the `third` field, by // producing trait implementations conflict error during compilation, if it does. impl AsRef for Field { fn as_ref(&self) -> &f64 { &self.third } } #[test] fn field() { let item = Field { first: "test".to_owned(), second: 0, third: 0.0, }; assert!(ptr::eq(item.as_ref(), &item.first)); assert!(ptr::eq(item.as_ref(), &item.second)); } #[derive(AsRef)] struct FieldForward { #[as_ref(forward)] first: String, second: i32, } #[test] fn field_forward() { let item = FieldForward { first: "test".to_owned(), second: 0, }; let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); } type RenamedString = String; #[derive(AsRef)] struct Types { #[as_ref(str, RenamedString)] first: String, #[as_ref([u8])] second: Vec, } // Asserts that the macro expansion doesn't generate `AsRef` impl for the field type, by // producing trait implementations conflict error during compilation, if it does. impl AsRef> for Types { fn as_ref(&self) -> &Vec { &self.second } } #[test] fn types() { let item = Types { first: "test".to_owned(), second: vec![0u8], }; let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &String = item.as_ref(); assert!(ptr::eq(rf, &item.first)); let rf: &[u8] = item.as_ref(); assert!(ptr::eq(rf, item.second.as_ref())); } mod generic { use super::*; #[derive(AsRef)] struct Nothing { first: Vec, second: VecDeque, } #[test] fn nothing() { let item = Nothing { first: vec![1], second: VecDeque::from([2]), }; assert!(ptr::eq(item.as_ref(), &item.first)); assert!(ptr::eq(item.as_ref(), &item.second)); } #[derive(AsRef)] struct Skip { first: Vec, second: VecDeque, #[as_ref(skip)] third: V, } #[test] fn skip() { let item = Skip { first: vec![1], second: VecDeque::from([2]), third: 0, }; assert!(ptr::eq(item.as_ref(), &item.first)); assert!(ptr::eq(item.as_ref(), &item.second)); } #[derive(AsRef)] struct Field { #[as_ref] first: Vec, #[as_ref] second: VecDeque, third: V, } #[test] fn field() { let item = Field { first: vec![1], second: VecDeque::from([2]), third: 0, }; assert!(ptr::eq(item.as_ref(), &item.first)); assert!(ptr::eq(item.as_ref(), &item.second)); } #[derive(AsRef)] struct FieldForward { #[as_ref(forward)] first: T, second: U, } #[test] fn field_forward() { let item = FieldForward { first: "test".to_owned(), second: 0, }; let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); } #[derive(AsRef)] struct Types { #[as_ref(str)] first: T, #[as_ref([u8])] second: U, } #[test] fn types() { let item = Types { first: "test".to_owned(), second: vec![0u8], }; let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &[u8] = item.as_ref(); assert!(ptr::eq(rf, item.second.as_ref())); } #[derive(AsRef)] struct TypesWithInner { #[as_ref(Vec, [T])] first: Vec, #[as_ref(str)] second: U, } #[test] fn types_with_inner() { let item = TypesWithInner { first: vec![1i32], second: "a".to_owned(), }; let rf: &Vec = item.as_ref(); assert!(ptr::eq(rf, &item.first)); let rf: &[i32] = item.as_ref(); assert!(ptr::eq(rf, item.first.as_ref())); let rf: &str = item.as_ref(); assert!(ptr::eq(rf, item.second.as_ref())); } #[derive(AsRef)] struct FieldNonGeneric { #[as_ref([T])] first: Vec, second: T, } #[test] fn field_non_generic() { let item = FieldNonGeneric { first: vec![], second: 2i32, }; assert!(ptr::eq(item.as_ref(), item.first.as_ref())); } } } } derive_more-1.0.0/tests/boats_display_derive.rs000064400000000000000000000025711046102023000200320ustar 00000000000000// The following code is from https://github.com/withoutboats/display_derive/blob/232a32ee19e262aacbd2c93be5b4ce9e89a5fc30/tests/tests.rs // Written by without boats originally use derive_more::Display; #[derive(Display)] #[display("An error has occurred.")] struct UnitError; #[test] fn unit_struct() { let s = UnitError.to_string(); assert_eq!(s, "An error has occurred."); } #[derive(Display)] #[display("Error code: {}", code)] struct RecordError { code: u32, } #[test] fn record_struct() { let s = RecordError { code: 0 }.to_string(); assert_eq!(s, "Error code: 0"); } #[derive(Display)] #[display("Error code: {}", _0)] struct TupleError(i32); #[test] fn tuple_struct() { let s = TupleError(2).to_string(); assert_eq!(s, "Error code: 2"); } #[allow(clippy::enum_variant_names)] // because of the original source #[derive(Display)] enum EnumError { #[display("Error code: {}", code)] StructVariant { code: i32 }, #[display("Error: {}", _0)] TupleVariant(&'static str), #[display("An error has occurred.")] UnitVariant, } #[test] fn enum_error() { let s = EnumError::StructVariant { code: 2 }.to_string(); assert_eq!(s, "Error code: 2"); let s = EnumError::TupleVariant("foobar").to_string(); assert_eq!(s, "Error: foobar"); let s = EnumError::UnitVariant.to_string(); assert_eq!(s, "An error has occurred."); } derive_more-1.0.0/tests/compile_fail/as_mut/enum.rs000064400000000000000000000001251046102023000205070ustar 00000000000000#[derive(derive_more::AsMut)] enum Foo { Bar(i32), Baz(i32), } fn main() {} derive_more-1.0.0/tests/compile_fail/as_mut/multiple_field_attrs.rs000064400000000000000000000001561046102023000237620ustar 00000000000000#[derive(derive_more::AsMut)] struct Foo { #[as_mut] #[as_mut(forward)] bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_mut/multiple_struct_attrs.rs000064400000000000000000000001571046102023000242240ustar 00000000000000#[derive(derive_more::AsMut)] #[as_mut(forward)] #[as_mut(forward)] struct Foo { bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_mut/renamed_generic.rs000064400000000000000000000003151046102023000226530ustar 00000000000000struct Foo(T); type Bar = Foo; #[derive(derive_more::AsMut)] #[as_mut(Bar)] struct Baz(Foo); fn main() { let mut item = Baz(Foo(1i32)); let _: &mut Bar = item.as_mut(); } derive_more-1.0.0/tests/compile_fail/as_mut/skip_and_others.rs000064400000000000000000000001731046102023000227220ustar 00000000000000#[derive(derive_more::AsMut)] struct Foo { #[as_mut] bar: i32, #[as_mut(ignore)] baz: f32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_mut/struct_and_field.rs000064400000000000000000000001521046102023000230540ustar 00000000000000#[derive(derive_more::AsMut)] #[as_mut(forward)] struct Foo { #[as_mut] bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_mut/struct_attr_empty.rs000064400000000000000000000001131046102023000233340ustar 00000000000000#[derive(derive_more::AsMut)] #[as_mut(forward)] struct Foo; fn main() {} derive_more-1.0.0/tests/compile_fail/as_mut/struct_attr_multiple_fields.rs000064400000000000000000000001521046102023000253620ustar 00000000000000#[derive(derive_more::AsMut)] #[as_mut(forward)] struct Foo { bar: i32, baz: f32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_mut/struct_attr_tuple.rs000064400000000000000000000001551046102023000233350ustar 00000000000000#[derive(derive_more::AsMut)] #[as_mut((i32, f32))] struct Foo { bar: i32, baz: f32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_mut/union.rs000064400000000000000000000001241046102023000206720ustar 00000000000000#[derive(derive_more::AsMut)] union Foo { f1: u32, f2: f32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_mut/unknown_field_attr_arg.rs000064400000000000000000000001341046102023000242700ustar 00000000000000#[derive(derive_more::AsMut)] struct Foo { #[as_mut(baz)] bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_mut/unknown_struct_attr_arg.rs000064400000000000000000000001301046102023000245250ustar 00000000000000#[derive(derive_more::AsMut)] #[as_mut(baz)] struct Foo { bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/enum.rs000064400000000000000000000001251046102023000204560ustar 00000000000000#[derive(derive_more::AsRef)] enum Foo { Bar(i32), Baz(i32), } fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/multiple_field_attrs.rs000064400000000000000000000001561046102023000237310ustar 00000000000000#[derive(derive_more::AsRef)] struct Foo { #[as_ref] #[as_ref(forward)] bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/multiple_struct_attrs.rs000064400000000000000000000001571046102023000241730ustar 00000000000000#[derive(derive_more::AsRef)] #[as_ref(forward)] #[as_ref(forward)] struct Foo { bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/renamed_generic.rs000064400000000000000000000003051046102023000226210ustar 00000000000000struct Foo(T); type Bar = Foo; #[derive(derive_more::AsRef)] #[as_ref(Bar)] struct Baz(Foo); fn main() { let item = Baz(Foo(1i32)); let _: &Bar = item.as_ref(); } derive_more-1.0.0/tests/compile_fail/as_ref/skip_and_others.rs000064400000000000000000000001711046102023000226670ustar 00000000000000#[derive(derive_more::AsRef)] struct Foo { #[as_ref] bar: i32, #[as_ref(skip)] baz: f32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/struct_and_field.rs000064400000000000000000000001521046102023000230230ustar 00000000000000#[derive(derive_more::AsRef)] #[as_ref(forward)] struct Foo { #[as_ref] bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/struct_attr_empty.rs000064400000000000000000000001131046102023000233030ustar 00000000000000#[derive(derive_more::AsRef)] #[as_ref(forward)] struct Foo; fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/struct_attr_multiple_fields.rs000064400000000000000000000001521046102023000253310ustar 00000000000000#[derive(derive_more::AsRef)] #[as_ref(forward)] struct Foo { bar: i32, baz: f32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/struct_attr_tuple.rs000064400000000000000000000001551046102023000233040ustar 00000000000000#[derive(derive_more::AsRef)] #[as_ref((i32, f32))] struct Foo { bar: i32, baz: f32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/union.rs000064400000000000000000000001241046102023000206410ustar 00000000000000#[derive(derive_more::AsRef)] union Foo { f1: u32, f2: f32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/unknown_field_attr_arg.rs000064400000000000000000000001341046102023000242370ustar 00000000000000#[derive(derive_more::AsRef)] struct Foo { #[as_ref(baz)] bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/as_ref/unknown_struct_attr_arg.rs000064400000000000000000000001301046102023000244740ustar 00000000000000#[derive(derive_more::AsRef)] #[as_ref(baz)] struct Foo { bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/both_fmt_and_skip_on_field.rs000064400000000000000000000002061046102023000246520ustar 00000000000000#[derive(derive_more::Debug)] pub struct Foo { #[debug("Stuff({}): {}", bar)] #[debug(skip)] bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/duplicate_fmt_on_struct.rs000064400000000000000000000001421046102023000242600ustar 00000000000000#[derive(derive_more::Debug)] #[debug("Test")] #[debug("Second")] pub struct Foo {} fn main() {} derive_more-1.0.0/tests/compile_fail/debug/duplicate_fmt_on_variant.rs000064400000000000000000000001631046102023000244030ustar 00000000000000#[derive(derive_more::Debug)] pub enum Foo { #[debug("Test")] #[debug("Second")] Unit, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/extra_placeholder.rs000064400000000000000000000001631046102023000230300ustar 00000000000000#[derive(derive_more::Debug)] pub struct Foo { #[debug("Stuff({}): {}", bar)] bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/fmt_on_container_and_field_simultaneously.rs000064400000000000000000000001701046102023000300270ustar 00000000000000#[derive(derive_more::Debug)] #[debug("{bar}")] pub struct Foo { #[debug("{bar}")] bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/fmt_on_enum.rs000064400000000000000000000001271046102023000216510ustar 00000000000000#[derive(derive_more::Debug)] #[debug("Test")] pub enum Foo { Unit } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/legacy_bound_syntax.rs000064400000000000000000000001761046102023000234100ustar 00000000000000#[derive(derive_more::Debug)] #[debug(bound = "String: std::fmt::Display")] pub struct Foo { bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/legacy_fmt_syntax.rs000064400000000000000000000003261046102023000230640ustar 00000000000000#[derive(derive_more::Debug)] pub struct Foo { #[debug(fmt = "Stuff({}): {}", "bar")] bar: String, } #[derive(derive_more::Debug)] #[debug(fmt = "Stuff({}): {}", _0)] pub struct Bar(String); fn main() {} derive_more-1.0.0/tests/compile_fail/debug/lifetime_no_debug.rs000064400000000000000000000002071046102023000230020ustar 00000000000000struct NoDebug<'a> { a: &'a f64, } #[derive(derive_more::Debug)] struct SomeType<'a> { no_debug: NoDebug<'a>, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/missing_placeholder.rs000064400000000000000000000001551046102023000233570ustar 00000000000000#[derive(derive_more::Debug)] pub struct Foo { #[debug("Stuff()", bar)] bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/named_field_prefixed_with_dot.rs000064400000000000000000000001601046102023000253560ustar 00000000000000#[derive(derive_more::Debug)] pub struct Foo { #[debug("Stuff({})", .bar)] bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/unclosed_brace.rs000064400000000000000000000001561046102023000223150ustar 00000000000000#[derive(derive_more::Debug)] pub struct Foo { #[debug("Stuff({)", bar)] bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/union.rs000064400000000000000000000001141046102023000204670ustar 00000000000000#[derive(derive_more::Debug)] pub union Foo { bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/unknown_attribute.rs000064400000000000000000000001561046102023000231270ustar 00000000000000#[derive(derive_more::Debug)] #[debug(unknown = "unknown")] pub struct Foo { bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/unnamed_field_prefixed_with_dot.rs000064400000000000000000000001361046102023000257240ustar 00000000000000#[derive(derive_more::Debug)] pub struct Foo(#[debug("Stuff({})", .0)] String); fn main() {} derive_more-1.0.0/tests/compile_fail/debug/wrong_formatting_argument.rs000064400000000000000000000001571046102023000246360ustar 00000000000000#[derive(derive_more::Debug)] pub struct Foo { #[debug("Stuff({bar:M})")] bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/wrong_named_parameter.rs000064400000000000000000000001561046102023000237050ustar 00000000000000#[derive(derive_more::Debug)] pub struct Foo { #[debug("Stuff({bars})")] bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/debug/wrong_unnamed_parameter.rs000064400000000000000000000001341046102023000242440ustar 00000000000000#[derive(derive_more::Debug)] pub struct Foo(#[debug("Stuff({_1})")] String); fn main() {} derive_more-1.0.0/tests/compile_fail/display/extra_placeholder.rs000064400000000000000000000001631046102023000234070ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({}): {}", bar)] pub struct Foo { bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/legacy_bound_syntax.rs000064400000000000000000000002021046102023000237550ustar 00000000000000#[derive(derive_more::Display)] #[display(bound = "String: std::fmt::Display")] pub struct Foo { bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/legacy_fmt_syntax.rs000064400000000000000000000003321046102023000234400ustar 00000000000000#[derive(derive_more::Display)] #[display(fmt = "Stuff({}): {}", "bar")] pub struct Foo { bar: String, } #[derive(derive_more::Display)] #[display(fmt = "Stuff({}): {}", _0)] pub struct Bar(String); fn main() {} derive_more-1.0.0/tests/compile_fail/display/missing_placeholder.rs000064400000000000000000000001551046102023000237360ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff()", bar)] pub struct Foo { bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/mutlifield_enum_variant_without_attribute.rs000064400000000000000000000001461046102023000304770ustar 00000000000000#[derive(derive_more::Display)] enum Enum { Variant { foo: String, bar: String }, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/mutlifield_struct_without_attribute.rs000064400000000000000000000001431046102023000273300ustar 00000000000000#[derive(derive_more::Display)] pub struct Foo { foo: String, bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/named_field_prefixed_with_dot.rs000064400000000000000000000001601046102023000257350ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({})", .bar)] pub struct Foo { bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/non_display_implicit_enum_unit_variant.rs000064400000000000000000000001441046102023000277410ustar 00000000000000#[derive(derive_more::Display, derive_more::UpperHex)] enum Enum { UnitVariant, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/shared_format_positional_placeholders.rs000064400000000000000000000003751046102023000275330ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({})")] enum Foo { A, } #[derive(derive_more::Display)] #[display("Stuff({0})")] enum Foo2 { A, } #[derive(derive_more::Display)] #[display("Stuff()", _0, _2)] enum Foo3 { A, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/shared_format_unclosed_brace.rs000064400000000000000000000001311046102023000255630ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({)")] enum Foo { A, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/shared_format_variant_spec.rs000064400000000000000000000001441046102023000252750ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({_variant:?})")] enum Foo { A, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/unclosed_brace.rs000064400000000000000000000001561046102023000226740ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({)", bar)] pub struct Foo { bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/unknown_attribute.rs000064400000000000000000000002171046102023000235040ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({})", bar)] #[display(unknown = "unknown")] pub struct Foo { bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/unnamed_field_prefixed_with_dot.rs000064400000000000000000000001421046102023000263000ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({})", .0)] pub struct Foo(String); fn main() {} derive_more-1.0.0/tests/compile_fail/display/wrong_formatting_argument.rs000064400000000000000000000001611046102023000252100ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({:M})", bar)] pub struct Foo { bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/wrong_named_parameter.rs000064400000000000000000000001561046102023000242640ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({bars})")] pub struct Foo { bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/display/wrong_unnamed_parameter.rs000064400000000000000000000001401046102023000246200ustar 00000000000000#[derive(derive_more::Display)] #[display("Stuff({_1})")] pub struct Foo(String); fn main() {} derive_more-1.0.0/tests/compile_fail/from/legacy_enum_attribute.rs000064400000000000000000000001511046102023000235700ustar 00000000000000#[derive(derive_more::From)] enum Foo { #[from(types(i32, "&str"))] Bar(String), } fn main() {} derive_more-1.0.0/tests/compile_fail/from/legacy_struct_attribute.rs000064400000000000000000000001701046102023000241510ustar 00000000000000#[derive(derive_more::From)] #[from(types(i32, "&str"))] struct Foo { foo: String, bar: String, } fn main() {} derive_more-1.0.0/tests/compile_fail/from/multiple_enum_attributes.rs000064400000000000000000000001541046102023000243450ustar 00000000000000#[derive(derive_more::From)] enum Foo { #[from(i32)] #[from(forward)] Bar(i32), } fn main() {} derive_more-1.0.0/tests/compile_fail/from/multiple_struct_attributes.rs000064400000000000000000000001321046102023000247210ustar 00000000000000#[derive(derive_more::From)] #[from(i32)] #[from(forward)] struct Foo(i32); fn main() {} derive_more-1.0.0/tests/compile_fail/from/struct_tuple_no_parens.rs000064400000000000000000000001461046102023000240220ustar 00000000000000#[derive(derive_more::From)] #[from(i16, i16)] struct Point { x: i32, y: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/from/struct_tuple_too_long.rs000064400000000000000000000001551046102023000236560ustar 00000000000000#[derive(derive_more::From)] #[from((i16, i16, i16))] struct Point { x: i32, y: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/from/struct_tuple_too_short.rs000064400000000000000000000001441046102023000240540ustar 00000000000000#[derive(derive_more::From)] #[from((i16,))] struct Point { x: i32, y: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/from/union.rs000064400000000000000000000001131046102023000203430ustar 00000000000000#[derive(derive_more::From)] pub union Foo { bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/into/enum.rs000064400000000000000000000001061046102023000201670ustar 00000000000000#[derive(derive_more::Into)] enum Foo { Foo(i32), } fn main() {} derive_more-1.0.0/tests/compile_fail/into/legacy_complex_attribute.rs000064400000000000000000000002061046102023000243020ustar 00000000000000#[derive(derive_more::Into)] #[into(owned(types("Cow<'_ str>")), ref, ref_mut, types(i32, "&str"))] struct Foo(String); fn main() {} derive_more-1.0.0/tests/compile_fail/into/legacy_types_attribute.rs000064400000000000000000000001331046102023000237760ustar 00000000000000#[derive(derive_more::Into)] #[into(types(i32, "&str"))] struct Foo(String); fn main() {} derive_more-1.0.0/tests/compile_fail/into/mixed_field_skip_types.rs000064400000000000000000000001351046102023000237500ustar 00000000000000#[derive(derive_more::Into)] struct Foo { #[into(skip, i32)] a: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/into/mixed_regular_and_wrapped_types.rs000064400000000000000000000001461046102023000256460ustar 00000000000000#[derive(derive_more::Into)] #[into(owned, ref(i32), i32)] struct Foo { bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/into/multiple_skip.rs000064400000000000000000000001521046102023000221050ustar 00000000000000#[derive(derive_more::Into)] struct Foo { #[into(skip)] #[into(skip)] a: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/into/tuple_no_parens.rs000064400000000000000000000001461046102023000224240ustar 00000000000000#[derive(derive_more::Into)] #[into(i16, i16)] struct Point { x: i32, y: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/into/tuple_too_long.rs000064400000000000000000000001551046102023000222600ustar 00000000000000#[derive(derive_more::Into)] #[into((i16, i16, i16))] struct Point { x: i32, y: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/into/tuple_too_short.rs000064400000000000000000000001441046102023000224560ustar 00000000000000#[derive(derive_more::Into)] #[into((i16,))] struct Point { x: i32, y: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/into/union.rs000064400000000000000000000001131046102023000203510ustar 00000000000000#[derive(derive_more::Into)] pub union Foo { bar: i32, } fn main() {} derive_more-1.0.0/tests/compile_fail/is_variant/must_use.rs000064400000000000000000000002361046102023000222610ustar 00000000000000#[derive(derive_more::IsVariant)] enum MustUse { Yes, } #[forbid(unused_must_use)] fn main() { let must_use = MustUse::Yes; must_use.is_yes(); } derive_more-1.0.0/tests/compile_fail/mod.rs000064400000000000000000000002161046102023000170330ustar 00000000000000#[rustversion::stable] #[test] fn compile_fail() { let t = trybuild::TestCases::new(); t.compile_fail("tests/compile_fail/*/*.rs"); } derive_more-1.0.0/tests/compile_fail/try_from/invalid_repr.rs000064400000000000000000000001271046102023000225740ustar 00000000000000#[derive(derive_more::TryFrom)] #[repr(a + b)] enum Enum { Variant } fn main() {} derive_more-1.0.0/tests/compile_fail/try_from/struct.rs000064400000000000000000000000751046102023000214440ustar 00000000000000#[derive(derive_more::TryFrom)] struct Struct; fn main() {} derive_more-1.0.0/tests/compile_fail/try_from/union.rs000064400000000000000000000001161046102023000212440ustar 00000000000000#[derive(derive_more::TryFrom)] union Union { field: i32, } fn main() {} derive_more-1.0.0/tests/constructor.rs000064400000000000000000000011761046102023000162240ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use derive_more::Constructor; #[derive(Constructor)] struct EmptyTuple(); const EMPTY_TUPLE: EmptyTuple = EmptyTuple::new(); #[derive(Constructor)] struct EmptyStruct {} const EMPTY_STRUCT: EmptyStruct = EmptyStruct::new(); #[derive(Constructor)] struct EmptyUnit; const EMPTY_UNIT: EmptyUnit = EmptyUnit::new(); #[derive(Constructor)] struct MyInts(i32, i32); const MY_INTS: MyInts = MyInts::new(1, 2); #[derive(Constructor)] struct Point2D { x: i32, y: i32, } const POINT_2D: Point2D = Point2D::new(-4, 7); derive_more-1.0.0/tests/debug.rs000064400000000000000000001755221046102023000147340ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; mod structs { mod unit { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Unit; #[derive(Debug)] struct Tuple(); #[derive(Debug)] struct Struct {} #[test] fn assert() { assert_eq!(format!("{:?}", Unit), "Unit"); assert_eq!(format!("{:#?}", Unit), "Unit"); assert_eq!(format!("{:?}", Tuple()), "Tuple"); assert_eq!(format!("{:#?}", Tuple()), "Tuple"); assert_eq!(format!("{:?}", Struct {}), "Struct"); assert_eq!(format!("{:#?}", Struct {}), "Struct"); } mod interpolated_struct { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] #[debug("Format String")] struct Unit; #[test] fn assert() { assert_eq!(format!("{Unit:?}"), "Format String"); } } mod transparency { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; const I32: i32 = 11; const F64: f64 = 3.15; const POINTER: &f64 = &3.15; #[derive(Debug)] #[debug("{I32}")] struct Display; #[derive(Debug)] #[debug("{I32:?}")] struct StructDebug; #[derive(Debug)] #[debug("{:b}", I32)] struct Binary; #[derive(Debug)] #[debug("{0:o}", I32)] struct Octal; #[derive(Debug)] #[debug("{I32:x}")] struct LowerHex; #[derive(Debug)] #[debug("{:X}", I32)] struct UpperHex; #[derive(Debug)] #[debug("{F64:e}")] struct LowerExp; #[derive(Debug)] #[debug("{named:E}", named = F64)] struct UpperExp; #[derive(Debug)] #[debug("{POINTER:p}")] struct Pointer; #[test] fn assert() { assert_eq!(format!("{:03?}", Display), "011"); assert_eq!(format!("{:03?}", StructDebug), "011"); assert_eq!(format!("{:07?}", Binary), "0001011"); assert_eq!(format!("{:07?}", Octal), "0000013"); assert_eq!(format!("{:03?}", LowerHex), "00b"); assert_eq!(format!("{:03?}", UpperHex), "00B"); assert_eq!(format!("{:07?}", LowerExp), "03.15e0"); assert_eq!(format!("{:07?}", UpperExp), "03.15E0"); assert_eq!(format!("{:018?}", Pointer), format!("{POINTER:018p}")); } mod omitted { mod on_modifiers { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; const I32: i32 = 11; const F64: f64 = 3.15; #[derive(Debug)] #[debug("{I32:x?}")] struct LowerDebug; #[derive(Debug)] #[debug("{I32:X?}")] struct UpperDebug; #[derive(Debug)] #[debug("{:^}", I32)] struct Align; #[derive(Debug)] #[debug("{:+}", I32)] struct Sign; #[derive(Debug)] #[debug("{:#b}", I32)] struct Alternate; #[derive(Debug)] #[debug("{:0}", I32)] struct ZeroPadded; #[derive(Debug)] #[debug("{:07}", I32)] struct Width; #[derive(Debug)] #[debug("{:.1}", F64)] struct Precision; #[test] fn assert() { assert_eq!(format!("{:03?}", LowerDebug), "b"); assert_eq!(format!("{:03?}", UpperDebug), "B"); assert_eq!(format!("{:03?}", Align), "11"); assert_eq!(format!("{:04?}", Sign), "+11"); assert_eq!(format!("{:07?}", Alternate), "0b1011"); assert_eq!(format!("{:07?}", ZeroPadded), "11"); assert_eq!(format!("{:03?}", Width), "0000011"); assert_eq!(format!("{:.3?}", Precision), "3.1"); } } } } } mod single_field { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Tuple(i32); #[derive(Debug)] struct Struct { field: i32, } #[test] fn assert() { assert_eq!(format!("{:?}", Tuple(0)), "Tuple(0)"); assert_eq!(format!("{:#?}", Tuple(0)), "Tuple(\n 0,\n)"); assert_eq!(format!("{:?}", Struct { field: 0 }), "Struct { field: 0 }"); assert_eq!( format!("{:#?}", Struct { field: 0 }), "Struct {\n field: 0,\n}", ); } mod str_field { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Tuple(#[debug("i32")] i32); #[derive(Debug)] struct Struct { #[debug("i32")] field: i32, } #[test] fn assert() { assert_eq!(format!("{:?}", Tuple(0)), "Tuple(i32)"); assert_eq!(format!("{:#?}", Tuple(0)), "Tuple(\n i32,\n)"); assert_eq!( format!("{:?}", Struct { field: 0 }), "Struct { field: i32 }", ); assert_eq!( format!("{:#?}", Struct { field: 0 }), "Struct {\n field: i32,\n}", ); } } mod interpolated_field { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Tuple(#[debug("{_0}.{}", _0)] i32); #[derive(Debug)] struct Struct { #[debug("{field}.{}", field)] field: i32, } #[test] fn assert() { assert_eq!(format!("{:?}", Tuple(0)), "Tuple(0.0)"); assert_eq!(format!("{:#?}", Tuple(0)), "Tuple(\n 0.0,\n)"); assert_eq!( format!("{:?}", Struct { field: 0 }), "Struct { field: 0.0 }", ); assert_eq!( format!("{:#?}", Struct { field: 0 }), "Struct {\n field: 0.0,\n}", ); } mod pointer { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Tuple<'a>(#[debug("{_0:p}.{:p}", self.0)] &'a i32); #[derive(Debug)] struct Struct<'a> { #[debug("{field:p}.{:p}", self.field)] field: &'a i32, } #[derive(Debug)] #[debug("{_0:p}")] struct TupleTransparent<'a>(&'a i32); #[derive(Debug)] #[debug("{field:p}")] struct StructTransparent<'a> { field: &'a i32, } #[test] fn assert() { let a = 42; assert_eq!( format!("{:?}", Tuple(&a)), format!("Tuple({0:p}.{0:p})", &a), ); assert_eq!( format!("{:?}", Struct { field: &a }), format!("Struct {{ field: {0:p}.{0:p} }}", &a), ); assert_eq!( format!("{:?}", TupleTransparent(&a)), format!("{0:p}", &a), ); assert_eq!( format!("{:?}", StructTransparent { field: &a }), format!("{0:p}", &a), ); } } } mod ignore { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Tuple(#[debug(ignore)] i32); #[derive(Debug)] struct Struct { #[debug(skip)] field: i32, } #[test] fn assert() { assert_eq!(format!("{:?}", Tuple(0)), "Tuple(..)"); assert_eq!(format!("{:#?}", Tuple(0)), "Tuple(..)"); assert_eq!(format!("{:?}", Struct { field: 0 }), "Struct { .. }"); assert_eq!(format!("{:#?}", Struct { field: 0 }), "Struct { .. }"); } } mod transparency { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] #[debug("{_0:?}")] struct TupleDebug(i32); #[derive(Debug)] #[debug("{}", field)] struct StructDisplay { field: i32, } #[test] fn assert() { assert_eq!(format!("{:03?}", TupleDebug(7)), "007"); assert_eq!(format!("{:03?}", StructDisplay { field: 7 }), "007"); } mod suppressed { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] #[debug("{}", format_args!("{_0:?}"))] struct TupleDebug(i32); #[derive(Debug)] #[debug("{}", format_args!("{}", field))] struct StructDisplay { field: i32, } #[test] fn assert() { assert_eq!(format!("{:03?}", TupleDebug(7)), "7"); assert_eq!(format!("{:03?}", StructDisplay { field: 7 }), "7"); } } mod omitted { mod on_modifiers { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] #[debug("{_0:x?}")] struct LowerDebug(i32); #[derive(Debug)] #[debug("{_0:X?}")] struct UpperDebug(i32); #[derive(Debug)] #[debug("{:^}", _0)] struct Align(i32); #[derive(Debug)] #[debug("{:+}", _0)] struct Sign(i32); #[derive(Debug)] #[debug("{:#b}", _0)] struct Alternate(i32); #[derive(Debug)] #[debug("{:0}", _0)] struct ZeroPadded(i32); #[derive(Debug)] #[debug("{:07}", _0)] struct Width(i32); #[derive(Debug)] #[debug("{:.5}", _0)] struct Precision(f64); #[test] fn assert() { assert_eq!(format!("{:03?}", LowerDebug(7)), "7"); assert_eq!(format!("{:03?}", UpperDebug(8)), "8"); assert_eq!(format!("{:03?}", Align(5)), "5"); assert_eq!(format!("{:03?}", Sign(5)), "+5"); assert_eq!(format!("{:07?}", Alternate(5)), "0b101"); assert_eq!(format!("{:07?}", ZeroPadded(-5)), "-5"); assert_eq!(format!("{:03?}", Width(5)), "0000005"); assert_eq!(format!("{:.3?}", Precision(1.23456789)), "1.23457"); } } } } } mod multi_field { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Tuple(i32, i32); #[derive(Debug)] struct Struct { field1: i32, field2: i32, } #[test] fn assert() { assert_eq!(format!("{:?}", Tuple(1, 2)), "Tuple(1, 2)"); assert_eq!(format!("{:#?}", Tuple(1, 2)), "Tuple(\n 1,\n 2,\n)"); assert_eq!( format!( "{:?}", Struct { field1: 1, field2: 2, } ), "Struct { field1: 1, field2: 2 }", ); assert_eq!( format!( "{:#?}", Struct { field1: 1, field2: 2, } ), "Struct {\n field1: 1,\n field2: 2,\n}", ); } mod str_field { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Tuple(i32, #[debug("i32")] i32); #[derive(Debug)] struct Struct { #[debug("i32")] field1: i32, field2: i32, } #[test] fn assert() { assert_eq!(format!("{:?}", Tuple(1, 2)), "Tuple(1, i32)"); assert_eq!( format!("{:#?}", Tuple(1, 2)), "Tuple(\n 1,\n i32,\n)", ); assert_eq!( format!( "{:?}", Struct { field1: 1, field2: 2, } ), "Struct { field1: i32, field2: 2 }", ); assert_eq!( format!( "{:#?}", Struct { field1: 1, field2: 2, } ), "Struct {\n field1: i32,\n field2: 2,\n}", ); } } mod interpolated_field { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Tuple(i32, #[debug("{_0}.{}", _1)] i32); #[derive(Debug)] struct Struct { #[debug("{field1}.{}", field2)] field1: i32, field2: i32, } #[test] fn assert() { assert_eq!(format!("{:?}", Tuple(1, 2)), "Tuple(1, 1.2)"); assert_eq!( format!("{:#?}", Tuple(1, 2)), "Tuple(\n 1,\n 1.2,\n)", ); assert_eq!( format!( "{:?}", Struct { field1: 1, field2: 2, } ), "Struct { field1: 1.2, field2: 2 }", ); assert_eq!( format!( "{:#?}", Struct { field1: 1, field2: 2, } ), "Struct {\n field1: 1.2,\n field2: 2,\n}", ); } } mod interpolated_struct { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] #[debug("{_0} * {_1}")] struct Tuple(u8, bool); #[derive(Debug)] #[debug("{a} * {b}")] struct Struct { a: u8, b: bool, } #[test] fn assert() { assert_eq!(format!("{:?}", Tuple(10, true)), "10 * true"); assert_eq!(format!("{:?}", Struct { a: 10, b: true }), "10 * true"); } mod pointer { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] #[debug("{_0:p} * {_1:p}")] struct Tuple<'a, 'b>(&'a u8, &'b bool); #[derive(Debug)] #[debug("{a:p} * {b:p}")] struct Struct<'a, 'b> { a: &'a u8, b: &'b bool, } #[test] fn assert() { let (a, b) = (10, true); assert_eq!( format!("{:?}", Tuple(&a, &b)), format!("{:p} * {:p}", &a, &b), ); assert_eq!( format!("{:?}", Struct { a: &a, b: &b }), format!("{:p} * {:p}", &a, &b), ); } } } mod ignore { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Tuple(#[debug(ignore)] i32, i32); #[derive(Debug)] struct Struct { field1: i32, #[debug(skip)] field2: i32, } #[test] fn assert() { assert_eq!(format!("{:?}", Tuple(1, 2)), "Tuple(2, ..)"); assert_eq!(format!("{:#?}", Tuple(1, 2)), "Tuple(\n 2,\n ..\n)",); assert_eq!( format!( "{:?}", Struct { field1: 1, field2: 2 } ), "Struct { field1: 1, .. }", ); assert_eq!( format!( "{:#?}", Struct { field1: 1, field2: 2 } ), "Struct {\n field1: 1,\n ..\n}", ); } } mod transparency { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] #[debug("{0:o}", _0)] struct TupleOctal(i32, i64); #[derive(Debug)] #[debug("{named:e}", named = b)] struct StructLowerExp { a: i32, b: f64, } #[test] fn assert() { assert_eq!(format!("{:03?}", TupleOctal(9, 4)), "011"); assert_eq!( format!("{:.1?}", StructLowerExp { a: 7, b: 3.15 }), "3.1e0", ); } } } } mod enums { mod no_variants { use derive_more::Debug; #[derive(Debug)] enum Void {} const fn assert() {} const _: () = assert::(); } mod unit_variant { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] enum Enum { Unit, Unnamed(), Named {}, } #[test] fn assert() { assert_eq!(format!("{:?}", Enum::Unit), "Unit"); assert_eq!(format!("{:#?}", Enum::Unit), "Unit"); assert_eq!(format!("{:?}", Enum::Unnamed()), "Unnamed"); assert_eq!(format!("{:#?}", Enum::Unnamed()), "Unnamed"); assert_eq!(format!("{:?}", Enum::Named {}), "Named"); assert_eq!(format!("{:#?}", Enum::Named {}), "Named"); } mod transparency { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; const I32: i32 = 11; const F64: f64 = 3.15; const POINTER: &f64 = &3.15; #[derive(Debug)] enum Unit { #[debug("{I32}")] Display, #[debug("{I32:?}")] Debug, #[debug("{:b}", I32)] Binary, #[debug("{0:o}", I32)] Octal, #[debug("{I32:x}")] LowerHex, #[debug("{:X}", I32)] UpperHex, #[debug("{F64:e}")] LowerExp, #[debug("{named:E}", named = F64)] UpperExp, #[debug("{POINTER:p}")] Pointer, } #[test] fn assert() { assert_eq!(format!("{:03?}", Unit::Display), "011"); assert_eq!(format!("{:03?}", Unit::Debug), "011"); assert_eq!(format!("{:07?}", Unit::Binary), "0001011"); assert_eq!(format!("{:07?}", Unit::Octal), "0000013"); assert_eq!(format!("{:03?}", Unit::LowerHex), "00b"); assert_eq!(format!("{:03?}", Unit::UpperHex), "00B"); assert_eq!(format!("{:07?}", Unit::LowerExp), "03.15e0"); assert_eq!(format!("{:07?}", Unit::UpperExp), "03.15E0"); assert_eq!( format!("{:018?}", Unit::Pointer), format!("{POINTER:018p}"), ); } mod omitted { mod on_modifiers { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; const I32: i32 = 11; const F64: f64 = 3.15; #[derive(Debug)] enum Unit { #[debug("{I32:x?}")] LowerDebug, #[debug("{I32:X?}")] UpperDebug, #[debug("{:^}", I32)] Align, #[debug("{:+}", I32)] Sign, #[debug("{:#b}", I32)] Alternate, #[debug("{:0}", I32)] ZeroPadded, #[debug("{:07}", I32)] Width, #[debug("{:.1}", F64)] Precision, } #[test] fn assert() { assert_eq!(format!("{:03?}", Unit::LowerDebug), "b"); assert_eq!(format!("{:03?}", Unit::UpperDebug), "B"); assert_eq!(format!("{:03?}", Unit::Align), "11"); assert_eq!(format!("{:04?}", Unit::Sign), "+11"); assert_eq!(format!("{:07?}", Unit::Alternate), "0b1011"); assert_eq!(format!("{:07?}", Unit::ZeroPadded), "11"); assert_eq!(format!("{:03?}", Unit::Width), "0000011"); assert_eq!(format!("{:.3?}", Unit::Precision), "3.1"); } } } } } mod single_field_variant { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] enum Enum { Unnamed(i32), Named { field: i32, }, StrUnnamed(#[debug("i32")] i32), StrNamed { #[debug("i32")] field: i32, }, InterpolatedUnnamed(#[debug("{_0}.{}", _0)] i32), InterpolatedNamed { #[debug("{field}.{}", field)] field: i32, }, SkippedUnnamed(#[debug(skip)] i32), SkippedNamed { #[debug(skip)] field: i32, }, } #[test] fn assert() { assert_eq!(format!("{:?}", Enum::Unnamed(1)), "Unnamed(1)"); assert_eq!(format!("{:#?}", Enum::Unnamed(1)), "Unnamed(\n 1,\n)"); assert_eq!( format!("{:?}", Enum::Named { field: 1 }), "Named { field: 1 }", ); assert_eq!( format!("{:#?}", Enum::Named { field: 1 }), "Named {\n field: 1,\n}", ); assert_eq!(format!("{:?}", Enum::StrUnnamed(1)), "StrUnnamed(i32)"); assert_eq!( format!("{:#?}", Enum::StrUnnamed(1)), "StrUnnamed(\n i32,\n)", ); assert_eq!( format!("{:?}", Enum::StrNamed { field: 1 }), "StrNamed { field: i32 }", ); assert_eq!( format!("{:#?}", Enum::StrNamed { field: 1 }), "StrNamed {\n field: i32,\n}", ); assert_eq!( format!("{:?}", Enum::InterpolatedUnnamed(1)), "InterpolatedUnnamed(1.1)", ); assert_eq!( format!("{:#?}", Enum::InterpolatedUnnamed(1)), "InterpolatedUnnamed(\n 1.1,\n)", ); assert_eq!( format!("{:?}", Enum::InterpolatedNamed { field: 1 }), "InterpolatedNamed { field: 1.1 }", ); assert_eq!( format!("{:#?}", Enum::InterpolatedNamed { field: 1 }), "InterpolatedNamed {\n field: 1.1,\n}", ); assert_eq!( format!("{:?}", Enum::SkippedUnnamed(1)), "SkippedUnnamed(..)", ); assert_eq!( format!("{:#?}", Enum::SkippedUnnamed(1)), "SkippedUnnamed(..)", ); assert_eq!( format!("{:?}", Enum::SkippedNamed { field: 1 }), "SkippedNamed { .. }", ); assert_eq!( format!("{:#?}", Enum::SkippedNamed { field: 1 }), "SkippedNamed { .. }", ); } mod transparency { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] enum Enum { #[debug("{_0:?}")] Debug(i32), #[debug("{}", field)] Display { field: i32 }, } #[test] fn assert() { assert_eq!(format!("{:03?}", Enum::Debug(7)), "007"); assert_eq!(format!("{:03?}", Enum::Display { field: 7 }), "007"); } mod suppressed { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] enum Enum { #[debug("{}", format_args!("{_0:?}"))] Debug(i32), #[debug("{}", format_args!("{}", field))] Display { field: i32 }, } #[test] fn assert() { assert_eq!(format!("{:03?}", Enum::Debug(7)), "7"); assert_eq!(format!("{:03?}", Enum::Display { field: 7 }), "7"); } } mod omitted { mod on_modifiers { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] enum Enum { #[debug("{_0:x?}")] LowerDebug(i32), #[debug("{_0:X?}")] UpperDebug(i32), #[debug("{:^}", _0)] Align(i32), #[debug("{:+}", _0)] Sign(i32), #[debug("{:#b}", _0)] Alternate(i32), #[debug("{:0}", _0)] ZeroPadded(i32), #[debug("{:07}", _0)] Width(i32), #[debug("{:.5}", _0)] Precision(f64), } #[test] fn assert() { assert_eq!(format!("{:03?}", Enum::LowerDebug(7)), "7"); assert_eq!(format!("{:03?}", Enum::UpperDebug(8)), "8"); assert_eq!(format!("{:03?}", Enum::Align(5)), "5"); assert_eq!(format!("{:03?}", Enum::Sign(5)), "+5"); assert_eq!(format!("{:07?}", Enum::Alternate(5)), "0b101"); assert_eq!(format!("{:07?}", Enum::ZeroPadded(-5)), "-5"); assert_eq!(format!("{:03?}", Enum::Width(5)), "0000005"); assert_eq!( format!("{:.3?}", Enum::Precision(1.23456789)), "1.23457", ); } } } } } mod multi_field_variant { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] enum Enum { Unnamed(i32, i32), Named { field1: i32, field2: i32, }, StrUnnamed(#[debug("i32")] i32, i32), StrNamed { field1: i32, #[debug("i32")] field2: i32, }, InterpolatedUnnamed(i32, #[debug("{_0}.{}", _1)] i32), InterpolatedNamed { #[debug("{field1}.{}", field2)] field1: i32, field2: i32, }, SkippedUnnamed(i32, #[debug(skip)] i32), SkippedNamed { #[debug(skip)] field1: i32, field2: i32, }, } #[test] fn assert() { assert_eq!(format!("{:?}", Enum::Unnamed(1, 2)), "Unnamed(1, 2)"); assert_eq!( format!("{:#?}", Enum::Unnamed(1, 2)), "Unnamed(\n 1,\n 2,\n)", ); assert_eq!( format!("{:?}", Enum::StrUnnamed(1, 2)), "StrUnnamed(i32, 2)", ); assert_eq!( format!("{:#?}", Enum::StrUnnamed(1, 2)), "StrUnnamed(\n i32,\n 2,\n)", ); assert_eq!( format!( "{:?}", Enum::StrNamed { field1: 1, field2: 2, } ), "StrNamed { field1: 1, field2: i32 }", ); assert_eq!( format!( "{:#?}", Enum::StrNamed { field1: 1, field2: 2, } ), "StrNamed {\n field1: 1,\n field2: i32,\n}", ); assert_eq!( format!("{:?}", Enum::InterpolatedUnnamed(1, 2)), "InterpolatedUnnamed(1, 1.2)", ); assert_eq!( format!("{:#?}", Enum::InterpolatedUnnamed(1, 2)), "InterpolatedUnnamed(\n 1,\n 1.2,\n)", ); assert_eq!( format!( "{:?}", Enum::InterpolatedNamed { field1: 1, field2: 2, } ), "InterpolatedNamed { field1: 1.2, field2: 2 }", ); assert_eq!( format!( "{:#?}", Enum::InterpolatedNamed { field1: 1, field2: 2, } ), "InterpolatedNamed {\n field1: 1.2,\n field2: 2,\n}", ); assert_eq!( format!("{:?}", Enum::SkippedUnnamed(1, 2)), "SkippedUnnamed(1, ..)", ); assert_eq!( format!("{:#?}", Enum::SkippedUnnamed(1, 2)), "SkippedUnnamed(\n 1,\n ..\n)", ); assert_eq!( format!( "{:?}", Enum::SkippedNamed { field1: 1, field2: 2, } ), "SkippedNamed { field2: 2, .. }", ); assert_eq!( format!( "{:#?}", Enum::SkippedNamed { field1: 1, field2: 2, } ), "SkippedNamed {\n field2: 2,\n ..\n}", ); } mod interpolated_variant { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] enum Enum { #[debug("Format String")] Unit, #[debug("Format {a} String {b}")] Fields { a: usize, b: u8 }, } #[test] fn assert() { assert_eq!(format!("{:?}", Enum::Unit), "Format String"); assert_eq!( format!("{:?}", Enum::Fields { a: 1, b: 2 }), "Format 1 String 2", ); } } mod transparency { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] enum Enum { #[debug("{0:o}", _0)] TupleOctal(i32, i64), #[debug("{named:e}", named = b)] StructLowerExp { a: i32, b: f64 }, } #[test] fn assert() { assert_eq!(format!("{:03?}", Enum::TupleOctal(9, 4)), "011"); assert_eq!( format!("{:.1?}", Enum::StructLowerExp { a: 7, b: 3.15 }), "3.1e0", ); } } } } mod generic { #[cfg(not(feature = "std"))] use alloc::{boxed::Box, format}; use core::fmt; use derive_more::Debug; struct NotDebug; impl fmt::Display for NotDebug { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("NotDebug").finish() } } #[derive(Debug)] struct NamedGenericStruct { field: T, } #[test] fn named_generic_struct() { assert_eq!( format!("{:?}", NamedGenericStruct { field: 1 }), "NamedGenericStruct { field: 1 }", ); assert_eq!( format!("{:#?}", NamedGenericStruct { field: 1 }), "NamedGenericStruct {\n field: 1,\n}", ); } #[derive(Debug)] struct NamedGenericStructUnsized { field: T, } #[test] fn named_generic_struct_unsized() { assert_eq!( format!("{:?}", NamedGenericStructUnsized { field: 1 }), "NamedGenericStructUnsized { field: 1 }", ); assert_eq!( format!("{:#?}", NamedGenericStructUnsized { field: 1 }), "NamedGenericStructUnsized {\n field: 1,\n}", ); } #[derive(Debug)] struct NamedGenericStructIgnored { #[debug(ignore)] field: T, } #[test] fn named_generic_struct_ignored() { assert_eq!( format!("{:?}", NamedGenericStructIgnored { field: NotDebug }), "NamedGenericStructIgnored { .. }", ); assert_eq!( format!("{:#?}", NamedGenericStructIgnored { field: NotDebug }), "NamedGenericStructIgnored { .. }", ); } #[derive(Debug)] struct InterpolatedNamedGenericStruct { #[debug("{field}.{}", field)] field: T, } #[test] fn interpolated_named_generic_struct() { assert_eq!( format!("{:?}", InterpolatedNamedGenericStruct { field: 1 }), "InterpolatedNamedGenericStruct { field: 1.1 }", ); assert_eq!( format!("{:#?}", InterpolatedNamedGenericStruct { field: 1 }), "InterpolatedNamedGenericStruct {\n field: 1.1,\n}", ); assert_eq!( format!("{:?}", InterpolatedNamedGenericStruct { field: NotDebug }), "InterpolatedNamedGenericStruct { field: NotDebug.NotDebug }", ); assert_eq!( format!("{:#?}", InterpolatedNamedGenericStruct { field: NotDebug }), "InterpolatedNamedGenericStruct {\n field: NotDebug.NotDebug,\n}", ); } #[derive(Debug)] struct InterpolatedNamedGenericStructWidthPrecision { #[debug("{field:<>width$.prec$}.{field}")] field: T, width: usize, prec: usize, } #[test] fn interpolated_named_generic_struct_width_precision() { assert_eq!( format!( "{:?}", InterpolatedNamedGenericStructWidthPrecision { field: 1.2345, width: 9, prec: 2, } ), "InterpolatedNamedGenericStructWidthPrecision { \ field: <<<<<1.23.1.2345, \ width: 9, \ prec: 2 \ }", ); assert_eq!( format!( "{:#?}", InterpolatedNamedGenericStructWidthPrecision { field: 1.2345, width: 9, prec: 2, } ), "InterpolatedNamedGenericStructWidthPrecision {\n \ field: <<<<<1.23.1.2345,\n \ width: 9,\n \ prec: 2,\n\ }", ); } #[derive(Debug)] #[debug("test_named")] struct InterpolatedNamedGenericStructIgnored { field: T, } #[test] fn interpolated_named_generic_struct_ignored() { assert_eq!( format!( "{:?}", InterpolatedNamedGenericStructIgnored { field: NotDebug }, ), "test_named", ); } #[derive(Debug)] struct AliasedNamedGenericStruct { #[debug("{alias}", alias = field)] field: T, } #[test] fn aliased_named_generic_struct() { assert_eq!( format!("{:?}", AliasedNamedGenericStruct { field: 1 }), "AliasedNamedGenericStruct { field: 1 }", ); assert_eq!( format!("{:#?}", AliasedNamedGenericStruct { field: 1 }), "AliasedNamedGenericStruct {\n field: 1,\n}", ); } #[derive(Debug)] struct AliasedFieldNamedGenericStruct { #[debug("{field1}", field1 = field2)] field1: T, field2: i32, } #[test] fn aliased_field_named_generic_struct() { assert_eq!( format!( "{:?}", AliasedFieldNamedGenericStruct { field1: NotDebug, field2: 1, }, ), "AliasedFieldNamedGenericStruct { field1: 1, field2: 1 }", ); assert_eq!( format!( "{:#?}", AliasedFieldNamedGenericStruct { field1: NotDebug, field2: 1, }, ), "AliasedFieldNamedGenericStruct {\n field1: 1,\n field2: 1,\n}", ); } #[derive(Debug)] struct UnnamedGenericStruct(T); #[test] fn unnamed_generic_struct() { assert_eq!( format!("{:?}", UnnamedGenericStruct(2)), "UnnamedGenericStruct(2)", ); assert_eq!( format!("{:#?}", UnnamedGenericStruct(2)), "UnnamedGenericStruct(\n 2,\n)", ); } #[derive(Debug)] struct UnnamedGenericStructUnsized(T); #[test] fn unnamed_generic_struct_unsized() { assert_eq!( format!("{:?}", UnnamedGenericStructUnsized(2)), "UnnamedGenericStructUnsized(2)", ); assert_eq!( format!("{:#?}", UnnamedGenericStructUnsized(2)), "UnnamedGenericStructUnsized(\n 2,\n)", ); } #[derive(Debug)] struct UnnamedGenericStructIgnored(#[debug(skip)] T); #[test] fn unnamed_generic_struct_ignored() { assert_eq!( format!("{:?}", UnnamedGenericStructIgnored(NotDebug)), "UnnamedGenericStructIgnored(..)", ); assert_eq!( format!("{:#?}", UnnamedGenericStructIgnored(NotDebug)), "UnnamedGenericStructIgnored(..)", ); } #[derive(Debug)] struct InterpolatedUnnamedGenericStruct(#[debug("{}.{_0}", _0)] T); #[test] fn interpolated_unnamed_generic_struct() { assert_eq!( format!("{:?}", InterpolatedUnnamedGenericStruct(2)), "InterpolatedUnnamedGenericStruct(2.2)", ); assert_eq!( format!("{:#?}", InterpolatedUnnamedGenericStruct(2)), "InterpolatedUnnamedGenericStruct(\n 2.2,\n)", ); assert_eq!( format!("{:?}", InterpolatedUnnamedGenericStruct(NotDebug)), "InterpolatedUnnamedGenericStruct(NotDebug.NotDebug)", ); assert_eq!( format!("{:#?}", InterpolatedUnnamedGenericStruct(NotDebug)), "InterpolatedUnnamedGenericStruct(\n NotDebug.NotDebug,\n)", ); } #[derive(Debug)] #[debug("test_unnamed")] struct InterpolatedUnnamedGenericStructIgnored(T); #[test] fn interpolated_unnamed_generic_struct_ignored() { assert_eq!( format!("{:?}", InterpolatedUnnamedGenericStructIgnored(NotDebug)), "test_unnamed", ); } #[derive(Debug)] struct AliasedUnnamedGenericStruct(#[debug("{alias}", alias = _0)] T); #[test] fn aliased_unnamed_generic_struct() { assert_eq!( format!("{:?}", AliasedUnnamedGenericStruct(2)), "AliasedUnnamedGenericStruct(2)", ); assert_eq!( format!("{:#?}", AliasedUnnamedGenericStruct(2)), "AliasedUnnamedGenericStruct(\n 2,\n)", ); } #[derive(Debug)] struct AliasedFieldUnnamedGenericStruct(#[debug("{_0}", _0 = _1)] T, i32); #[test] fn aliased_field_unnamed_generic_struct() { assert_eq!( format!("{:?}", AliasedFieldUnnamedGenericStruct(NotDebug, 2)), "AliasedFieldUnnamedGenericStruct(2, 2)", ); assert_eq!( format!("{:#?}", AliasedFieldUnnamedGenericStruct(NotDebug, 2)), "AliasedFieldUnnamedGenericStruct(\n 2,\n 2,\n)", ); } #[derive(Debug)] enum GenericEnum { A { field: A }, B(B), } #[test] fn generic_enum() { assert_eq!( format!("{:?}", GenericEnum::A::<_, u8> { field: 1 }), "A { field: 1 }", ); assert_eq!( format!("{:#?}", GenericEnum::A::<_, u8> { field: 1 }), "A {\n field: 1,\n}", ); assert_eq!(format!("{:?}", GenericEnum::B::(2)), "B(2)"); assert_eq!( format!("{:#?}", GenericEnum::B::(2)), "B(\n 2,\n)", ); } #[derive(derive_more::Debug)] enum GenericEnumUnsized { A { field: Box }, B(&'static B), } #[test] fn generic_enum_unsized() { assert_eq!( format!("{:?}", GenericEnumUnsized::A:: { field: 1.into() }), "A { field: 1 }", ); assert_eq!( format!( "{:#?}", GenericEnumUnsized::A:: { field: 1.into() }, ), "A {\n field: 1,\n}", ); assert_eq!( format!("{:?}", GenericEnumUnsized::B::(&2)), "B(2)", ); assert_eq!( format!("{:#?}", GenericEnumUnsized::B::(&2)), "B(\n 2,\n)", ); } #[derive(Debug)] enum InterpolatedGenericEnum { A { #[debug("{}.{field}", field)] field: A, }, B(#[debug("{}.{_0}", _0)] B), } #[test] fn interpolated_generic_enum() { assert_eq!( format!("{:?}", InterpolatedGenericEnum::A::<_, u8> { field: 1 }), "A { field: 1.1 }", ); assert_eq!( format!("{:#?}", InterpolatedGenericEnum::A::<_, u8> { field: 1 }), "A {\n field: 1.1,\n}", ); assert_eq!( format!("{:?}", InterpolatedGenericEnum::B::(2)), "B(2.2)", ); assert_eq!( format!("{:#?}", InterpolatedGenericEnum::B::(2)), "B(\n 2.2,\n)", ); } #[derive(Debug)] enum InterpolatedGenericEnumIgnored { #[debug("A {field}")] A { field: A }, #[debug("B")] B(B), } #[test] fn interpolated_generic_enum_ignored() { assert_eq!( format!( "{:?}", InterpolatedGenericEnumIgnored::A::<_, u8> { field: NotDebug }, ), "A NotDebug", ); assert_eq!( format!("{:?}", InterpolatedGenericEnumIgnored::B::(NotDebug)), "B", ); } #[derive(Debug)] struct MultiTraitNamedGenericStruct { #[debug("{}.{}<->{0:o}.{1:#x}<->{0:?}.{1:X?}", a, b)] a: A, b: B, } #[test] fn multi_trait_named_generic_struct() { let s = MultiTraitNamedGenericStruct { a: 8u8, b: 255 }; assert_eq!( format!("{s:?}"), "MultiTraitNamedGenericStruct { a: 8.255<->10.0xff<->8.FF, b: 255 }", ); assert_eq!( format!("{s:#?}"), "MultiTraitNamedGenericStruct {\n a: 8.255<->10.0xff<->8.FF,\n b: 255,\n}", ); } #[derive(Debug)] struct MultiTraitUnnamedGenericStruct( #[debug("{}.{}.{{}}.{0:o}.{1:#x}-{0:>4?}.{1:^4X?}", _0, _1)] A, B, ); #[test] fn multi_trait_unnamed_generic_struct() { let s = MultiTraitUnnamedGenericStruct(8u8, 255); assert_eq!( format!("{s:?}"), "MultiTraitUnnamedGenericStruct(8.255.{}.10.0xff- 8. FF , 255)", ); assert_eq!( format!("{s:#?}"), "MultiTraitUnnamedGenericStruct(\n 8.255.{}.10.0xff- 8. FF ,\n 255,\n)", ); } #[derive(Debug)] struct UnusedGenericStruct(#[debug("{}", 3 * 4)] T); #[test] fn unused_generic_struct() { let s = UnusedGenericStruct(NotDebug); assert_eq!(format!("{s:?}"), "UnusedGenericStruct(12)"); assert_eq!(format!("{s:#?}"), "UnusedGenericStruct(\n 12,\n)"); } mod associated_type_field_enumerator { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; trait Trait { type Type; } struct Struct; impl Trait for Struct { type Type = i32; } #[test] fn auto_generic_named_struct_associated() { #[derive(Debug)] struct AutoGenericNamedStructAssociated { field: ::Type, } let s = AutoGenericNamedStructAssociated:: { field: 10 }; assert_eq!( format!("{s:?}"), "AutoGenericNamedStructAssociated { field: 10 }", ); assert_eq!( format!("{s:#?}"), "AutoGenericNamedStructAssociated {\n field: 10,\n}", ); } #[test] fn auto_generic_unnamed_struct_associated() { #[derive(Debug)] struct AutoGenericUnnamedStructAssociated(::Type); let s = AutoGenericUnnamedStructAssociated::(10); assert_eq!(format!("{s:?}"), "AutoGenericUnnamedStructAssociated(10)",); assert_eq!( format!("{s:#?}"), "AutoGenericUnnamedStructAssociated(\n 10,\n)", ); } #[test] fn auto_generic_enum_associated() { #[derive(Debug)] enum AutoGenericEnumAssociated { Enumerator(::Type), } let e = AutoGenericEnumAssociated::::Enumerator(10); assert_eq!(format!("{:?}", e), "Enumerator(10)"); assert_eq!(format!("{:#?}", e), "Enumerator(\n 10,\n)"); } } mod complex_type_field_enumerator { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Struct(T); #[test] fn auto_generic_named_struct_complex() { #[derive(Debug)] struct AutoGenericNamedStructComplex { field: Struct, } let s = AutoGenericNamedStructComplex { field: Struct(10) }; assert_eq!( format!("{s:?}"), "AutoGenericNamedStructComplex { field: Struct(10) }", ); assert_eq!( format!("{s:#?}"), "AutoGenericNamedStructComplex {\n field: Struct(\n 10,\n ),\n}", ); } #[test] fn auto_generic_unnamed_struct_complex() { #[derive(Debug)] struct AutoGenericUnnamedStructComplex(Struct); let s = AutoGenericUnnamedStructComplex(Struct(10)); assert_eq!( format!("{s:?}"), "AutoGenericUnnamedStructComplex(Struct(10))", ); assert_eq!( format!("{s:#?}"), "AutoGenericUnnamedStructComplex(\n Struct(\n 10,\n ),\n)", ); } #[test] fn auto_generic_enum_complex() { #[derive(Debug)] enum AutoGenericEnumComplex { Enumerator(Struct), } let e = AutoGenericEnumComplex::Enumerator(Struct(10)); assert_eq!(format!("{:?}", e), "Enumerator(Struct(10))"); assert_eq!( format!("{:#?}", e), "Enumerator(\n Struct(\n 10,\n ),\n)", ) } } mod reference { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[test] fn auto_generic_reference() { #[derive(Debug)] struct AutoGenericReference<'a, T>(&'a T); let s = AutoGenericReference(&10); assert_eq!(format!("{s:?}"), "AutoGenericReference(10)"); assert_eq!(format!("{s:#?}"), "AutoGenericReference(\n 10,\n)"); } #[test] fn auto_generic_static_reference() { #[derive(Debug)] struct AutoGenericStaticReference(&'static T); let s = AutoGenericStaticReference(&10); assert_eq!(format!("{s:?}"), "AutoGenericStaticReference(10)"); assert_eq!(format!("{s:#?}"), "AutoGenericStaticReference(\n 10,\n)",); } } mod indirect { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] struct Struct(T); #[test] fn auto_generic_indirect() { #[derive(Debug)] struct AutoGenericIndirect(Struct<&'static T>); const V: i32 = 10; let s = AutoGenericIndirect(Struct(&V)); assert_eq!(format!("{s:?}"), "AutoGenericIndirect(Struct(10))"); assert_eq!( format!("{s:#?}"), "AutoGenericIndirect(\n Struct(\n 10,\n ),\n)", ); } } mod bound { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[test] fn simple() { #[derive(Debug)] struct Struct(#[debug("{}.{}", _0, _1)] T1, #[debug(skip)] T2); let s = Struct(10, 20); assert_eq!(format!("{s:?}"), "Struct(10.20, ..)"); assert_eq!(format!("{s:#?}"), "Struct(\n 10.20,\n ..\n)"); } #[test] fn underscored_simple() { #[derive(Debug)] struct Struct(#[debug("{_0}.{_1}")] T1, #[debug(skip)] T2); let s = Struct(10, 20); assert_eq!(format!("{s:?}"), "Struct(10.20, ..)"); assert_eq!(format!("{s:#?}"), "Struct(\n 10.20,\n ..\n)"); } #[test] fn redundant() { #[derive(Debug)] #[debug(bound(T1: ::core::fmt::Display, T2: ::core::fmt::Display))] struct Struct(#[debug("{}.{}", _0, _1)] T1, #[debug(skip)] T2); let s = Struct(10, 20); assert_eq!(format!("{s:?}"), "Struct(10.20, ..)"); assert_eq!(format!("{s:#?}"), "Struct(\n 10.20,\n ..\n)"); } #[test] fn underscored_redundant() { #[derive(Debug)] #[debug(bound(T1: ::core::fmt::Display, T2: ::core::fmt::Display))] struct Struct(#[debug("{_0}.{_1}")] T1, #[debug(ignore)] T2); let s = Struct(10, 20); assert_eq!(format!("{s:?}"), "Struct(10.20, ..)"); assert_eq!(format!("{s:#?}"), "Struct(\n 10.20,\n ..\n)"); } #[test] fn complex() { trait Trait1 { fn function1(&self) -> &'static str; } trait Trait2 { fn function2(&self) -> &'static str; } impl Trait1 for i32 { fn function1(&self) -> &'static str { "WHAT" } } impl Trait2 for i32 { fn function2(&self) -> &'static str { "EVER" } } #[derive(Debug)] #[debug(bound(T1: Trait1 + Trait2, T2: Trait1 + Trait2))] struct Struct( #[debug("{}_{}_{}_{}", _0.function1(), _0, _1.function2(), _1)] T1, T2, ); let s = Struct(10, 20); assert_eq!(format!("{s:?}"), "Struct(WHAT_10_EVER_20, 20)"); assert_eq!( format!("{s:#?}"), "Struct(\n WHAT_10_EVER_20,\n 20,\n)", ); } #[test] fn underscored_complex() { trait Trait1 { fn function1(&self) -> &'static str; } trait Trait2 { fn function2(&self) -> &'static str; } impl Trait1 for i32 { fn function1(&self) -> &'static str { "WHAT" } } impl Trait2 for i32 { fn function2(&self) -> &'static str { "EVER" } } #[derive(Debug)] #[debug(bound(T1: Trait1 + Trait2, T2: Trait1 + Trait2))] struct Struct( #[debug("{}_{_0}_{}_{_1}", _0.function1(), _1.function2())] T1, T2, ); let s = Struct(10, 20); assert_eq!(format!("{s:?}"), "Struct(WHAT_10_EVER_20, 20)"); assert_eq!( format!("{s:#?}"), "Struct(\n WHAT_10_EVER_20,\n 20,\n)", ); } } mod transparency { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] #[debug("{0:o}", _0)] struct Tuple(T); #[derive(Debug)] #[debug("{named:e}", named = b)] struct Struct { a: A, b: B, } #[derive(Debug)] enum Enum { #[debug("{_0:?}")] Debug(A), #[debug("{}", c)] Display { b: B, c: C }, } #[test] fn assert() { assert_eq!(format!("{:03?}", Tuple(9)), "011"); assert_eq!(format!("{:.1?}", Struct { a: 9, b: 3.15 }), "3.1e0"); assert_eq!(format!("{:03?}", Enum::<_, u8, u8>::Debug(7)), "007"); assert_eq!( format!("{:03?}", Enum::::Display { b: 7, c: 8 }), "008", ); } mod omitted { mod on_modifiers { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] enum Enum { #[debug("{_0:x?}")] LowerDebug(A), #[debug("{_0:X?}")] UpperDebug(B), #[debug("{:^}", _0)] Align(C), #[debug("{:+}", _0)] Sign(C), #[debug("{:#b}", _0)] Alternate(C), #[debug("{:0}", _0)] ZeroPadded(C), #[debug("{:07}", _0)] Width(C), #[debug("{:.5}", _0)] Precision(D), } #[test] fn assert() { assert_eq!( format!("{:03?}", Enum::<_, u8, u8, f64>::LowerDebug(7)), "7", ); assert_eq!( format!("{:03?}", Enum::::UpperDebug(8)), "8", ); assert_eq!( format!("{:03?}", Enum::::Align(5)), "5", ); assert_eq!( format!("{:03?}", Enum::::Sign(5)), "+5", ); assert_eq!( format!("{:07?}", Enum::::Alternate(5)), "0b101", ); assert_eq!( format!("{:07?}", Enum::::ZeroPadded(-5)), "-5", ); assert_eq!( format!("{:03?}", Enum::::Width(5)), "0000005", ); assert_eq!( format!("{:.3?}", Enum::::Precision(1.23456789)), "1.23457", ); } } } } } // See: https://github.com/JelteF/derive_more/issues/301 mod complex_enum_syntax { #[cfg(not(feature = "std"))] use alloc::format; use derive_more::Debug; #[derive(Debug)] enum Enum { A = if cfg!(unix) { 2 } else { 3 }, } #[test] fn assert() { assert_eq!(format!("{:?}", Enum::A), "A"); } } // See: https://github.com/JelteF/derive_more/issues/363 mod type_variables { mod our_alloc { #[cfg(not(feature = "std"))] pub use alloc::{boxed::Box, format, vec, vec::Vec}; #[cfg(feature = "std")] pub use std::{boxed::Box, format, vec, vec::Vec}; } use our_alloc::{format, vec, Box, Vec}; use derive_more::Debug; #[derive(Debug)] struct ItemStruct { next: Option>, } #[derive(Debug)] struct ItemTuple(Option>); #[derive(Debug)] #[debug("Item({_0:?})")] struct ItemTupleContainerFmt(Option>); #[derive(Debug)] enum ItemEnum { Node { children: Vec, inner: i32 }, Leaf { inner: i32 }, } #[derive(Debug)] struct VecMeansDifferent { next: our_alloc::Vec, real: Vec, } #[derive(Debug)] struct Array { #[debug("{t}")] t: [T; 10], } mod parens { #![allow(unused_parens)] // test that type is found even in parentheses use derive_more::Debug; #[derive(Debug)] struct Paren { t: (T), } } #[derive(Debug)] struct ParenthesizedGenericArgumentsInput { t: dyn Fn(T) -> i32, } #[derive(Debug)] struct ParenthesizedGenericArgumentsOutput { t: dyn Fn(i32) -> T, } #[derive(Debug)] struct Ptr { t: *const T, } #[derive(Debug)] struct Reference<'a, T> { t: &'a T, } #[derive(Debug)] struct Slice<'a, T> { t: &'a [T], } #[derive(Debug)] struct BareFn { t: Box T>, } #[derive(Debug)] struct Tuple { t: Box<(T, T)>, } trait MyTrait {} #[derive(Debug)] struct TraitObject { t: Box>, } #[test] fn assert() { assert_eq!( format!( "{:?}", ItemStruct { next: Some(Box::new(ItemStruct { next: None })) }, ), "ItemStruct { next: Some(ItemStruct { next: None }) }", ); assert_eq!( format!("{:?}", ItemTuple(Some(Box::new(ItemTuple(None))))), "ItemTuple(Some(ItemTuple(None)))", ); assert_eq!( format!( "{:?}", ItemTupleContainerFmt(Some(Box::new(ItemTupleContainerFmt(None)))), ), "Item(Some(Item(None)))", ); let item = ItemEnum::Node { children: vec![ ItemEnum::Node { children: vec![], inner: 0, }, ItemEnum::Leaf { inner: 1 }, ], inner: 2, }; assert_eq!( format!("{item:?}"), "Node { children: [Node { children: [], inner: 0 }, Leaf { inner: 1 }], inner: 2 }", ) } } derive_more-1.0.0/tests/deref.rs000064400000000000000000000022621046102023000147210ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use ::alloc::{boxed::Box, vec::Vec}; use derive_more::Deref; #[derive(Deref)] #[deref(forward)] struct MyBoxedInt(Box); #[derive(Deref)] #[deref(forward)] struct NumRef<'a> { num: &'a i32, } #[derive(Deref)] struct NumRef2<'a> { #[deref(forward)] num: &'a i32, useless: bool, } #[derive(Deref)] #[deref(forward)] struct NumRef3<'a> { num: &'a i32, #[deref(ignore)] useless: bool, } #[derive(Deref)] struct MyInt(i32); #[derive(Deref)] struct Point1D { x: i32, } #[derive(Deref)] struct Point1D2 { x: i32, #[deref(ignore)] useless: bool, } #[derive(Deref)] struct CoolVec { cool: bool, #[deref] vec: Vec, } #[derive(Deref)] struct GenericVec(Vec); #[test] fn deref_generic() { let gv = GenericVec(Vec::::new()); assert!(gv.is_empty()) } #[derive(Deref)] struct GenericBox(#[deref(forward)] Box); #[test] fn deref_generic_forward() { let boxed = GenericBox(Box::new(1i32)); assert_eq!(*boxed, 1i32); } derive_more-1.0.0/tests/deref_mut.rs000064400000000000000000000057751046102023000156220ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::{boxed::Box, vec, vec::Vec}; use derive_more::DerefMut; #[derive(DerefMut)] #[deref_mut(forward)] struct MyBoxedInt(Box); // `Deref` implementation is required for `DerefMut`. impl ::core::ops::Deref for MyBoxedInt { type Target = as ::core::ops::Deref>::Target; #[inline] fn deref(&self) -> &Self::Target { as ::core::ops::Deref>::deref(&self.0) } } #[derive(DerefMut)] struct NumRef<'a> { #[deref_mut(forward)] num: &'a mut i32, } // `Deref` implementation is required for `DerefMut`. impl<'a> ::core::ops::Deref for NumRef<'a> { type Target = <&'a mut i32 as ::core::ops::Deref>::Target; #[inline] fn deref(&self) -> &Self::Target { <&'a mut i32 as ::core::ops::Deref>::deref(&self.num) } } #[derive(DerefMut)] #[deref_mut(forward)] struct NumRef2<'a> { num: &'a mut i32, #[deref_mut(ignore)] useless: bool, } // `Deref` implementation is required for `DerefMut`. impl<'a> ::core::ops::Deref for NumRef2<'a> { type Target = <&'a mut i32 as ::core::ops::Deref>::Target; #[inline] fn deref(&self) -> &Self::Target { <&'a mut i32 as ::core::ops::Deref>::deref(&self.num) } } #[derive(DerefMut)] struct MyInt(i32); // `Deref` implementation is required for `DerefMut`. impl ::core::ops::Deref for MyInt { type Target = i32; #[inline] fn deref(&self) -> &Self::Target { &self.0 } } #[derive(DerefMut)] struct Point1D { x: i32, } // `Deref` implementation is required for `DerefMut`. impl ::core::ops::Deref for Point1D { type Target = i32; #[inline] fn deref(&self) -> &Self::Target { &self.x } } #[derive(DerefMut)] struct CoolVec { cool: bool, #[deref_mut] vec: Vec, } // `Deref` implementation is required for `DerefMut`. impl ::core::ops::Deref for CoolVec { type Target = Vec; #[inline] fn deref(&self) -> &Self::Target { &self.vec } } #[derive(DerefMut)] struct GenericVec(Vec); // `Deref` implementation is required for `DerefMut`. impl ::core::ops::Deref for GenericVec { type Target = Vec; #[inline] fn deref(&self) -> &Self::Target { &self.0 } } #[test] fn deref_mut_generic() { let mut gv = GenericVec::(vec![42]); assert!(gv.get_mut(0).is_some()); } #[derive(DerefMut)] struct GenericBox(#[deref_mut(forward)] Box); // `Deref` implementation is required for `DerefMut`. impl ::core::ops::Deref for GenericBox where Box: ::core::ops::Deref, { type Target = as ::core::ops::Deref>::Target; #[inline] fn deref(&self) -> &Self::Target { as ::core::ops::Deref>::deref(&self.0) } } #[test] fn deref_mut_generic_forward() { let mut boxed = GenericBox(Box::new(1i32)); *boxed = 3; assert_eq!(*boxed, 3i32); } derive_more-1.0.0/tests/display.rs000064400000000000000000002361031046102023000153040ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::{format, string::ToString}; use derive_more::{ Binary, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, }; mod structs { use super::*; mod unit { use super::*; #[derive(Display)] struct Unit; #[derive(Display)] struct r#RawUnit; #[derive(Display)] struct Tuple(); #[derive(Display)] struct Struct {} #[test] fn assert() { assert_eq!(Unit.to_string(), "Unit"); assert_eq!(r#RawUnit.to_string(), "RawUnit"); assert_eq!(Tuple().to_string(), "Tuple"); assert_eq!(Struct {}.to_string(), "Struct"); } mod str { use super::*; #[derive(Display)] #[display("unit")] pub struct Unit; #[derive(Display)] #[display("tuple")] pub struct Tuple(); #[derive(Display)] #[display("struct")] pub struct Struct {} #[test] fn assert() { assert_eq!(Unit.to_string(), "unit"); assert_eq!(Tuple().to_string(), "tuple"); assert_eq!(Struct {}.to_string(), "struct"); } } mod interpolated { use super::*; #[derive(Display)] #[display("unit: {}", 0)] pub struct Unit; #[derive(Display)] #[display("tuple: {}", 0)] pub struct Tuple(); #[derive(Display)] #[display("struct: {}", 0)] pub struct Struct {} #[test] fn assert() { assert_eq!(Unit.to_string(), "unit: 0"); assert_eq!(Tuple().to_string(), "tuple: 0"); assert_eq!(Struct {}.to_string(), "struct: 0"); } } mod transparency { use super::*; mod interpolated { use super::*; const I32: i32 = 11; const F64: f64 = 3.15; const POINTER: &f64 = &3.15; #[derive(Display)] #[display("{I32}")] struct Display; #[derive(Display)] #[display("{I32:?}")] struct Debug; #[derive(Display)] #[display("{:b}", I32)] struct Binary; #[derive(Display)] #[display("{0:o}", I32)] struct Octal; #[derive(Display)] #[display("{I32:x}")] struct LowerHex; #[derive(Display)] #[display("{:X}", I32)] struct UpperHex; #[derive(Display)] #[display("{F64:e}")] struct LowerExp; #[derive(Display)] #[display("{named:E}", named = F64)] struct UpperExp; #[derive(Display)] #[display("{POINTER:p}")] struct Pointer; #[test] fn assert() { assert_eq!(format!("{:03}", Display), "011"); assert_eq!(format!("{:03}", Debug), "011"); assert_eq!(format!("{:07}", Binary), "0001011"); assert_eq!(format!("{:07}", Octal), "0000013"); assert_eq!(format!("{:03}", LowerHex), "00b"); assert_eq!(format!("{:03}", UpperHex), "00B"); assert_eq!(format!("{:07}", LowerExp), "03.15e0"); assert_eq!(format!("{:07}", UpperExp), "03.15E0"); assert_eq!(format!("{:018}", Pointer), format!("{POINTER:018p}")); } } mod omitted { use super::*; mod on_modifiers { use super::*; const I32: i32 = 11; const F64: f64 = 3.15; #[derive(Display)] #[display("{I32:x?}")] struct LowerDebug; #[derive(Display)] #[display("{I32:X?}")] struct UpperDebug; #[derive(Display)] #[display("{:^}", I32)] struct Align; #[derive(Display)] #[display("{:+}", I32)] struct Sign; #[derive(Display)] #[display("{:#b}", I32)] struct Alternate; #[derive(Display)] #[display("{:0}", I32)] struct ZeroPadded; #[derive(Display)] #[display("{:07}", I32)] struct Width; #[derive(Display)] #[display("{:.1}", F64)] struct Precision; #[test] fn assert() { assert_eq!(format!("{:03}", LowerDebug), "b"); assert_eq!(format!("{:03}", UpperDebug), "B"); assert_eq!(format!("{:03}", Align), "11"); assert_eq!(format!("{:04}", Sign), "+11"); assert_eq!(format!("{:07}", Alternate), "0b1011"); assert_eq!(format!("{:07}", ZeroPadded), "11"); assert_eq!(format!("{:03}", Width), "0000011"); assert_eq!(format!("{:.3}", Precision), "3.1"); } } } } } mod single_field { use super::*; #[derive(Display)] struct Tuple(i32); #[derive(Binary)] struct Binary(i32); #[derive(Display)] struct Struct { field: i32, } #[derive(Octal)] struct Octal { field: i32, } #[test] fn assert() { assert_eq!(Tuple(0).to_string(), "0"); assert_eq!(format!("{:b}", Binary(10)), "1010"); assert_eq!(Struct { field: 0 }.to_string(), "0"); assert_eq!(format!("{:o}", Octal { field: 10 }).to_string(), "12"); } mod str { use super::*; #[derive(Display)] #[display("tuple")] struct Tuple(i32); #[derive(Display)] #[display("struct")] struct Struct { field: i32, } #[test] fn assert() { assert_eq!(Tuple(0).to_string(), "tuple"); assert_eq!(Struct { field: 0 }.to_string(), "struct"); } } mod interpolated { use super::*; #[derive(Display)] #[display("tuple: {_0} {}", _0)] struct Tuple(i32); #[derive(Display)] #[display("struct: {field} {}", field)] struct Struct { field: i32, } #[test] fn assert() { assert_eq!(Tuple(0).to_string(), "tuple: 0 0"); assert_eq!(Struct { field: 0 }.to_string(), "struct: 0 0"); } } mod transparency { use super::*; mod direct { use super::*; #[derive(Display)] struct TupleDisplay(i32); #[derive(Binary)] struct TupleBinary(i32); #[derive(Octal)] struct TupleOctal(i32); #[derive(LowerHex)] struct StructLowerHex { field: i32, } #[derive(UpperHex)] struct StructUpperHex { field: i32, } #[derive(LowerExp)] struct StructLowerExp { field: f64, } #[derive(UpperExp)] struct StructUpperExp { field: f64, } #[derive(Pointer)] struct StructPointer<'a> { field: &'a i32, } #[test] fn assert() { assert_eq!(format!("{:03}", TupleDisplay(7)), "007"); assert_eq!(format!("{:07b}", TupleBinary(7)), "0000111"); assert_eq!(format!("{:03o}", TupleOctal(9)), "011"); assert_eq!(format!("{:03x}", StructLowerHex { field: 42 }), "02a"); assert_eq!(format!("{:03X}", StructUpperHex { field: 42 }), "02A"); assert_eq!( format!("{:07e}", StructLowerExp { field: 42.0 }), "004.2e1", ); assert_eq!( format!("{:07E}", StructUpperExp { field: 42.0 }), "004.2E1", ); let a = 42; assert_eq!( format!("{:018p}", StructPointer { field: &a }), format!("{:018p}", &a), ); } } mod interpolated { use super::*; #[derive(Display)] #[display("{_0}")] struct TupleDisplay(i32); #[derive(Display)] #[display("{_0:?}")] struct TupleDebug(i32); #[derive(Display)] #[display("{:b}", _0)] struct TupleBinary(i32); #[derive(Display)] #[display("{0:o}", _0)] struct TupleOctal(i32); #[derive(Display)] #[display("{field:x}")] struct StructLowerHex { field: i32, } #[derive(Display)] #[display("{:X}", field)] struct StructUpperHex { field: i32, } #[derive(Display)] #[display("{field:e}")] struct StructLowerExp { field: f64, } #[derive(Display)] #[display("{named:E}", named = field)] struct StructUpperExp { field: f64, } #[derive(Display)] #[display("{field:p}")] struct StructPointer<'a> { field: &'a i32, } #[test] fn assert() { assert_eq!(format!("{:03}", TupleDisplay(7)), "007"); assert_eq!(format!("{:03}", TupleDebug(8)), "008"); assert_eq!(format!("{:07}", TupleBinary(7)), "0000111"); assert_eq!(format!("{:03}", TupleOctal(9)), "011"); assert_eq!(format!("{:03}", StructLowerHex { field: 42 }), "02a"); assert_eq!(format!("{:03}", StructUpperHex { field: 42 }), "02A"); assert_eq!( format!("{:07}", StructLowerExp { field: 42.0 }), "004.2e1", ); assert_eq!( format!("{:07}", StructUpperExp { field: 42.0 }), "004.2E1", ); let a = 42; assert_eq!( format!("{:018}", StructPointer { field: &a }), format!("{:018p}", &a), ); } } mod suppressed { use super::*; #[derive(Display)] #[display("{}", format_args!("{_0}"))] struct TupleDisplay(i32); #[derive(Display)] #[display("{}", format_args!("{_0:?}"))] struct TupleDebug(i32); #[derive(Display)] #[display("{}", format_args!("{_0:b}"))] struct TupleBinary(i32); #[derive(Display)] #[display("{}", format_args!("{_0:o}"))] struct TupleOctal(i32); #[derive(Display)] #[display("{}", format_args!("{field:x}"))] struct StructLowerHex { field: i32, } #[derive(Display)] #[display("{}", format_args!("{field:X}"))] struct StructUpperHex { field: i32, } #[derive(Display)] #[display("{}", format_args!("{field:e}"))] struct StructLowerExp { field: f64, } #[derive(Display)] #[display("{}", format_args!("{field:E}"))] struct StructUpperExp { field: f64, } #[derive(Display)] #[display("{}", format_args!("{field:p}", field = *field))] struct StructPointer<'a> { field: &'a i32, } #[test] fn assert() { assert_eq!(format!("{:03}", TupleDisplay(7)), "7"); assert_eq!(format!("{:03}", TupleDebug(8)), "8"); assert_eq!(format!("{:07}", TupleBinary(7)), "111"); assert_eq!(format!("{:03}", TupleOctal(9)), "11"); assert_eq!(format!("{:03}", StructLowerHex { field: 42 }), "2a"); assert_eq!(format!("{:03}", StructUpperHex { field: 42 }), "2A"); assert_eq!( format!("{:07}", StructLowerExp { field: 42.0 }), "4.2e1", ); assert_eq!( format!("{:07}", StructUpperExp { field: 42.0 }), "4.2E1", ); let a = 42; assert_eq!( format!("{:018}", StructPointer { field: &a }), format!("{:p}", &a), ); } } mod omitted { use super::*; mod on_modifiers { use super::*; #[derive(Display)] #[display("{_0:x?}")] struct LowerDebug(i32); #[derive(Display)] #[display("{_0:X?}")] struct UpperDebug(i32); #[derive(Display)] #[display("{:^}", _0)] struct Align(i32); #[derive(Display)] #[display("{:+}", _0)] struct Sign(i32); #[derive(Display)] #[display("{:#b}", _0)] struct Alternate(i32); #[derive(Display)] #[display("{:0}", _0)] struct ZeroPadded(i32); #[derive(Display)] #[display("{:07}", _0)] struct Width(i32); #[derive(Display)] #[display("{:.5}", _0)] struct Precision(f64); #[test] fn assert() { assert_eq!(format!("{:03}", LowerDebug(7)), "7"); assert_eq!(format!("{:03}", UpperDebug(8)), "8"); assert_eq!(format!("{:03}", Align(5)), "5"); assert_eq!(format!("{:03}", Sign(5)), "+5"); assert_eq!(format!("{:07}", Alternate(5)), "0b101"); assert_eq!(format!("{:07}", ZeroPadded(-5)), "-5"); assert_eq!(format!("{:03}", Width(5)), "0000005"); assert_eq!(format!("{:.3}", Precision(1.23456789)), "1.23457"); } } } } } mod multi_field { use super::*; mod str { use super::*; #[derive(Display)] #[display("tuple")] struct Tuple(i32, i32); #[derive(Display)] #[display("struct")] struct Struct { field1: i32, field2: i32, } #[test] fn assert() { assert_eq!(Tuple(1, 2).to_string(), "tuple"); assert_eq!( Struct { field1: 1, field2: 2, } .to_string(), "struct", ); } } mod interpolated { use super::*; #[derive(Display)] #[display( "{_0} {ident} {_1} {} {}", _1, _0 + _1, ident = 123, _1 = _0, )] struct Tuple(i32, i32); #[derive(Display)] #[display( "{field1} {ident} {field2} {} {}", field2, field1 + field2, ident = 123, field2 = field1, )] struct Struct { field1: i32, field2: i32, } #[test] fn assert() { assert_eq!(Tuple(1, 2).to_string(), "1 123 1 2 3"); assert_eq!( Struct { field1: 1, field2: 2, } .to_string(), "1 123 1 2 3", ); } } mod transparency { use super::*; mod interpolated { use super::*; #[derive(Display)] #[display("{_0}")] struct TupleDisplay(i32, u64); #[derive(Display)] #[display("{:?}", _1)] struct TupleDebug(i32, u64); #[derive(Display)] #[display("{0:b}", _1)] struct TupleBinary(i32, u64); #[derive(Display)] #[display("{named:o}", named = _0)] struct TupleOctal(i32, u64); #[derive(Display)] #[display("{b:x}")] struct StructLowerHex { a: i32, b: u64, } #[derive(Display)] #[display("{:X}", a)] struct StructUpperHex { a: i32, b: u64, } #[derive(Display)] #[display("{a:e}")] struct StructLowerExp { a: f64, b: f32, } #[derive(Display)] #[display("{:E}", b)] struct StructUpperExp { a: f64, b: f32, } #[derive(Display)] #[display("{b:p}")] struct StructPointer<'a> { a: &'a i32, b: &'a i32, } #[test] fn assert() { assert_eq!(format!("{:03}", TupleDisplay(7, 8)), "007"); assert_eq!(format!("{:03}", TupleDebug(7, 8)), "008"); assert_eq!(format!("{:07}", TupleBinary(6, 7)), "0000111"); assert_eq!(format!("{:03}", TupleOctal(9, 10)), "011"); assert_eq!( format!("{:03}", StructLowerHex { a: 41, b: 42 }), "02a" ); assert_eq!( format!("{:03}", StructUpperHex { a: 42, b: 43 }), "02A" ); assert_eq!( format!("{:07}", StructLowerExp { a: 42.0, b: 43.0 }), "004.2e1", ); assert_eq!( format!("{:07}", StructUpperExp { a: 41.0, b: 42.0 }), "004.2E1", ); let (a, b) = (42, 43); assert_eq!( format!("{:018}", StructPointer { a: &a, b: &b }), format!("{:018p}", &b), ); } } } } } mod enums { use super::*; mod no_variants { use super::*; #[derive(Display)] enum Void {} const fn assert() {} const _: () = assert::(); } mod unit_variant { use super::*; #[derive(Display)] enum Enum { Unit, r#RawUnit, Unnamed(), Named {}, #[display("STR_UNIT")] StrUnit, #[display("STR_UNNAMED")] StrUnnamed(), #[display("STR_NAMED")] StrNamed {}, } #[test] fn assert() { assert_eq!(Enum::Unit.to_string(), "Unit"); assert_eq!(Enum::r#RawUnit.to_string(), "RawUnit"); assert_eq!(Enum::Unnamed().to_string(), "Unnamed"); assert_eq!(Enum::Named {}.to_string(), "Named"); assert_eq!(Enum::StrUnit.to_string(), "STR_UNIT"); assert_eq!(Enum::StrUnnamed().to_string(), "STR_UNNAMED"); assert_eq!(Enum::StrNamed {}.to_string(), "STR_NAMED"); } mod transparency { use super::*; mod interpolated { use super::*; const I32: i32 = 11; const F64: f64 = 3.15; const POINTER: &f64 = &3.15; #[derive(Display)] enum Unit { #[display("{I32}")] Display, #[display("{I32:?}")] Debug, #[display("{:b}", I32)] Binary, #[display("{0:o}", I32)] Octal, #[display("{I32:x}")] LowerHex, #[display("{:X}", I32)] UpperHex, #[display("{F64:e}")] LowerExp, #[display("{named:E}", named = F64)] UpperExp, #[display("{POINTER:p}")] Pointer, } #[test] fn assert() { assert_eq!(format!("{:03}", Unit::Display), "011"); assert_eq!(format!("{:03}", Unit::Debug), "011"); assert_eq!(format!("{:07}", Unit::Binary), "0001011"); assert_eq!(format!("{:07}", Unit::Octal), "0000013"); assert_eq!(format!("{:03}", Unit::LowerHex), "00b"); assert_eq!(format!("{:03}", Unit::UpperHex), "00B"); assert_eq!(format!("{:07}", Unit::LowerExp), "03.15e0"); assert_eq!(format!("{:07}", Unit::UpperExp), "03.15E0"); assert_eq!( format!("{:018}", Unit::Pointer), format!("{POINTER:018p}"), ); } } mod omitted { use super::*; mod on_modifiers { use super::*; const I32: i32 = 11; const F64: f64 = 3.15; #[derive(Display)] enum Unit { #[display("{I32:x?}")] LowerDebug, #[display("{I32:X?}")] UpperDebug, #[display("{:^}", I32)] Align, #[display("{:+}", I32)] Sign, #[display("{:#b}", I32)] Alternate, #[display("{:0}", I32)] ZeroPadded, #[display("{:07}", I32)] Width, #[display("{:.1}", F64)] Precision, } #[test] fn assert() { assert_eq!(format!("{:03}", Unit::LowerDebug), "b"); assert_eq!(format!("{:03}", Unit::UpperDebug), "B"); assert_eq!(format!("{:03}", Unit::Align), "11"); assert_eq!(format!("{:04}", Unit::Sign), "+11"); assert_eq!(format!("{:07}", Unit::Alternate), "0b1011"); assert_eq!(format!("{:07}", Unit::ZeroPadded), "11"); assert_eq!(format!("{:03}", Unit::Width), "0000011"); assert_eq!(format!("{:.3}", Unit::Precision), "3.1"); } } } } } mod single_field_variant { use super::*; #[derive(Display)] enum Enum { Unnamed(i32), Named { field: i32, }, #[display("unnamed")] StrUnnamed(i32), #[display("named")] StrNamed { field: i32, }, #[display("{_0} {}", _0)] InterpolatedUnnamed(i32), #[display("{field} {}", field)] InterpolatedNamed { field: i32, }, } #[test] fn assert() { assert_eq!(Enum::Unnamed(1).to_string(), "1"); assert_eq!(Enum::Named { field: 1 }.to_string(), "1"); assert_eq!(Enum::StrUnnamed(1).to_string(), "unnamed"); assert_eq!(Enum::StrNamed { field: 1 }.to_string(), "named"); assert_eq!(Enum::InterpolatedUnnamed(1).to_string(), "1 1"); assert_eq!(Enum::InterpolatedNamed { field: 1 }.to_string(), "1 1"); } mod transparency { use super::*; mod direct { use super::*; #[derive(Display)] enum Display { A(i32), B { field: u8 }, } #[derive(Binary)] enum Binary { A(i32), B { field: u8 }, } #[derive(Octal)] enum Octal { A(i32), B { field: u8 }, } #[derive(LowerHex)] enum LowerHex { A(i32), B { field: u8 }, } #[derive(UpperHex)] enum UpperHex { A(i32), B { field: u8 }, } #[derive(LowerExp)] enum LowerExp { A(f64), B { field: f32 }, } #[derive(UpperExp)] enum UpperExp { A(f64), B { field: f32 }, } #[derive(Pointer)] enum Pointer<'a> { A(&'a i32), B { field: &'a u8 }, } #[test] fn assert() { assert_eq!(format!("{:03}", Display::A(7)), "007"); assert_eq!(format!("{:03}", Display::B { field: 8 }), "008"); assert_eq!(format!("{:07b}", Binary::A(7)), "0000111"); assert_eq!(format!("{:07b}", Binary::B { field: 8 }), "0001000"); assert_eq!(format!("{:03o}", Octal::A(9)), "011"); assert_eq!(format!("{:03o}", Octal::B { field: 10 }), "012"); assert_eq!(format!("{:03x}", LowerHex::A(42)), "02a"); assert_eq!(format!("{:03x}", LowerHex::B { field: 43 }), "02b"); assert_eq!(format!("{:03X}", UpperHex::A(42)), "02A"); assert_eq!(format!("{:03X}", UpperHex::B { field: 43 }), "02B"); assert_eq!(format!("{:07e}", LowerExp::A(42.0)), "004.2e1"); assert_eq!( format!("{:07e}", LowerExp::B { field: 43.0 }), "004.3e1", ); assert_eq!(format!("{:07E}", UpperExp::A(42.0)), "004.2E1"); assert_eq!( format!("{:07E}", UpperExp::B { field: 43.0 }), "004.3E1", ); let (a, b) = (7, 42); assert_eq!( format!("{:018p}", Pointer::A(&a)), format!("{:018p}", &a), ); assert_eq!( format!("{:018p}", Pointer::B { field: &b }), format!("{:018p}", &b), ); } } mod interpolated { use super::*; #[derive(Display)] enum Display { #[display("{_0}")] A(i32), #[display("{}", field)] B { field: u8 }, } #[derive(Display)] enum Debug { #[display("{0:?}", _0)] A(i32), #[display("{named:?}", named = field)] B { field: u8 }, } #[derive(Display)] enum Binary { #[display("{_0:b}")] A(i32), #[display("{:b}", field)] B { field: u8 }, } #[derive(Display)] enum Octal { #[display("{_0:o}")] A(i32), #[display("{:o}", field)] B { field: u8 }, } #[derive(Display)] enum LowerHex { #[display("{_0:x}")] A(i32), #[display("{:x}", field)] B { field: u8 }, } #[derive(Display)] enum UpperHex { #[display("{_0:X}")] A(i32), #[display("{:X}", field)] B { field: u8 }, } #[derive(Display)] enum LowerExp { #[display("{:e}", _0)] A(f64), #[display("{field:e}")] B { field: f32 }, } #[derive(Display)] enum UpperExp { #[display("{:E}", _0)] A(f64), #[display("{field:E}")] B { field: f32 }, } #[derive(Display)] enum Pointer<'a> { #[display("{:p}", *_0)] A(&'a i32), #[display("{field:p}")] B { field: &'a u8 }, } #[test] fn assert() { assert_eq!(format!("{:03}", Display::A(7)), "007"); assert_eq!(format!("{:03}", Display::B { field: 8 }), "008"); assert_eq!(format!("{:03}", Debug::A(8)), "008"); assert_eq!(format!("{:03}", Debug::B { field: 9 }), "009"); assert_eq!(format!("{:07}", Binary::A(7)), "0000111"); assert_eq!(format!("{:07}", Binary::B { field: 8 }), "0001000"); assert_eq!(format!("{:03}", Octal::A(9)), "011"); assert_eq!(format!("{:03}", Octal::B { field: 10 }), "012"); assert_eq!(format!("{:03}", LowerHex::A(42)), "02a"); assert_eq!(format!("{:03}", LowerHex::B { field: 43 }), "02b"); assert_eq!(format!("{:03}", UpperHex::A(42)), "02A"); assert_eq!(format!("{:03}", UpperHex::B { field: 43 }), "02B"); assert_eq!(format!("{:07}", LowerExp::A(42.0)), "004.2e1"); assert_eq!( format!("{:07}", LowerExp::B { field: 43.0 }), "004.3e1", ); assert_eq!(format!("{:07}", UpperExp::A(42.0)), "004.2E1"); assert_eq!( format!("{:07}", UpperExp::B { field: 43.0 }), "004.3E1", ); let (a, b) = (7, 42); assert_eq!( format!("{:018}", Pointer::A(&a)), format!("{:018p}", &a), ); assert_eq!( format!("{:018}", Pointer::B { field: &b }), format!("{:018p}", &b), ); } } mod suppressed { use super::*; #[derive(Display)] enum Display { #[display("{}", format_args!("{_0}"))] A(i32), #[display("{}", format_args!("{}", field))] B { field: u8 }, } #[derive(Display)] enum Debug { #[display("{}", format_args!("{_0:?}"))] A(i32), #[display("{}", format_args!("{:?}", field))] B { field: u8 }, } #[derive(Display)] enum Binary { #[display("{}", format_args!("{_0:b}"))] A(i32), #[display("{}", format_args!("{:b}", field))] B { field: u8 }, } #[derive(Display)] enum Octal { #[display("{}", format_args!("{_0:o}"))] A(i32), #[display("{}", format_args!("{:o}", field))] B { field: u8 }, } #[derive(Display)] enum LowerHex { #[display("{}", format_args!("{_0:x}"))] A(i32), #[display("{}", format_args!("{:x}", field))] B { field: u8 }, } #[derive(Display)] enum UpperHex { #[display("{}", format_args!("{_0:X}"))] A(i32), #[display("{}", format_args!("{:X}", field))] B { field: u8 }, } #[derive(Display)] enum LowerExp { #[display("{}", format_args!("{:e}", _0))] A(f64), #[display("{}", format_args!("{field:e}"))] B { field: f32 }, } #[derive(Display)] enum UpperExp { #[display("{}", format_args!("{:E}", _0))] A(f64), #[display("{}", format_args!("{field:E}"))] B { field: f32 }, } #[derive(Display)] enum Pointer<'a> { #[display("{}", format_args!("{:p}", *_0))] A(&'a i32), #[display("{}", format_args!("{field:p}", field = *field))] B { field: &'a u8 }, } #[test] fn assert() { assert_eq!(format!("{:03}", Display::A(7)), "7"); assert_eq!(format!("{:03}", Display::B { field: 8 }), "8"); assert_eq!(format!("{:03}", Debug::A(8)), "8"); assert_eq!(format!("{:03}", Debug::B { field: 9 }), "9"); assert_eq!(format!("{:07}", Binary::A(7)), "111"); assert_eq!(format!("{:07}", Binary::B { field: 8 }), "1000"); assert_eq!(format!("{:03}", Octal::A(9)), "11"); assert_eq!(format!("{:03}", Octal::B { field: 10 }), "12"); assert_eq!(format!("{:03}", LowerHex::A(42)), "2a"); assert_eq!(format!("{:03}", LowerHex::B { field: 43 }), "2b"); assert_eq!(format!("{:03}", UpperHex::A(42)), "2A"); assert_eq!(format!("{:03}", UpperHex::B { field: 43 }), "2B"); assert_eq!(format!("{:07}", LowerExp::A(42.0)), "4.2e1"); assert_eq!(format!("{:07}", LowerExp::B { field: 43.0 }), "4.3e1"); assert_eq!(format!("{:07}", UpperExp::A(42.0)), "4.2E1"); assert_eq!(format!("{:07}", UpperExp::B { field: 43.0 }), "4.3E1"); let (a, b) = (7, 42); assert_eq!(format!("{:018}", Pointer::A(&a)), format!("{:0p}", &a)); assert_eq!( format!("{:018}", Pointer::B { field: &b }), format!("{:p}", &b), ); } } } } mod multi_field_variant { use super::*; #[derive(Display)] enum Enum { #[display("unnamed")] StrUnnamed(i32, i32), #[display("named")] StrNamed { field1: i32, field2: i32 }, #[display( "{_0} {ident} {_1} {} {}", _1, _0 + _1, ident = 123, _1 = _0, )] InterpolatedUnnamed(i32, i32), #[display( "{field1} {ident} {field2} {} {}", field2, field1 + field2, ident = 123, field2 = field1, )] InterpolatedNamed { field1: i32, field2: i32 }, } #[test] fn assert() { assert_eq!(Enum::StrUnnamed(1, 2).to_string(), "unnamed"); assert_eq!( Enum::StrNamed { field1: 1, field2: 2, } .to_string(), "named", ); assert_eq!(Enum::InterpolatedUnnamed(1, 2).to_string(), "1 123 1 2 3"); assert_eq!( Enum::InterpolatedNamed { field1: 1, field2: 2, } .to_string(), "1 123 1 2 3", ); } mod transparency { use super::*; mod interpolated { use super::*; #[derive(Display)] enum Display { #[display("{_0}")] A(i32, i64), #[display("{}", b)] B { a: u8, b: i32 }, } #[derive(Display)] enum Debug { #[display("{0:?}", _1)] A(i32, i64), #[display("{named:?}", named = a)] B { a: u8, b: i32 }, } #[derive(Display)] enum Binary { #[display("{_0:b}")] A(i32, i64), #[display("{:b}", b)] B { a: u8, b: i32 }, } #[derive(Display)] enum Octal { #[display("{_0:o}")] A(i32, i64), #[display("{:o}", b)] B { a: u8, b: i32 }, } #[derive(Display)] enum LowerHex { #[display("{_0:x}")] A(i32, i64), #[display("{:x}", b)] B { a: u8, b: i32 }, } #[derive(Display)] enum UpperHex { #[display("{_0:X}")] A(i32, i64), #[display("{:X}", b)] B { a: u8, b: i32 }, } #[derive(Display)] enum LowerExp { #[display("{:e}", _1)] A(f64, f32), #[display("{a:e}")] B { a: f64, b: f32 }, } #[derive(Display)] enum UpperExp { #[display("{:E}", _1)] A(f64, f32), #[display("{a:E}")] B { a: f64, b: f32 }, } #[derive(Display)] enum Pointer<'a> { #[display("{:p}", *_1)] A(&'a f64, &'a f32), #[display("{a:p}")] B { a: &'a f64, b: &'a f32 }, } #[test] fn assert() { assert_eq!(format!("{:03}", Display::A(7, 8)), "007"); assert_eq!(format!("{:03}", Display::B { a: 7, b: 8 }), "008"); assert_eq!(format!("{:03}", Debug::A(7, 8)), "008"); assert_eq!(format!("{:03}", Debug::B { a: 7, b: 8 }), "007"); assert_eq!(format!("{:07}", Binary::A(7, 8)), "0000111"); assert_eq!(format!("{:07}", Binary::B { a: 7, b: 8 }), "0001000"); assert_eq!(format!("{:03}", Octal::A(9, 10)), "011"); assert_eq!(format!("{:03}", Octal::B { a: 9, b: 10 }), "012"); assert_eq!(format!("{:03}", LowerHex::A(42, 41)), "02a"); assert_eq!(format!("{:03}", LowerHex::B { a: 42, b: 43 }), "02b"); assert_eq!(format!("{:03}", UpperHex::A(42, 41)), "02A"); assert_eq!(format!("{:03}", UpperHex::B { a: 42, b: 43 }), "02B"); assert_eq!(format!("{:07}", LowerExp::A(41.0, 42.0)), "004.2e1"); assert_eq!( format!("{:07}", LowerExp::B { a: 43.0, b: 52.0 }), "004.3e1", ); assert_eq!(format!("{:07}", UpperExp::A(41.0, 42.0)), "004.2E1"); assert_eq!( format!("{:07}", UpperExp::B { a: 43.0, b: 52.0 }), "004.3E1", ); let (a, b) = (8.3, 42.1); assert_eq!( format!("{:018}", Pointer::A(&7.0, &a)), format!("{:018p}", &a), ); assert_eq!( format!("{:018}", Pointer::B { a: &b, b: &43.3 }), format!("{:018p}", &b), ); } } } mod shared_format { use super::*; mod single { use super::*; #[derive(Display)] #[display("Variant: {_variant}")] enum Enum { #[display("A {_0}")] A(i32), #[display("B {}", field)] B { field: i32, }, C, } #[test] fn assert() { assert_eq!(Enum::A(1).to_string(), "Variant: A 1"); assert_eq!(Enum::B { field: 2 }.to_string(), "Variant: B 2"); assert_eq!(Enum::C.to_string(), "Variant: C"); } } mod transparent { use super::*; #[derive(Display)] #[display("{_variant}")] enum Enum { #[display("A {_0}")] A(i32), #[display("B {}", field)] B { field: i32, }, C, #[display("{_0:b}")] TransparentBinary(i32), } #[test] fn assert() { assert_eq!(Enum::A(1).to_string(), "A 1"); assert_eq!(Enum::B { field: 2 }.to_string(), "B 2"); assert_eq!(Enum::C.to_string(), "C"); assert_eq!( format!("{:08}", Enum::TransparentBinary(4)), "00000100", ); } } mod multiple { use super::*; #[derive(Display)] #[display("{_variant} Variant: {_variant} {}", _variant)] enum Enum { #[display("A {_0}")] A(i32), #[display("B {}", field)] B { field: i32, }, C, } #[test] fn assert() { assert_eq!(Enum::A(1).to_string(), "A 1 Variant: A 1 A 1"); assert_eq!( Enum::B { field: 2 }.to_string(), "B 2 Variant: B 2 B 2", ); assert_eq!(Enum::C.to_string(), "C Variant: C C"); } } mod none { use super::*; /// Make sure that variant-specific bounds are not added if `_variant` is not used. struct NoDisplay; #[derive(Display)] #[display("Variant")] enum Enum { #[display("A {_0}")] A(i32), #[display("B {}", field)] B { field: i32, }, C, D(T), } #[test] fn assert() { assert_eq!(Enum::::A(1).to_string(), "Variant"); assert_eq!( Enum::::B { field: 2 }.to_string(), "Variant", ); assert_eq!(Enum::::C.to_string(), "Variant"); assert_eq!(Enum::::D(NoDisplay).to_string(), "Variant"); } } mod use_field { use super::*; #[derive(Display)] #[display("Variant {_0}")] enum Enum { A(i32), B(&'static str), C(T), } #[test] fn assert() { assert_eq!(Enum::::A(1).to_string(), "Variant 1"); assert_eq!(Enum::::B("abc").to_string(), "Variant abc"); assert_eq!(Enum::::C(9).to_string(), "Variant 9"); } } mod use_field_and_variant { use super::*; #[derive(Display)] #[display("Variant {_variant} {}", _0)] enum Enum { #[display("A")] A(i32), #[display("B")] B(&'static str), #[display("C")] C(T), } #[test] fn assert() { assert_eq!(Enum::::A(1).to_string(), "Variant A 1"); assert_eq!(Enum::::B("abc").to_string(), "Variant B abc"); assert_eq!(Enum::::C(9).to_string(), "Variant C 9"); } } mod pointer { use super::*; #[derive(Display)] #[display("Pointer {_0:p} {_variant} {_0:p}")] enum Pointer<'a> { #[display("A")] A(&'a f64), #[display("B")] B(&'a f32), } #[test] fn assert() { let (a, b) = (8.3, 42.1); assert_eq!( Pointer::A(&a).to_string(), format!("Pointer {0:p} A {0:p}", &a), ); assert_eq!( Pointer::B(&b).to_string(), format!("Pointer {0:p} B {0:p}", &b), ); } } } } } mod generic { use super::*; trait Bound {} impl Bound for () {} fn display_bound(_: &T) -> &'static str { "()" } #[derive(Display)] #[display("Generic {}", field)] struct NamedGenericStruct { field: T, } #[test] fn named_generic_struct() { assert_eq!(NamedGenericStruct { field: 1 }.to_string(), "Generic 1"); } #[derive(Display)] #[display("Generic {field}")] struct InterpolatedNamedGenericStruct { field: T, } #[test] fn interpolated_named_generic_struct() { assert_eq!( InterpolatedNamedGenericStruct { field: 1 }.to_string(), "Generic 1", ); } #[derive(Display)] #[display("Generic {field:<>width$.prec$} {field}")] struct InterpolatedNamedGenericStructWidthPrecision { field: T, width: usize, prec: usize, } #[test] fn interpolated_named_generic_struct_width_precision() { assert_eq!( InterpolatedNamedGenericStructWidthPrecision { field: 1.2345, width: 9, prec: 2, } .to_string(), "Generic <<<<<1.23 1.2345", ); } #[derive(Display)] struct AutoNamedGenericStruct { field: T, } #[test] fn auto_named_generic_struct() { assert_eq!(AutoNamedGenericStruct { field: 1 }.to_string(), "1"); } #[derive(Display)] #[display("{alias}", alias = field)] struct AliasedNamedGenericStruct { field: T, } #[test] fn aliased_named_generic_struct() { assert_eq!(AliasedNamedGenericStruct { field: 1 }.to_string(), "1"); } #[derive(Display)] #[display("{field1}", field1 = field2)] struct AliasedFieldNamedGenericStruct { field1: T, field2: i32, } #[test] fn aliased_field_named_generic_struct() { assert_eq!( AliasedFieldNamedGenericStruct { field1: (), field2: 1, } .to_string(), "1", ); } #[derive(Display)] #[display("Generic {}", _0)] struct UnnamedGenericStruct(T); #[test] fn unnamed_generic_struct() { assert_eq!(UnnamedGenericStruct(2).to_string(), "Generic 2"); } #[derive(Display)] #[display("Generic {_0}")] struct InterpolatedUnnamedGenericStruct(T); #[test] fn interpolated_unnamed_generic_struct() { assert_eq!(InterpolatedUnnamedGenericStruct(2).to_string(), "Generic 2"); } #[derive(Display)] struct AutoUnnamedGenericStruct(T); #[test] fn auto_unnamed_generic_struct() { assert_eq!(AutoUnnamedGenericStruct(2).to_string(), "2"); } #[derive(Display)] #[display("{alias}", alias = _0)] struct AliasedUnnamedGenericStruct(T); #[test] fn aliased_unnamed_generic_struct() { assert_eq!(AliasedUnnamedGenericStruct(2).to_string(), "2"); } #[derive(Display)] #[display("{_0}", _0 = _1)] struct AliasedFieldUnnamedGenericStruct(T, i32); #[test] fn aliased_field_unnamed_generic_struct() { assert_eq!(AliasedFieldUnnamedGenericStruct((), 2).to_string(), "2"); } #[derive(Display)] enum GenericEnum { #[display("Gen::A {}", field)] A { field: A }, #[display("Gen::B {}", _0)] B(B), } #[test] fn generic_enum() { assert_eq!(GenericEnum::A::<_, u8> { field: 1 }.to_string(), "Gen::A 1"); assert_eq!(GenericEnum::B::(2).to_string(), "Gen::B 2"); } #[derive(Display)] enum InterpolatedGenericEnum { #[display("Gen::A {field}")] A { field: A }, #[display("Gen::B {_0}")] B(B), } #[test] fn interpolated_generic_enum() { assert_eq!( InterpolatedGenericEnum::A::<_, u8> { field: 1 }.to_string(), "Gen::A 1", ); assert_eq!( InterpolatedGenericEnum::B::(2).to_string(), "Gen::B 2", ); } #[derive(Display)] enum AutoGenericEnum { A { field: A }, B(B), } #[test] fn auto_generic_enum() { assert_eq!(AutoGenericEnum::A::<_, u8> { field: 1 }.to_string(), "1"); assert_eq!(AutoGenericEnum::B::(2).to_string(), "2"); } #[derive(Display)] #[display("{} {} <-> {0:o} {1:#x} <-> {0:?} {1:X?}", a, b)] struct MultiTraitNamedGenericStruct { a: A, b: B, } #[test] fn multi_trait_named_generic_struct() { let s = MultiTraitNamedGenericStruct { a: 8u8, b: 255 }; assert_eq!(s.to_string(), "8 255 <-> 10 0xff <-> 8 FF"); } #[derive(Display)] #[display("{} {b} <-> {0:o} {1:#x} <-> {0:?} {1:X?}", a, b)] struct InterpolatedMultiTraitNamedGenericStruct { a: A, b: B, } #[test] fn interpolated_multi_trait_named_generic_struct() { let s = InterpolatedMultiTraitNamedGenericStruct { a: 8u8, b: 255 }; assert_eq!(s.to_string(), "8 255 <-> 10 0xff <-> 8 FF"); } #[derive(Display)] #[display("{} {} {{}} {0:o} {1:#x} - {0:>4?} {1:^4X?}", _0, _1)] struct MultiTraitUnnamedGenericStruct(A, B); #[test] fn multi_trait_unnamed_generic_struct() { let s = MultiTraitUnnamedGenericStruct(8u8, 255); assert_eq!(s.to_string(), "8 255 {} 10 0xff - 8 FF "); } #[derive(Display)] #[display("{} {_1} {{}} {0:o} {1:#x} - {0:>4?} {1:^4X?}", _0, _1)] struct InterpolatedMultiTraitUnnamedGenericStruct(A, B); #[test] fn interpolated_multi_trait_unnamed_generic_struct() { let s = InterpolatedMultiTraitUnnamedGenericStruct(8u8, 255); assert_eq!(s.to_string(), "8 255 {} 10 0xff - 8 FF "); } #[derive(Display)] #[display("{}", 3 * 4)] struct UnusedGenericStruct(T); #[test] fn unused_generic_struct() { let s = UnusedGenericStruct(()); assert_eq!(s.to_string(), "12"); } mod associated_type_field_enumerator { use super::*; trait Trait { type Type; } struct Struct; impl Trait for Struct { type Type = i32; } #[test] fn auto_generic_named_struct_associated() { #[derive(Display)] struct AutoGenericNamedStructAssociated { field: ::Type, } let s = AutoGenericNamedStructAssociated:: { field: 10 }; assert_eq!(s.to_string(), "10"); } #[test] fn auto_generic_unnamed_struct_associated() { #[derive(Display)] struct AutoGenericUnnamedStructAssociated(::Type); let s = AutoGenericUnnamedStructAssociated::(10); assert_eq!(s.to_string(), "10"); } #[test] fn auto_generic_enum_associated() { #[derive(Display)] enum AutoGenericEnumAssociated { Enumerator(::Type), } let e = AutoGenericEnumAssociated::::Enumerator(10); assert_eq!(e.to_string(), "10"); } } mod complex_type_field_enumerator { use super::*; #[derive(Display)] struct Struct(T); #[test] fn auto_generic_named_struct_complex() { #[derive(Display)] struct AutoGenericNamedStructComplex { field: Struct, } let s = AutoGenericNamedStructComplex { field: Struct(10) }; assert_eq!(s.to_string(), "10"); } #[test] fn auto_generic_unnamed_struct_complex() { #[derive(Display)] struct AutoGenericUnnamedStructComplex(Struct); let s = AutoGenericUnnamedStructComplex(Struct(10)); assert_eq!(s.to_string(), "10"); } #[test] fn auto_generic_enum_complex() { #[derive(Display)] enum AutoGenericEnumComplex { Enumerator(Struct), } let e = AutoGenericEnumComplex::Enumerator(Struct(10)); assert_eq!(e.to_string(), "10") } } mod reference { use super::*; #[test] fn auto_generic_reference() { #[derive(Display)] struct AutoGenericReference<'a, T>(&'a T); let s = AutoGenericReference(&10); assert_eq!(s.to_string(), "10"); } #[test] fn auto_generic_static_reference() { #[derive(Display)] struct AutoGenericStaticReference(&'static T); let s = AutoGenericStaticReference(&10); assert_eq!(s.to_string(), "10"); } } mod indirect { use super::*; #[derive(Display)] struct Struct(T); #[test] fn auto_generic_indirect() { #[derive(Display)] struct AutoGenericIndirect(Struct<&'static T>); const V: i32 = 10; let s = AutoGenericIndirect(Struct(&V)); assert_eq!(s.to_string(), "10"); } } mod bound { use super::*; #[test] fn simple() { #[derive(Display)] #[display("{} {}", _0, _1)] struct Struct(T1, T2); let s = Struct(10, 20); assert_eq!(s.to_string(), "10 20"); } #[test] fn debug() { #[derive(Debug)] struct OnlyDebug; #[derive(Display)] #[display("{:?}", _0)] struct Struct(T); let s = Struct(OnlyDebug); assert_eq!(s.to_string(), "OnlyDebug"); } #[test] fn underscored_simple() { #[derive(Display)] #[display("{_0} {_1}")] struct Struct(T1, T2); let s = Struct(10, 20); assert_eq!(s.to_string(), "10 20"); } #[test] fn underscored_debug() { #[derive(Debug)] struct OnlyDebug; #[derive(Display)] #[display("{_0:?}")] struct Struct(T); let s = Struct(OnlyDebug); assert_eq!(s.to_string(), "OnlyDebug"); } #[test] fn redundant() { #[derive(Display)] #[display(bound(T1: ::core::fmt::Display, T2: ::core::fmt::Debug))] #[display("{} {:?}", _0, _1)] struct Struct(T1, T2); let s = Struct(10, 20); assert_eq!(s.to_string(), "10 20"); } #[test] fn underscored_redundant() { #[derive(Display)] #[display(bound(T1: ::core::fmt::Display, T2: ::core::fmt::Debug))] #[display("{_0} {_1:?}")] struct Struct(T1, T2); let s = Struct(10, 20); assert_eq!(s.to_string(), "10 20"); } #[test] fn complex() { #[derive(Debug)] struct DebugOnly; trait Trait1 { fn function1(&self) -> &'static str; } trait Trait2 { fn function2(&self) -> &'static str; } impl Trait1 for i32 { fn function1(&self) -> &'static str { "WHAT" } } impl Trait2 for i32 { fn function2(&self) -> &'static str { "EVER" } } impl Trait1 for DebugOnly { fn function1(&self) -> &'static str { "MAN" } } #[derive(Display)] #[display("{} {} {} {} {:?}", _0.function1(), _0, _0.function2(), _1.function1(), _1)] #[display(bound(T1: Trait1 + Trait2, T2: Trait1))] struct Struct(T1, T2); let s = Struct(10, DebugOnly); assert_eq!(s.to_string(), "WHAT 10 EVER MAN DebugOnly"); } #[test] fn underscored_complex() { #[derive(Debug)] struct DebugOnly; trait Trait1 { fn function1(&self) -> &'static str; } trait Trait2 { fn function2(&self) -> &'static str; } impl Trait1 for i32 { fn function1(&self) -> &'static str { "WHAT" } } impl Trait2 for i32 { fn function2(&self) -> &'static str { "EVER" } } impl Trait1 for DebugOnly { fn function1(&self) -> &'static str { "MAN" } } #[derive(Display)] #[display(bound(T1: Trait1 + Trait2, T2: Trait1))] #[display("{} {_0} {} {} {_1:?}", _0.function1(), _0.function2(), _1.function1())] struct Struct(T1, T2); let s = Struct(10, DebugOnly); assert_eq!(s.to_string(), "WHAT 10 EVER MAN DebugOnly"); } #[test] fn explicit_only() { trait Trait { fn function(&self) -> &'static str; } struct NoDisplay; impl Trait for NoDisplay { fn function(&self) -> &'static str { "no display" } } #[derive(Display)] #[display("{}", _0.function())] #[display(bound(T: Trait))] struct Struct(T); let s = Struct(NoDisplay); assert_eq!(s.to_string(), "no display"); } } mod transparency { use super::*; mod direct { use super::*; #[derive( Display, Binary, Octal, LowerHex, UpperHex, LowerExp, UpperExp, Pointer )] struct Tuple(T); #[derive( Display, Binary, Octal, LowerHex, UpperHex, LowerExp, UpperExp, Pointer )] struct Struct { field: T, } #[derive( Display, Binary, Octal, LowerHex, UpperHex, LowerExp, UpperExp, Pointer )] enum Enum { A(A), B { field: B }, } #[test] fn assert() { assert_eq!(format!("{:03}", Tuple(7)), "007"); assert_eq!(format!("{:03}", Struct { field: 7 }), "007"); assert_eq!(format!("{:03}", Enum::<_, i8>::A(7)), "007"); assert_eq!(format!("{:03}", Enum::::B { field: 8 }), "008"); assert_eq!(format!("{:07b}", Tuple(7)), "0000111"); assert_eq!(format!("{:07b}", Struct { field: 7 }), "0000111"); assert_eq!(format!("{:07b}", Enum::<_, i8>::A(7)), "0000111"); assert_eq!(format!("{:07b}", Enum::::B { field: 8 }), "0001000"); assert_eq!(format!("{:03o}", Tuple(9)), "011"); assert_eq!(format!("{:03o}", Struct { field: 9 }), "011"); assert_eq!(format!("{:03o}", Enum::<_, i8>::A(9)), "011"); assert_eq!(format!("{:03o}", Enum::::B { field: 10 }), "012"); assert_eq!(format!("{:03x}", Tuple(42)), "02a"); assert_eq!(format!("{:03x}", Struct { field: 42 }), "02a"); assert_eq!(format!("{:03x}", Enum::<_, i8>::A(42)), "02a"); assert_eq!(format!("{:03x}", Enum::::B { field: 43 }), "02b"); assert_eq!(format!("{:03X}", Tuple(42)), "02A"); assert_eq!(format!("{:03X}", Struct { field: 42 }), "02A"); assert_eq!(format!("{:03X}", Enum::<_, i8>::A(42)), "02A"); assert_eq!(format!("{:03X}", Enum::::B { field: 43 }), "02B"); assert_eq!(format!("{:07e}", Tuple(42.0)), "004.2e1"); assert_eq!(format!("{:07e}", Struct { field: 42.0 }), "004.2e1"); assert_eq!(format!("{:07e}", Enum::<_, i8>::A(42.0)), "004.2e1"); assert_eq!( format!("{:07e}", Enum::::B { field: 43.0 }), "004.3e1", ); assert_eq!(format!("{:07E}", Tuple(42.0)), "004.2E1"); assert_eq!(format!("{:07E}", Struct { field: 42.0 }), "004.2E1"); assert_eq!(format!("{:07E}", Enum::<_, i8>::A(42.0)), "004.2E1"); assert_eq!( format!("{:07E}", Enum::::B { field: 43.0 }), "004.3E1", ); let (a, b) = (42, 7); assert_eq!(format!("{:018p}", Tuple(&a)), format!("{:018p}", &a)); assert_eq!( format!("{:018p}", Struct { field: &a }), format!("{:018p}", &a), ); assert_eq!( format!("{:018p}", Enum::<_, &i8>::A(&b)), format!("{:018p}", &b), ); assert_eq!( format!("{:018p}", Enum::<&i8, _>::B { field: &a }), format!("{:018p}", &a), ); } } mod interpolated { use super::*; #[derive(Display)] #[display("{_0}")] struct TupleDisplay(T); #[derive(Display)] #[display("{0:?}", _0)] struct TupleDebug(T); #[derive(Display)] #[display("{_0:b}")] struct TupleBinary(T, Y); #[derive(Display)] #[display("{_1:o}")] struct TupleOctal(Y, T); #[derive(Display)] #[display("{0:x}", _0)] struct TupleLowerHex(T); #[derive(Display)] #[display("{_0:X}")] struct TupleUpperHex(T); #[derive(Display)] #[display("{:e}", _0)] struct TupleLowerExp(T); #[derive(Display)] #[display("{:E}", _0)] struct TupleUpperExp(T); #[derive(Display)] #[display("{_0:p}")] struct TuplePointer(T); #[derive(Display)] #[display("{field}")] struct StructDisplay { field: T, } #[derive(Display)] #[display("{a:b}")] struct StructBinary { a: T, b: Y, } #[derive(Display)] #[display("{named:o}", named = b)] struct StructOctal { a: Y, b: T, } #[derive(Display)] #[display("{field:x}")] struct StructLowerHex { field: T, } #[derive(Display)] #[display("{field:X}")] struct StructUpperHex { field: T, } #[derive(Display)] #[display("{:e}", field)] struct StructLowerExp { field: T, } #[derive(Display)] #[display("{:E}", field)] struct StructUpperExp { field: T, } #[derive(Display)] #[display("{field:p}")] struct StructPointer { field: T, } #[derive(Display)] enum EnumDisplay { #[display("{_0}")] A(A), #[display("{}", field)] B { field: B }, } #[derive(Display)] enum EnumBinary { #[display("{_0:b}")] A(A, C), #[display("{:b}", b)] B { b: B, d: D }, } #[derive(Display)] enum EnumOctal { #[display("{_1:o}")] A(A, C), #[display("{:o}", d)] B { b: B, d: D }, } #[derive(Display)] enum EnumLowerHex { #[display("{_0:x}")] A(A), #[display("{:x}", field)] B { field: B }, } #[derive(Display)] enum EnumUpperHex { #[display("{_0:X}")] A(A), #[display("{:X}", field)] B { field: B }, } #[derive(Display)] enum EnumLowerExp { #[display("{:e}", _0)] A(A), #[display("{field:e}")] B { field: B }, } #[derive(Display)] enum EnumUpperExp { #[display("{:E}", _0)] A(A), #[display("{field:E}")] B { field: B }, } #[derive(Display)] enum EnumPointer { #[display("{_0:p}")] A(A), #[display("{field:p}")] B { field: B }, } #[test] fn assert() { assert_eq!(format!("{:03}", TupleDisplay(7)), "007"); assert_eq!(format!("{:03}", TupleDebug(8)), "008"); assert_eq!(format!("{:03}", StructDisplay { field: 7 }), "007"); assert_eq!(format!("{:03}", EnumDisplay::<_, i8>::A(7)), "007"); assert_eq!( format!("{:03}", EnumDisplay::::B { field: 8 }), "008", ); assert_eq!(format!("{:07}", TupleBinary(7, ())), "0000111"); assert_eq!(format!("{:07}", StructBinary { a: 7, b: () }), "0000111"); assert_eq!( format!("{:07}", EnumBinary::<_, i8, _, ()>::A(7, ())), "0000111", ); assert_eq!( format!("{:07}", EnumBinary::::B { b: 8, d: () }), "0001000", ); assert_eq!(format!("{:03}", TupleOctal((), 9)), "011"); assert_eq!(format!("{:03}", StructOctal { a: (), b: 9 }), "011"); assert_eq!( format!("{:03}", EnumOctal::<_, (), _, i8>::A((), 9)), "011", ); assert_eq!( format!("{:03}", EnumOctal::<(), _, i8, _>::B { b: (), d: 10 }), "012", ); assert_eq!(format!("{:03}", TupleLowerHex(42)), "02a"); assert_eq!(format!("{:03}", StructLowerHex { field: 42 }), "02a"); assert_eq!(format!("{:03}", EnumLowerHex::<_, i8>::A(42)), "02a"); assert_eq!( format!("{:03}", EnumLowerHex::::B { field: 43 }), "02b", ); assert_eq!(format!("{:03}", TupleUpperHex(42)), "02A"); assert_eq!(format!("{:03}", StructUpperHex { field: 42 }), "02A"); assert_eq!(format!("{:03}", EnumUpperHex::<_, i8>::A(42)), "02A"); assert_eq!( format!("{:03}", EnumUpperHex::::B { field: 43 }), "02B", ); assert_eq!(format!("{:07}", TupleLowerExp(42.0)), "004.2e1"); assert_eq!(format!("{:07}", StructLowerExp { field: 42.0 }), "004.2e1"); assert_eq!(format!("{:07}", EnumLowerExp::<_, i8>::A(42.0)), "004.2e1"); assert_eq!( format!("{:07}", EnumLowerExp::::B { field: 43.0 }), "004.3e1", ); assert_eq!(format!("{:07}", TupleUpperExp(42.0)), "004.2E1"); assert_eq!(format!("{:07}", StructUpperExp { field: 42.0 }), "004.2E1"); assert_eq!(format!("{:07}", EnumUpperExp::<_, i8>::A(42.0)), "004.2E1"); assert_eq!( format!("{:07}", EnumUpperExp::::B { field: 43.0 }), "004.3E1", ); let (a, b) = (42, 7); assert_eq!(format!("{:018}", TuplePointer(&a)), format!("{:018p}", &a)); assert_eq!( format!("{:018}", StructPointer { field: &a }), format!("{:018p}", &a), ); assert_eq!( format!("{:018}", EnumPointer::<_, &i8>::A(&b)), format!("{:018p}", &b), ); assert_eq!( format!("{:018}", EnumPointer::<&i8, _>::B { field: &a }), format!("{:018p}", &a), ); } } mod omitted { use super::*; mod on_modifiers { use super::*; #[derive(Display)] enum Enum { #[display("{_0:x?}")] LowerDebug(A), #[display("{_0:X?}")] UpperDebug(B), #[display("{:^}", _0)] Align(C), #[display("{:+}", _0)] Sign(C), #[display("{:#b}", _0)] Alternate(C), #[display("{:0}", _0)] ZeroPadded(C), #[display("{:07}", _0)] Width(C), #[display("{:.5}", _0)] Precision(D), } #[test] fn assert() { assert_eq!( format!("{:03}", Enum::<_, u8, u8, f64>::LowerDebug(7)), "7", ); assert_eq!( format!("{:03}", Enum::::UpperDebug(8)), "8", ); assert_eq!(format!("{:03}", Enum::::Align(5)), "5"); assert_eq!(format!("{:03}", Enum::::Sign(5)), "+5"); assert_eq!( format!("{:07}", Enum::::Alternate(5)), "0b101", ); assert_eq!( format!("{:07}", Enum::::ZeroPadded(-5)), "-5", ); assert_eq!( format!("{:03}", Enum::::Width(5)), "0000005", ); assert_eq!( format!("{:.3}", Enum::::Precision(1.23456789)), "1.23457", ); } } } } } // See: https://github.com/JelteF/derive_more/issues/363 mod type_variables { mod our_alloc { #[cfg(not(feature = "std"))] pub use alloc::{boxed::Box, format, vec::Vec}; #[cfg(feature = "std")] pub use std::{boxed::Box, format, vec::Vec}; } use our_alloc::{format, Box}; // We want `Vec` in scope to test that code generation works if it is there. #[allow(unused_imports)] use our_alloc::Vec; use derive_more::Display; #[derive(Display, Debug)] #[display("{inner:?}")] #[display(bounds(T: Display))] struct OptionalBox { inner: Option>, } #[derive(Display, Debug)] #[display("{next}")] struct ItemStruct { next: OptionalBox, } #[derive(Display)] #[derive(Debug)] struct ItemTuple(OptionalBox); #[derive(Display)] #[derive(Debug)] #[display("Item({_0})")] struct ItemTupleContainerFmt(OptionalBox); #[derive(Display, Debug)] #[display("{next}")] enum ItemEnumOuterFormat { Variant1 { next: OptionalBox, }, Variant2 { next: OptionalBox, }, } #[derive(Display, Debug)] enum ItemEnumInnerFormat { #[display("{next} {inner}")] Node { next: OptionalBox, inner: i32, }, #[display("{inner}")] Leaf { inner: i32 }, } #[derive(Display)] #[derive(Debug)] #[display("{next:?}, {real:?}")] struct VecMeansDifferent { next: our_alloc::Vec, real: Vec, } #[derive(Display)] #[derive(Debug)] #[display("{t:?}")] struct Array { t: [T; 10], } mod parens { #![allow(unused_parens)] // test that type is found even in parentheses use derive_more::Display; #[derive(Display)] struct Paren { t: (T), } } #[derive(Display)] struct ParenthesizedGenericArgumentsInput { t: dyn Fn(T) -> i32, } #[derive(Display)] struct ParenthesizedGenericArgumentsOutput { t: dyn Fn(i32) -> T, } #[derive(Display)] struct Ptr { t: *const T, } #[derive(Display)] struct Reference<'a, T> { t: &'a T, } #[derive(Display)] struct Slice<'a, T> { t: &'a [T], } #[derive(Display)] struct BareFn { t: Box T>, } #[derive(Display)] struct Tuple { t: Box<(T, T)>, } trait MyTrait {} #[derive(Display)] struct TraitObject { t: Box>, } #[test] fn assert() { assert_eq!( format!( "{}", ItemStruct { next: OptionalBox { inner: Some(Box::new(ItemStruct { next: OptionalBox { inner: None }, })), }, }, ), "Some(ItemStruct { next: OptionalBox { inner: None } })", ); assert_eq!( format!( "{}", ItemTuple(OptionalBox { inner: Some(Box::new(ItemTuple(OptionalBox { inner: None }))), }), ), "Some(ItemTuple(OptionalBox { inner: None }))", ); assert_eq!( format!( "{}", ItemTupleContainerFmt(OptionalBox { inner: Some(Box::new(ItemTupleContainerFmt(OptionalBox { inner: None, }))), }), ), "Item(Some(ItemTupleContainerFmt(OptionalBox { inner: None })))", ); let item = ItemEnumOuterFormat::Variant1 { next: OptionalBox { inner: Some(Box::new(ItemEnumOuterFormat::Variant2 { next: OptionalBox { inner: None }, })), }, }; assert_eq!( format!("{item}"), "Some(Variant2 { next: OptionalBox { inner: None } })", ) } } derive_more-1.0.0/tests/error/derives_for_enums_with_source.rs000064400000000000000000000134361046102023000231230ustar 00000000000000#![allow(dead_code)] // some code is tested for type checking only use super::*; derive_display!(TestErr); #[derive(Debug, Error)] enum TestErr { Unit, NamedImplicitNoSource { field: i32, }, NamedImplicitSource { source: SimpleErr, field: i32, }, #[cfg(feature = "std")] NamedImplicitBoxedSource { source: Box, field: i32, }, NamedExplicitNoSource { #[error(not(source))] source: SimpleErr, field: i32, }, NamedExplicitSource { #[error(source)] explicit_source: SimpleErr, field: i32, }, NamedExplicitNoSourceRedundant { #[error(not(source))] field: i32, }, NamedExplicitSourceRedundant { #[error(source)] source: SimpleErr, field: i32, }, NamedExplicitSuppressesImplicit { source: i32, #[error(source)] field: SimpleErr, }, UnnamedImplicitNoSource(i32, i32), UnnamedImplicitSource(SimpleErr), UnnamedExplicitNoSource(#[error(not(source))] SimpleErr), UnnamedExplicitSource(#[error(source)] SimpleErr, i32), UnnamedExplicitNoSourceRedundant( #[error(not(source))] i32, #[error(not(source))] i32, ), UnnamedExplicitSourceRedundant(#[error(source)] SimpleErr), NamedIgnore { #[error(ignore)] source: SimpleErr, field: i32, }, UnnamedIgnore(#[error(ignore)] SimpleErr), NamedIgnoreRedundant { #[error(ignore)] field: i32, }, UnnamedIgnoreRedundant(#[error(ignore)] i32, #[error(ignore)] i32), #[error(ignore)] NamedVariantIgnore { source: SimpleErr, field: i32, }, #[error(ignore)] UnnamedVariantIgnore(SimpleErr), #[error(ignore)] NamedVariantIgnoreRedundant { field: i32, }, #[error(ignore)] UnnamedVariantIgnoreRedundant(i32, i32), } #[test] fn unit() { assert!(TestErr::Unit.source().is_none()); } #[test] fn named_implicit_no_source() { let err = TestErr::NamedImplicitNoSource { field: 0 }; assert!(err.source().is_none()); } #[test] fn named_implicit_source() { let err = TestErr::NamedImplicitSource { source: SimpleErr, field: 0, }; assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[cfg(feature = "std")] #[test] fn named_implicit_boxed_source() { let err = TestErr::NamedImplicitBoxedSource { source: Box::new(SimpleErr), field: 0, }; assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_no_source() { let err = TestErr::NamedExplicitNoSource { source: SimpleErr, field: 0, }; assert!(err.source().is_none()); } #[test] fn named_explicit_source() { let err = TestErr::NamedExplicitSource { explicit_source: SimpleErr, field: 0, }; assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_no_source_redundant() { let err = TestErr::NamedExplicitNoSourceRedundant { field: 0 }; assert!(err.source().is_none()); } #[test] fn named_explicit_source_redundant() { let err = TestErr::NamedExplicitSourceRedundant { source: SimpleErr, field: 0, }; assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_suppresses_implicit() { let err = TestErr::NamedExplicitSuppressesImplicit { source: 0, field: SimpleErr, }; assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_implicit_no_source() { assert!(TestErr::UnnamedImplicitNoSource(0, 0).source().is_none()); } #[test] fn unnamed_implicit_source() { let err = TestErr::UnnamedImplicitSource(SimpleErr); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_explicit_no_source() { let err = TestErr::UnnamedExplicitNoSource(SimpleErr); assert!(err.source().is_none()); } #[test] fn unnamed_explicit_source() { let err = TestErr::UnnamedExplicitSource(SimpleErr, 0); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_explicit_no_source_redundant() { let err = TestErr::UnnamedExplicitNoSourceRedundant(0, 0); assert!(err.source().is_none()); } #[test] fn unnamed_explicit_source_redundant() { let err = TestErr::UnnamedExplicitSourceRedundant(SimpleErr); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_ignore() { let err = TestErr::NamedIgnore { source: SimpleErr, field: 0, }; assert!(err.source().is_none()); } #[test] fn unnamed_ignore() { let err = TestErr::UnnamedIgnore(SimpleErr); assert!(err.source().is_none()); } #[test] fn named_ignore_redundant() { let err = TestErr::NamedIgnoreRedundant { field: 0 }; assert!(err.source().is_none()); } #[test] fn unnamed_ignore_redundant() { let err = TestErr::UnnamedIgnoreRedundant(0, 0); assert!(err.source().is_none()); } #[test] fn named_variant_ignore() { let err = TestErr::NamedVariantIgnore { source: SimpleErr, field: 0, }; assert!(err.source().is_none()); } #[test] fn unnamed_variant_ignore() { let err = TestErr::UnnamedVariantIgnore(SimpleErr); assert!(err.source().is_none()) } #[test] fn named_variant_ignore_redundant() { let err = TestErr::NamedVariantIgnoreRedundant { field: 0 }; assert!(err.source().is_none()); } #[test] fn unnamed_variant_ignore_redundant() { let err = TestErr::UnnamedVariantIgnoreRedundant(0, 0); assert!(err.source().is_none()) } derive_more-1.0.0/tests/error/derives_for_generic_enums_with_source.rs000064400000000000000000000127021046102023000246120ustar 00000000000000#![allow(dead_code)] // some code is tested for type checking only use super::*; derive_display!(TestErr, T, E); #[derive(Debug, Error)] enum TestErr { Unit, NamedImplicitNoSource { field: T, }, NamedImplicitSource { source: E, field: T, }, NamedExplicitNoSource { #[error(not(source))] source: E, field: T, }, NamedExplicitSource { #[error(source)] explicit_source: E, field: T, }, NamedExplicitNoSourceRedundant { #[error(not(source))] field: T, }, NamedExplicitSourceRedundant { #[error(source)] source: E, field: T, }, NamedExplicitSuppressesImplicit { source: T, #[error(source)] field: E, }, UnnamedImplicitNoSource(T, T), UnnamedImplicitSource(E), UnnamedExplicitNoSource(#[error(not(source))] E), UnnamedExplicitSource(#[error(source)] E, T), UnnamedExplicitNoSourceRedundant(#[error(not(source))] T, #[error(not(source))] T), UnnamedExplicitSourceRedundant(#[error(source)] E), NamedIgnore { #[error(ignore)] source: E, field: T, }, UnnamedIgnore(#[error(ignore)] E), NamedIgnoreRedundant { #[error(ignore)] field: T, }, UnnamedIgnoreRedundant(#[error(ignore)] T, #[error(ignore)] T), #[error(ignore)] NamedVariantIgnore { source: E, field: T, }, #[error(ignore)] UnnamedVariantIgnore(E), #[error(ignore)] NamedVariantIgnoreRedundant { field: T, }, #[error(ignore)] UnnamedVariantIgnoreRedundant(T, T), } #[test] fn unit() { assert!(TestErr::::Unit.source().is_none()); } #[test] fn named_implicit_no_source() { let err = TestErr::::NamedImplicitNoSource { field: 0 }; assert!(err.source().is_none()); } #[test] fn named_implicit_source() { let err = TestErr::NamedImplicitSource { source: SimpleErr, field: 0, }; assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_no_source() { let err = TestErr::NamedExplicitNoSource { source: SimpleErr, field: 0, }; assert!(err.source().is_none()); } #[test] fn named_explicit_source() { let err = TestErr::NamedExplicitSource { explicit_source: SimpleErr, field: 0, }; assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_no_source_redundant() { let err = TestErr::::NamedExplicitNoSourceRedundant { field: 0 }; assert!(err.source().is_none()); } #[test] fn named_explicit_source_redundant() { let err = TestErr::NamedExplicitSourceRedundant { source: SimpleErr, field: 0, }; assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_suppresses_implicit() { let err = TestErr::NamedExplicitSuppressesImplicit { source: 0, field: SimpleErr, }; assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_implicit_no_source() { let err = TestErr::::UnnamedImplicitNoSource(0, 0); assert!(err.source().is_none()); } #[test] fn unnamed_implicit_source() { let err = TestErr::<_, i32>::UnnamedImplicitSource(SimpleErr); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_explicit_no_source() { let err = TestErr::<_, i32>::UnnamedExplicitNoSource(SimpleErr); assert!(err.source().is_none()); } #[test] fn unnamed_explicit_source() { let err = TestErr::UnnamedExplicitSource(SimpleErr, 0); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_explicit_no_source_redundant() { let err = TestErr::::UnnamedExplicitNoSourceRedundant(0, 0); assert!(err.source().is_none()); } #[test] fn unnamed_explicit_source_redundant() { let err = TestErr::<_, i32>::UnnamedExplicitSourceRedundant(SimpleErr); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_ignore() { let err = TestErr::NamedIgnore { source: SimpleErr, field: 0, }; assert!(err.source().is_none()); } #[test] fn unnamed_ignore() { let err = TestErr::<_, i32>::UnnamedIgnore(SimpleErr); assert!(err.source().is_none()); } #[test] fn named_ignore_redundant() { let err = TestErr::::NamedIgnoreRedundant { field: 0 }; assert!(err.source().is_none()); } #[test] fn unnamed_ignore_redundant() { let err = TestErr::::UnnamedIgnoreRedundant(0, 0); assert!(err.source().is_none()); } #[test] fn named_variant_ignore() { let err = TestErr::NamedVariantIgnore { source: SimpleErr, field: 0, }; assert!(err.source().is_none()); } #[test] fn unnamed_variant_ignore() { let err = TestErr::<_, i32>::UnnamedVariantIgnore(SimpleErr); assert!(err.source().is_none()) } #[test] fn named_variant_ignore_redundant() { let err = TestErr::::NamedVariantIgnoreRedundant { field: 0 }; assert!(err.source().is_none()); } #[test] fn unnamed_variant_ignore_redundant() { let err = TestErr::::UnnamedVariantIgnoreRedundant(0, 0); assert!(err.source().is_none()) } derive_more-1.0.0/tests/error/derives_for_generic_structs_with_source.rs000064400000000000000000000132441046102023000251740ustar 00000000000000#![allow(dead_code)] // some code is tested for type checking only use super::*; #[test] fn named_implicit_no_source() { derive_display!(TestErr, T); #[derive(Default, Debug, Error)] struct TestErr { field: T, } assert!(TestErr::::default().source().is_none()); } #[test] fn named_implicit_source() { derive_display!(TestErr, E, T); #[derive(Default, Debug, Error)] struct TestErr { source: E, field: T, } let err = TestErr::::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_no_source() { derive_display!(TestErr, E, T); #[derive(Default, Debug, Error)] struct TestErr { #[error(not(source))] source: E, field: T, } let err = TestErr::::default(); assert!(err.source().is_none()); } #[test] fn named_explicit_source() { derive_display!(TestErr, E, T); #[derive(Default, Debug, Error)] struct TestErr { #[error(source)] explicit_source: E, field: T, } let err = TestErr::::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_no_source_redundant() { derive_display!(TestErr, T); #[derive(Default, Debug, Error)] struct TestErr { #[error(not(source))] field: T, } assert!(TestErr::::default().source().is_none()); } #[test] fn named_explicit_source_redundant() { derive_display!(TestErr, E, T); #[derive(Default, Debug, Error)] struct TestErr { #[error(source)] source: E, field: T, } let err = TestErr::::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_suppresses_implicit() { derive_display!(TestErr, E, T); #[derive(Default, Debug, Error)] struct TestErr { source: E, #[error(source)] field: T, } let err = TestErr::::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_implicit_no_source() { derive_display!(TestErr, T); #[derive(Default, Debug, Error)] struct TestErr(T, T); assert!(TestErr::::default().source().is_none()); } #[test] fn unnamed_implicit_source() { derive_display!(TestErr, E); #[derive(Default, Debug, Error)] struct TestErr(E); let err = TestErr::::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_explicit_no_source() { derive_display!(TestErr, E); #[derive(Default, Debug, Error)] struct TestErr(#[error(not(source))] E); assert!(TestErr::::default().source().is_none()); } #[test] fn unnamed_explicit_source() { derive_display!(TestErr, E, T); #[derive(Default, Debug, Error)] struct TestErr(#[error(source)] E, T); let err = TestErr::::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_explicit_no_source_redundant() { derive_display!(TestErr, T); #[derive(Default, Debug, Error)] struct TestErr(#[error(not(source))] T, #[error(not(source))] T); assert!(TestErr::::default().source().is_none()); } #[test] fn unnamed_explicit_source_redundant() { derive_display!(TestErr, E); #[derive(Default, Debug, Error)] struct TestErr(#[error(source)] E); let err = TestErr::::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_ignore() { derive_display!(TestErr, E, T); #[derive(Default, Debug, Error)] struct TestErr { #[error(ignore)] source: E, field: T, } assert!(TestErr::::default().source().is_none()); } #[test] fn unnamed_ignore() { derive_display!(TestErr, E); #[derive(Default, Debug, Error)] struct TestErr(#[error(ignore)] E); assert!(TestErr::::default().source().is_none()); } #[test] fn named_ignore_redundant() { derive_display!(TestErr, T); #[derive(Default, Debug, Error)] struct TestErr { #[error(ignore)] field: T, } assert!(TestErr::::default().source().is_none()); } #[test] fn unnamed_ignore_redundant() { derive_display!(TestErr, T); #[derive(Default, Debug, Error)] struct TestErr(#[error(ignore)] T, #[error(ignore)] T); assert!(TestErr::::default().source().is_none()); } #[test] fn named_struct_ignore() { derive_display!(TestErr, E, T); #[derive(Default, Debug, Error)] #[error(ignore)] struct TestErr { source: E, field: T, } assert!(TestErr::::default().source().is_none()) } #[test] fn unnamed_struct_ignore() { derive_display!(TestErr, E); #[derive(Default, Debug, Error)] #[error(ignore)] struct TestErr(E); assert!(TestErr::::default().source().is_none()) } #[test] fn named_struct_ignore_redundant() { derive_display!(TestErr, T); #[derive(Default, Debug, Error)] #[error(ignore)] struct TestErr { field: T, } assert!(TestErr::::default().source().is_none()) } #[test] fn unnamed_struct_ignore_redundant() { derive_display!(TestErr, T); #[derive(Default, Debug, Error)] #[error(ignore)] struct TestErr(T, T); assert!(TestErr::::default().source().is_none()) } derive_more-1.0.0/tests/error/derives_for_structs_with_source.rs000064400000000000000000000126541046102023000235040ustar 00000000000000#![allow(dead_code)] // some code is tested for type checking only use super::*; #[test] fn unit() { assert!(SimpleErr.source().is_none()); } #[test] fn named_implicit_no_source() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr { field: i32, } assert!(TestErr::default().source().is_none()); } #[test] fn named_implicit_source() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr { source: SimpleErr, field: i32, } let err = TestErr::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_no_source() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr { #[error(not(source))] source: SimpleErr, field: i32, } assert!(TestErr::default().source().is_none()); } #[test] fn named_explicit_source() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr { #[error(source)] explicit_source: SimpleErr, field: i32, } let err = TestErr::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_no_source_redundant() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr { #[error(not(source))] field: i32, } assert!(TestErr::default().source().is_none()); } #[test] fn named_explicit_source_redundant() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr { #[error(source)] source: SimpleErr, field: i32, } let err = TestErr::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_explicit_suppresses_implicit() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr { source: i32, #[error(source)] field: SimpleErr, } let err = TestErr::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_implicit_no_source() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr(i32, i32); assert!(TestErr::default().source().is_none()); } #[test] fn unnamed_implicit_source() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr(SimpleErr); let err = TestErr::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_explicit_no_source() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr(#[error(not(source))] SimpleErr); assert!(TestErr::default().source().is_none()); } #[test] fn unnamed_explicit_source() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr(#[error(source)] SimpleErr, i32); let err = TestErr::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn unnamed_explicit_no_source_redundant() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr(#[error(not(source))] i32, #[error(not(source))] i32); assert!(TestErr::default().source().is_none()); } #[test] fn unnamed_explicit_source_redundant() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr(#[error(source)] SimpleErr); let err = TestErr::default(); assert!(err.source().is_some()); assert!(err.source().unwrap().is::()); } #[test] fn named_ignore() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr { #[error(ignore)] source: SimpleErr, field: i32, } assert!(TestErr::default().source().is_none()); } #[test] fn unnamed_ignore() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr(#[error(ignore)] SimpleErr); assert!(TestErr::default().source().is_none()); } #[test] fn named_ignore_redundant() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr { #[error(ignore)] field: i32, } assert!(TestErr::default().source().is_none()); } #[test] fn unnamed_ignore_redundant() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr(#[error(ignore)] i32, #[error(ignore)] i32); assert!(TestErr::default().source().is_none()); } #[test] fn named_struct_ignore() { derive_display!(TestErr); #[derive(Default, Debug, Error)] #[error(ignore)] struct TestErr { source: SimpleErr, field: i32, } assert!(TestErr::default().source().is_none()) } #[test] fn unnamed_struct_ignore() { derive_display!(TestErr); #[derive(Default, Debug, Error)] #[error(ignore)] struct TestErr(SimpleErr); assert!(TestErr::default().source().is_none()) } #[test] fn named_struct_ignore_redundant() { derive_display!(TestErr); #[derive(Default, Debug, Error)] #[error(ignore)] struct TestErr { field: i32, } assert!(TestErr::default().source().is_none()) } #[test] fn unnamed_struct_ignore_redundant() { derive_display!(TestErr); #[derive(Default, Debug, Error)] #[error(ignore)] struct TestErr(i32, i32); assert!(TestErr::default().source().is_none()) } derive_more-1.0.0/tests/error/mod.rs000064400000000000000000000023701046102023000155440ustar 00000000000000use derive_more::Error; /// Derives `std::fmt::Display` for structs/enums. /// Derived implementation outputs empty string. /// Useful, as a way to formally satisfy `Display` trait bound. /// /// ## Syntax: /// /// For regular structs/enums: /// /// ``` /// enum MyEnum { /// ... /// } /// /// derive_display!(MyEnum); /// ``` /// /// For generic structs/enums: /// /// ``` /// struct MyGenericStruct { /// ... /// } /// /// derive_display!(MyGenericStruct, T, U); /// ``` macro_rules! derive_display { (@fmt) => { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { write!(f, "") } }; ($type:ident) => { impl ::core::fmt::Display for $type { derive_display!(@fmt); } }; ($type:ident, $($type_parameters:ident),*) => { impl<$($type_parameters),*> ::core::fmt::Display for $type<$($type_parameters),*> { derive_display!(@fmt); } }; } mod derives_for_enums_with_source; mod derives_for_generic_enums_with_source; mod derives_for_generic_structs_with_source; mod derives_for_structs_with_source; #[cfg(all(feature = "std", nightly))] mod nightly; derive_display!(SimpleErr); #[derive(Default, Debug, Error)] struct SimpleErr; derive_more-1.0.0/tests/error/nightly/derives_for_enums_with_backtrace.rs000064400000000000000000000344671046102023000252270ustar 00000000000000// For creating backtraces with different addresses in tests. #![allow(clippy::redundant_closure, clippy::redundant_closure_call)] // for testing #![allow(dead_code)] // some code is tested for type checking only use core::error::{request_ref, request_value}; use super::*; derive_display!(TestErr); #[derive(Debug, Error)] enum TestErr { Unit, NamedImplicitNoBacktrace { field: i32, }, NamedImplicitBacktraceByFieldName { backtrace: MyBacktrace, field: i32, }, NamedImplicitBacktraceByFieldType { implicit_backtrace: Backtrace, field: i32, }, NamedExplicitNoBacktraceByFieldName { #[error(not(backtrace))] backtrace: MyBacktrace, field: i32, }, NamedExplicitNoBacktraceByFieldType { #[error(not(backtrace))] implicit_backtrace: Backtrace, field: i32, }, NamedExplicitBacktrace { #[error(backtrace)] explicit_backtrace: MyBacktrace, field: i32, }, NamedExplicitNoBacktraceRedundant { #[error(not(backtrace))] not_backtrace: MyBacktrace, #[error(not(backtrace))] field: i32, }, NamedExplicitBacktraceByFieldNameRedundant { #[error(backtrace)] backtrace: MyBacktrace, field: i32, }, NamedExplicitBacktraceByFieldTypeRedundant { #[error(backtrace)] implicit_backtrace: Backtrace, field: i32, }, NamedExplicitSuppressesImplicit { #[error(backtrace)] not_backtrace: MyBacktrace, backtrace: Backtrace, field: i32, }, NamedImplicitNoBacktraceFromSource { #[error(source)] err: BacktraceErr, }, NamedExplicitNoBacktraceFromSource { #[error(source, not(backtrace))] err: BacktraceErr, }, NamedExplicitBacktraceFromSource { #[error(backtrace, source)] err: BacktraceErr, }, NamedImplicitDifferentSourceAndBacktrace { #[error(source)] err: BacktraceErr, backtrace: Backtrace, }, NamedExplicitDifferentSourceAndBacktrace { #[error(source)] err: BacktraceErr, #[error(backtrace)] backtrace: Backtrace, }, UnnamedImplicitNoBacktrace(i32, i32), UnnamedImplicitBacktrace(Backtrace, i32, i32), UnnamedExplicitNoBacktrace(#[error(not(backtrace))] Backtrace, i32), UnnamedExplicitBacktrace(#[error(backtrace)] MyBacktrace, i32, i32), UnnamedExplicitNoBacktraceRedundant( #[error(not(backtrace))] MyBacktrace, #[error(not(backtrace))] i32, ), UnnamedExplicitBacktraceRedundant(#[error(backtrace)] Backtrace, i32, i32), UnnamedExplicitSuppressesImplicit(#[error(backtrace)] MyBacktrace, Backtrace, i32), UnnamedImplicitNoBacktraceFromSource(BacktraceErr), UnnamedExplicitNoBacktraceFromSource(#[error(not(backtrace))] BacktraceErr), UnnamedExplicitBacktraceFromSource(#[error(backtrace)] BacktraceErr), UnnamedImplicitDifferentSourceAndBacktrace( #[error(source)] BacktraceErr, Backtrace, ), UnnamedExplicitDifferentSourceAndBacktrace( #[error(source)] BacktraceErr, #[error(backtrace)] Backtrace, ), } impl TestErr { fn get_stored_backtrace(&self) -> &Backtrace { match self { Self::NamedImplicitBacktraceByFieldName { backtrace, .. } | Self::NamedImplicitBacktraceByFieldType { implicit_backtrace: backtrace, .. } | Self::NamedExplicitBacktrace { explicit_backtrace: backtrace, .. } | Self::NamedExplicitBacktraceByFieldNameRedundant { backtrace, .. } | Self::NamedExplicitBacktraceByFieldTypeRedundant { implicit_backtrace: backtrace, .. } | Self::NamedExplicitSuppressesImplicit { not_backtrace: backtrace, .. } | Self::NamedImplicitDifferentSourceAndBacktrace { backtrace, .. } | Self::NamedExplicitDifferentSourceAndBacktrace { backtrace, .. } | Self::UnnamedImplicitBacktrace(backtrace, _, _) | Self::UnnamedExplicitBacktrace(backtrace, _, _) | Self::UnnamedExplicitBacktraceRedundant(backtrace, _, _) | Self::UnnamedExplicitSuppressesImplicit(backtrace, _, _) | Self::UnnamedImplicitDifferentSourceAndBacktrace(_, backtrace) | Self::UnnamedExplicitDifferentSourceAndBacktrace(_, backtrace) => { backtrace } _ => panic!("ERROR IN TEST IMPLEMENTATION"), } } fn get_unused_backtrace(&self) -> &Backtrace { match self { Self::NamedExplicitSuppressesImplicit { backtrace, .. } => backtrace, Self::UnnamedExplicitSuppressesImplicit(_, backtrace, _) => backtrace, _ => panic!("ERROR IN TEST IMPLEMENTATION"), } } fn get_source_backtrace(&self) -> &Backtrace { request_ref(match self { Self::NamedExplicitBacktraceFromSource { err } | Self::NamedExplicitDifferentSourceAndBacktrace { err, .. } | Self::NamedImplicitDifferentSourceAndBacktrace { err, .. } | Self::UnnamedExplicitBacktraceFromSource(err) | Self::UnnamedExplicitDifferentSourceAndBacktrace(err, ..) | Self::UnnamedImplicitDifferentSourceAndBacktrace(err, ..) => err, _ => panic!("ERROR IN TEST IMPLEMENTATION"), }) .unwrap() } } type MyBacktrace = Backtrace; #[test] fn unit() { assert!(request_ref::(&TestErr::Unit).is_none()); } #[test] fn named_implicit_no_backtrace() { let err = TestErr::NamedImplicitNoBacktrace { field: 0 }; assert!(request_ref::(&err).is_none()); } #[test] fn named_implicit_backtrace_by_field_name() { let err = TestErr::NamedImplicitBacktraceByFieldName { backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn named_implicit_backtrace_by_field_type() { let err = TestErr::NamedImplicitBacktraceByFieldType { implicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn named_explicit_no_backtrace_by_field_name() { let err = TestErr::NamedExplicitNoBacktraceByFieldName { backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_none()); } #[test] fn named_explicit_no_backtrace_by_field_type() { let err = TestErr::NamedExplicitNoBacktraceByFieldType { implicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_none()); } #[test] fn named_explicit_backtrace() { let err = TestErr::NamedExplicitBacktrace { explicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn named_explicit_no_backtrace_redundant() { let err = TestErr::NamedExplicitNoBacktraceRedundant { not_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_none()); } #[test] fn named_explicit_backtrace_by_field_name_redundant() { let err = TestErr::NamedExplicitBacktraceByFieldNameRedundant { backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn named_explicit_backtrace_by_field_type_redundant() { let err = TestErr::NamedExplicitBacktraceByFieldTypeRedundant { implicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn named_explicit_suppresses_implicit() { let err = TestErr::NamedExplicitSuppressesImplicit { not_backtrace: Backtrace::force_capture(), backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_unused_backtrace); } #[test] fn named_implicit_no_backtrace_from_source() { let err = TestErr::NamedImplicitNoBacktraceFromSource { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn named_explicit_no_backtrace_from_source() { let err = TestErr::NamedExplicitNoBacktraceFromSource { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn named_explicit_backtrace_from_source() { let err = TestErr::NamedExplicitBacktraceFromSource { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_source_backtrace); } #[test] fn named_implicit_different_source_and_backtrace() { let err = TestErr::NamedImplicitDifferentSourceAndBacktrace { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_source_backtrace); } #[test] fn named_explicit_different_source_and_backtrace() { let err = TestErr::NamedExplicitDifferentSourceAndBacktrace { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_source_backtrace); } #[test] fn unnamed_implicit_no_backtrace() { let err = TestErr::UnnamedImplicitNoBacktrace(0, 0); assert!(request_ref::(&err).is_none()); } #[test] fn unnamed_implicit_backtrace() { let err = TestErr::UnnamedImplicitBacktrace(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn unnamed_explicit_no_backtrace() { let err = TestErr::UnnamedExplicitNoBacktrace(Backtrace::force_capture(), 0); assert!(request_ref::(&err).is_none()); } #[test] fn unnamed_explicit_backtrace() { let err = TestErr::UnnamedExplicitBacktrace(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn unnamed_explicit_no_backtrace_redundant() { let err = TestErr::UnnamedExplicitNoBacktraceRedundant(Backtrace::force_capture(), 0); assert!(request_ref::(&err).is_none()); } #[test] fn unnamed_explicit_backtrace_redundant() { let err = TestErr::UnnamedExplicitBacktraceRedundant(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn unnamed_explicit_suppresses_implicit() { let err = TestErr::UnnamedExplicitSuppressesImplicit( Backtrace::force_capture(), (|| Backtrace::force_capture())(), // ensure backtraces are different 0, ); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_unused_backtrace); } #[test] fn unnamed_implicit_no_backtrace_from_source() { let err = TestErr::UnnamedImplicitNoBacktraceFromSource(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn unnamed_explicit_no_backtrace_from_source() { let err = TestErr::UnnamedExplicitNoBacktraceFromSource(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn unnamed_explicit_backtrace_from_source() { let err = TestErr::UnnamedExplicitBacktraceFromSource(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_source_backtrace); } #[test] fn unnamed_implicit_different_source_and_backtrace() { let err = TestErr::UnnamedImplicitDifferentSourceAndBacktrace( BacktraceErr { backtrace: Backtrace::force_capture(), }, (|| Backtrace::force_capture())(), // ensure backtraces are different ); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_source_backtrace); } #[test] fn unnamed_explicit_different_source_and_backtrace() { let err = TestErr::UnnamedExplicitDifferentSourceAndBacktrace( BacktraceErr { backtrace: Backtrace::force_capture(), }, (|| Backtrace::force_capture())(), // ensure backtraces are different ); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_source_backtrace); } derive_more-1.0.0/tests/error/nightly/derives_for_generic_enums_with_backtrace.rs000064400000000000000000000351151046102023000267120ustar 00000000000000// For creating backtraces with different addresses in tests. #![allow(clippy::redundant_closure, clippy::redundant_closure_call)] // for testing #![allow(dead_code)] // some code is tested for type checking only use core::error::{request_ref, request_value}; use super::*; derive_display!(TestErr, T); #[derive(Debug, Error)] enum TestErr { Unit, NamedImplicitNoBacktrace { field: T, }, NamedImplicitBacktraceByFieldName { backtrace: MyBacktrace, field: T, }, NamedImplicitBacktraceByFieldType { implicit_backtrace: Backtrace, field: T, }, NamedExplicitNoBacktraceByFieldName { #[error(not(backtrace))] backtrace: MyBacktrace, field: T, }, NamedExplicitNoBacktraceByFieldType { #[error(not(backtrace))] implicit_backtrace: Backtrace, field: T, }, NamedExplicitBacktrace { #[error(backtrace)] explicit_backtrace: MyBacktrace, field: T, }, NamedExplicitNoBacktraceRedundant { #[error(not(backtrace))] not_backtrace: MyBacktrace, #[error(not(backtrace))] field: T, }, NamedExplicitBacktraceByFieldNameRedundant { #[error(backtrace)] backtrace: MyBacktrace, field: T, }, NamedExplicitBacktraceByFieldTypeRedundant { #[error(backtrace)] implicit_backtrace: Backtrace, field: T, }, NamedExplicitSuppressesImplicit { #[error(backtrace)] not_backtrace: MyBacktrace, backtrace: Backtrace, field: T, }, UnnamedImplicitNoBacktrace(T, T), UnnamedImplicitBacktrace(Backtrace, T, T), UnnamedExplicitNoBacktrace(#[error(not(backtrace))] Backtrace, T), UnnamedExplicitBacktrace(#[error(backtrace)] MyBacktrace, T, T), UnnamedExplicitNoBacktraceRedundant( #[error(not(backtrace))] MyBacktrace, #[error(not(backtrace))] T, ), UnnamedExplicitBacktraceRedundant(#[error(backtrace)] Backtrace, T, T), UnnamedExplicitSuppressesImplicit(#[error(backtrace)] MyBacktrace, Backtrace, T), } impl TestErr { fn get_stored_backtrace(&self) -> &Backtrace { match self { Self::NamedImplicitBacktraceByFieldName { backtrace, .. } => backtrace, Self::NamedImplicitBacktraceByFieldType { implicit_backtrace, .. } => implicit_backtrace, Self::NamedExplicitBacktrace { explicit_backtrace, .. } => explicit_backtrace, Self::NamedExplicitBacktraceByFieldNameRedundant { backtrace, .. } => { backtrace } Self::NamedExplicitBacktraceByFieldTypeRedundant { implicit_backtrace, .. } => implicit_backtrace, Self::NamedExplicitSuppressesImplicit { not_backtrace, .. } => { not_backtrace } Self::UnnamedImplicitBacktrace(backtrace, _, _) => backtrace, Self::UnnamedExplicitBacktrace(backtrace, _, _) => backtrace, Self::UnnamedExplicitBacktraceRedundant(backtrace, _, _) => backtrace, Self::UnnamedExplicitSuppressesImplicit(backtrace, _, _) => backtrace, _ => panic!("ERROR IN TEST IMPLEMENTATION"), } } fn get_unused_backtrace(&self) -> &Backtrace { match self { Self::NamedExplicitSuppressesImplicit { backtrace, .. } => backtrace, Self::UnnamedExplicitSuppressesImplicit(_, backtrace, _) => backtrace, _ => panic!("ERROR IN TEST IMPLEMENTATION"), } } } type MyBacktrace = Backtrace; #[test] fn unit() { assert!(request_ref::(&TestErr::::Unit).is_none()); } #[test] fn named_implicit_no_backtrace() { let err = TestErr::NamedImplicitNoBacktrace { field: 0 }; assert!(request_ref::(&err).is_none()); } #[test] fn named_implicit_backtrace_by_field_name() { let err = TestErr::NamedImplicitBacktraceByFieldName { backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn named_implicit_backtrace_by_field_type() { let err = TestErr::NamedImplicitBacktraceByFieldType { implicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn named_explicit_no_backtrace_by_field_name() { let err = TestErr::NamedExplicitNoBacktraceByFieldName { backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_none()); } #[test] fn named_explicit_no_backtrace_by_field_type() { let err = TestErr::NamedExplicitNoBacktraceByFieldType { implicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_none()); } #[test] fn named_explicit_backtrace() { let err = TestErr::NamedExplicitBacktrace { explicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn named_explicit_no_backtrace_redundant() { let err = TestErr::NamedExplicitNoBacktraceRedundant { not_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_none()); } #[test] fn named_explicit_backtrace_by_field_name_redundant() { let err = TestErr::NamedExplicitBacktraceByFieldNameRedundant { backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn named_explicit_backtrace_by_field_type_redundant() { let err = TestErr::NamedExplicitBacktraceByFieldTypeRedundant { implicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn named_explicit_suppresses_implicit() { let err = TestErr::NamedExplicitSuppressesImplicit { not_backtrace: Backtrace::force_capture(), backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_unused_backtrace); } #[test] fn unnamed_implicit_no_backtrace() { let err = TestErr::UnnamedImplicitNoBacktrace(0, 0); assert!(request_ref::(&err).is_none()); } #[test] fn unnamed_implicit_backtrace() { let err = TestErr::UnnamedImplicitBacktrace(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn unnamed_explicit_no_backtrace() { let err = TestErr::UnnamedExplicitNoBacktrace(Backtrace::force_capture(), 0); assert!(request_ref::(&err).is_none()); } #[test] fn unnamed_explicit_backtrace() { let err = TestErr::UnnamedExplicitBacktrace(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn unnamed_explicit_no_backtrace_redundant() { let err = TestErr::UnnamedExplicitNoBacktraceRedundant(Backtrace::force_capture(), 0); assert!(request_ref::(&err).is_none()); } #[test] fn unnamed_explicit_backtrace_redundant() { let err = TestErr::UnnamedExplicitBacktraceRedundant(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); } #[test] fn unnamed_explicit_suppresses_implicit() { let err = TestErr::UnnamedExplicitSuppressesImplicit( Backtrace::force_capture(), (|| Backtrace::force_capture())(), // ensure backtraces are different 0, ); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_unused_backtrace); } derive_display!(BoundedTestErr, T); #[derive(Debug, Error)] enum BoundedTestErr { NamedImplicitNoBacktraceFromSource { #[error(source)] err: T, }, NamedExplicitNoBacktraceFromSource { #[error(source, not(backtrace))] err: T, }, NamedExplicitBacktraceFromSource { #[error(backtrace, source)] err: T, }, NamedImplicitDifferentSourceAndBacktrace { #[error(source)] err: T, backtrace: Backtrace, }, NamedExplicitDifferentSourceAndBacktrace { #[error(source)] err: T, #[error(backtrace)] backtrace: Backtrace, }, UnnamedImplicitNoBacktraceFromSource(T), UnnamedExplicitNoBacktraceFromSource(#[error(not(backtrace))] T), UnnamedExplicitBacktraceFromSource(#[error(backtrace)] T), UnnamedImplicitDifferentSourceAndBacktrace(#[error(source)] T, Backtrace), UnnamedExplicitDifferentSourceAndBacktrace( #[error(source)] T, #[error(backtrace)] Backtrace, ), } impl BoundedTestErr { fn get_stored_backtrace(&self) -> &Backtrace { match self { Self::NamedImplicitDifferentSourceAndBacktrace { backtrace, .. } | Self::NamedExplicitDifferentSourceAndBacktrace { backtrace, .. } | Self::UnnamedImplicitDifferentSourceAndBacktrace(_, backtrace) | Self::UnnamedExplicitDifferentSourceAndBacktrace(_, backtrace) => { backtrace } _ => panic!("ERROR IN TEST IMPLEMENTATION"), } } fn get_source_backtrace(&self) -> &Backtrace { request_ref(match self { Self::NamedExplicitBacktraceFromSource { err } | Self::NamedExplicitDifferentSourceAndBacktrace { err, .. } | Self::NamedImplicitDifferentSourceAndBacktrace { err, .. } | Self::UnnamedExplicitBacktraceFromSource(err) | Self::UnnamedExplicitDifferentSourceAndBacktrace(err, ..) | Self::UnnamedImplicitDifferentSourceAndBacktrace(err, ..) => err, _ => panic!("ERROR IN TEST IMPLEMENTATION"), }) .unwrap() } } #[test] fn named_implicit_no_backtrace_from_source() { let err = BoundedTestErr::NamedImplicitNoBacktraceFromSource { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn named_explicit_no_backtrace_from_source() { let err = BoundedTestErr::NamedExplicitNoBacktraceFromSource { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn named_explicit_backtrace_from_source() { let err = BoundedTestErr::NamedExplicitBacktraceFromSource { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_source_backtrace); } #[test] fn named_implicit_different_source_and_backtrace() { let err = BoundedTestErr::NamedImplicitDifferentSourceAndBacktrace { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_source_backtrace); } #[test] fn named_explicit_different_source_and_backtrace() { let err = BoundedTestErr::NamedExplicitDifferentSourceAndBacktrace { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_source_backtrace); } #[test] fn unnamed_implicit_no_backtrace_from_source() { let err = BoundedTestErr::UnnamedImplicitNoBacktraceFromSource(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn unnamed_explicit_no_backtrace_from_source() { let err = BoundedTestErr::UnnamedExplicitNoBacktraceFromSource(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn unnamed_explicit_backtrace_from_source() { let err = BoundedTestErr::UnnamedExplicitBacktraceFromSource(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_source_backtrace); } #[test] fn unnamed_implicit_different_source_and_backtrace() { let err = BoundedTestErr::UnnamedImplicitDifferentSourceAndBacktrace( BacktraceErr { backtrace: Backtrace::force_capture(), }, (|| Backtrace::force_capture())(), // ensure backtraces are different ); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_source_backtrace); } #[test] fn unnamed_explicit_different_source_and_backtrace() { let err = BoundedTestErr::UnnamedExplicitDifferentSourceAndBacktrace( BacktraceErr { backtrace: Backtrace::force_capture(), }, (|| Backtrace::force_capture())(), // ensure backtraces are different ); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .get_stored_backtrace); assert_bt!(!=, err, .get_source_backtrace); } derive_more-1.0.0/tests/error/nightly/derives_for_generic_structs_with_backtrace.rs000064400000000000000000000277261046102023000273030ustar 00000000000000// For creating backtraces with different addresses in tests. #![allow(clippy::redundant_closure, clippy::redundant_closure_call)] // for testing #![allow(dead_code)] // some code is tested for type checking only use core::error::{request_ref, request_value}; use super::*; #[test] fn named_implicit_no_backtrace() { derive_display!(TestErr, T); #[derive(Default, Debug, Error)] struct TestErr { field: T, } assert!(request_ref::(&TestErr::::default()).is_none()); } #[test] fn named_implicit_backtrace_by_field_name() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { backtrace: MyBacktrace, field: T, } type MyBacktrace = Backtrace; let err = TestErr { backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err); } #[test] fn named_implicit_backtrace_by_field_type() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { implicit_backtrace: Backtrace, field: T, } let err = TestErr { implicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, implicit_backtrace); } #[test] fn named_explicit_no_backtrace_by_field_name() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(not(backtrace))] backtrace: MyBacktrace, field: T, } type MyBacktrace = Backtrace; assert!(request_ref::(&TestErr { backtrace: Backtrace::force_capture(), field: 0 }) .is_none()); } #[test] fn named_explicit_no_backtrace_by_field_type() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(not(backtrace))] implicit_backtrace: Backtrace, field: T, } assert!(request_ref::(&TestErr { implicit_backtrace: Backtrace::force_capture(), field: 0 }) .is_none()); } #[test] fn named_explicit_backtrace() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(backtrace)] explicit_backtrace: MyBacktrace, field: T, } type MyBacktrace = Backtrace; let err = TestErr { explicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, explicit_backtrace); } #[test] fn named_explicit_no_backtrace_redundant() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(not(backtrace))] not_backtrace: MyBacktrace, #[error(not(backtrace))] field: T, } type MyBacktrace = Backtrace; assert!(request_ref::(&TestErr { not_backtrace: Backtrace::force_capture(), field: 0 }) .is_none()); } #[test] fn named_explicit_backtrace_by_field_name_redundant() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(backtrace)] backtrace: MyBacktrace, field: T, } type MyBacktrace = Backtrace; let err = TestErr { backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err); } #[test] fn named_explicit_backtrace_by_field_type_redundant() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(backtrace)] implicit_backtrace: Backtrace, field: T, } let err = TestErr { implicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, implicit_backtrace); } #[test] fn named_explicit_suppresses_implicit() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(backtrace)] not_backtrace: MyBacktrace, backtrace: Backtrace, field: T, } type MyBacktrace = Backtrace; let err = TestErr { not_backtrace: Backtrace::force_capture(), backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, not_backtrace); assert_bt!(!=, err); } #[test] fn named_implicit_no_backtrace_from_source() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(source)] err: T, } let err = TestErr { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn named_explicit_no_backtrace_from_source() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(source, not(backtrace))] err: T, } let err = TestErr { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn named_explicit_backtrace_from_source() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(backtrace, source)] err: T, } let err = TestErr { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, request_ref::(&err.err).unwrap()); } #[test] fn named_implicit_different_source_and_backtrace() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(source)] err: T, backtrace: Backtrace, } let err = TestErr { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, backtrace); assert_bt!(!=, err, request_ref::(&err.err).unwrap()); } #[test] fn named_explicit_different_source_and_backtrace() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr { #[error(source)] err: T, #[error(backtrace)] backtrace: Backtrace, } let err = TestErr { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, backtrace); assert_bt!(!=, err, request_ref::(&err.err).unwrap()); } #[test] fn unnamed_implicit_no_backtrace() { derive_display!(TestErr, T); #[derive(Default, Debug, Error)] struct TestErr(T, T); assert!(request_ref::(&TestErr::::default()).is_none()); } #[test] fn unnamed_implicit_backtrace() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr(Backtrace, T, T); let err = TestErr(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .0); } #[test] fn unnamed_explicit_no_backtrace() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr(#[error(not(backtrace))] Backtrace, T); assert!( request_ref::(&TestErr(Backtrace::force_capture(), 0)).is_none() ); } #[test] fn unnamed_explicit_backtrace() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr(#[error(backtrace)] MyBacktrace, T, T); type MyBacktrace = Backtrace; let err = TestErr(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .0); } #[test] fn unnamed_explicit_no_backtrace_redundant() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr( #[error(not(backtrace))] MyBacktrace, #[error(not(backtrace))] T, ); type MyBacktrace = Backtrace; assert!( request_ref::(&TestErr(Backtrace::force_capture(), 0)).is_none() ); } #[test] fn unnamed_explicit_backtrace_redundant() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr(#[error(backtrace)] Backtrace, T, T); let err = TestErr(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .0); } #[test] fn unnamed_explicit_suppresses_implicit() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr(#[error(backtrace)] MyBacktrace, Backtrace, T); type MyBacktrace = Backtrace; let err = TestErr( Backtrace::force_capture(), (|| Backtrace::force_capture())(), // ensure backtraces are different 0, ); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .0); assert_bt!(!=, err, .1); } #[test] fn unnamed_implicit_no_backtrace_from_source() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr(T); let err = TestErr(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn unnamed_explicit_no_backtrace_from_source() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr(#[error(not(backtrace))] T); let err = TestErr(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn unnamed_explicit_backtrace_from_source() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr(#[error(backtrace)] T); let err = TestErr(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, request_ref::(&err.0).unwrap()); } #[test] fn unnamed_implicit_different_source_and_backtrace() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr(#[error(source)] T, Backtrace); let err = TestErr( BacktraceErr { backtrace: Backtrace::force_capture(), }, (|| Backtrace::force_capture())(), // ensure backtraces are different ); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .1); assert_bt!(!=, err, request_ref::(&err.0).unwrap()); } #[test] fn unnamed_explicit_different_source_and_backtrace() { derive_display!(TestErr, T); #[derive(Debug, Error)] struct TestErr(#[error(source)] T, #[error(backtrace)] Backtrace); let err = TestErr( BacktraceErr { backtrace: Backtrace::force_capture(), }, (|| Backtrace::force_capture())(), // ensure backtraces are different ); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .1); assert_bt!(!=, err, request_ref::(&err.0).unwrap()); } derive_more-1.0.0/tests/error/nightly/derives_for_structs_with_backtrace.rs000064400000000000000000000300221046102023000255660ustar 00000000000000// For creating backtraces with different addresses in tests. #![allow(clippy::redundant_closure, clippy::redundant_closure_call)] // for testing #![allow(dead_code)] // some code is tested for type checking only use core::error::{request_ref, request_value}; use super::*; #[test] fn unit() { assert!(request_ref::(&SimpleErr).is_none()); } #[test] fn named_implicit_no_backtrace() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr { field: i32, } assert!(request_ref::(&TestErr::default()).is_none()); } #[test] fn named_implicit_backtrace_by_field_name() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { backtrace: MyBacktrace, field: i32, } type MyBacktrace = Backtrace; let err = TestErr { backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err); } #[test] fn named_implicit_backtrace_by_field_type() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { implicit_backtrace: Backtrace, field: i32, } let err = TestErr { implicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, implicit_backtrace); } #[test] fn named_explicit_no_backtrace_by_field_name() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(not(backtrace))] backtrace: MyBacktrace, field: i32, } type MyBacktrace = Backtrace; assert!(request_ref::(&TestErr { backtrace: Backtrace::force_capture(), field: 0 }) .is_none()); } #[test] fn named_explicit_no_backtrace_by_field_type() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(not(backtrace))] implicit_backtrace: Backtrace, field: i32, } assert!(request_ref::(&TestErr { implicit_backtrace: Backtrace::force_capture(), field: 0 }) .is_none()); } #[test] fn named_explicit_backtrace() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(backtrace)] explicit_backtrace: MyBacktrace, field: i32, } type MyBacktrace = Backtrace; let err = TestErr { explicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, explicit_backtrace); } #[test] fn named_explicit_no_backtrace_redundant() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(not(backtrace))] not_backtrace: MyBacktrace, #[error(not(backtrace))] field: i32, } type MyBacktrace = Backtrace; assert!(request_ref::(&TestErr { not_backtrace: Backtrace::force_capture(), field: 0 }) .is_none()); } #[test] fn named_explicit_backtrace_by_field_name_redundant() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(backtrace)] backtrace: MyBacktrace, field: i32, } type MyBacktrace = Backtrace; let err = TestErr { backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err); } #[test] fn named_explicit_backtrace_by_field_type_redundant() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(backtrace)] implicit_backtrace: Backtrace, field: i32, } let err = TestErr { implicit_backtrace: Backtrace::force_capture(), field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, implicit_backtrace); } #[test] fn named_explicit_suppresses_implicit() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(backtrace)] not_backtrace: MyBacktrace, backtrace: Backtrace, field: i32, } type MyBacktrace = Backtrace; let err = TestErr { not_backtrace: Backtrace::force_capture(), backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different field: 0, }; assert!(request_ref::(&err).is_some()); assert_bt!(==, err, not_backtrace); assert_bt!(!=, err); } #[test] fn named_implicit_no_backtrace_from_source() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(source)] err: BacktraceErr, } let err = TestErr { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn named_explicit_no_backtrace_from_source() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(source, not(backtrace))] err: BacktraceErr, } let err = TestErr { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn named_explicit_backtrace_from_source() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(backtrace, source)] err: BacktraceErr, } let err = TestErr { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, request_ref::(&err.err).unwrap()); } #[test] fn named_implicit_different_source_and_backtrace() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(source)] err: BacktraceErr, backtrace: Backtrace, } let err = TestErr { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, backtrace); assert_bt!(!=, err, request_ref::(&err.err).unwrap()); } #[test] fn named_explicit_different_source_and_backtrace() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr { #[error(source)] err: BacktraceErr, #[error(backtrace)] backtrace: Backtrace, } let err = TestErr { err: BacktraceErr { backtrace: Backtrace::force_capture(), }, backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different }; assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, backtrace); assert_bt!(!=, err, request_ref::(&err.err).unwrap()); } #[test] fn unnamed_implicit_no_backtrace() { derive_display!(TestErr); #[derive(Default, Debug, Error)] struct TestErr(i32, i32); assert!(request_ref::(&TestErr::default()).is_none()); } #[test] fn unnamed_implicit_backtrace() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr(Backtrace, i32, i32); let err = TestErr(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .0); } #[test] fn unnamed_explicit_no_backtrace() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr(#[error(not(backtrace))] Backtrace, i32); assert!( request_ref::(&TestErr(Backtrace::force_capture(), 0)).is_none() ); } #[test] fn unnamed_explicit_backtrace() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr(#[error(backtrace)] MyBacktrace, i32, i32); type MyBacktrace = Backtrace; let err = TestErr(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .0); } #[test] fn unnamed_explicit_no_backtrace_redundant() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr( #[error(not(backtrace))] MyBacktrace, #[error(not(backtrace))] i32, ); type MyBacktrace = Backtrace; assert!( request_ref::(&TestErr(Backtrace::force_capture(), 0)).is_none() ); } #[test] fn unnamed_explicit_backtrace_redundant() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr(#[error(backtrace)] Backtrace, i32, i32); let err = TestErr(Backtrace::force_capture(), 0, 0); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .0); } #[test] fn unnamed_explicit_suppresses_implicit() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr(#[error(backtrace)] MyBacktrace, Backtrace, i32); type MyBacktrace = Backtrace; let err = TestErr( Backtrace::force_capture(), (|| Backtrace::force_capture())(), // ensure backtraces are different 0, ); assert!(request_ref::(&err).is_some()); assert_bt!(==, err, .0); assert_bt!(!=, err, .1); } #[test] fn unnamed_implicit_no_backtrace_from_source() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr(BacktraceErr); let err = TestErr(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn unnamed_explicit_no_backtrace_from_source() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr(#[error(not(backtrace))] BacktraceErr); let err = TestErr(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_none()); assert!(request_value::(&err).is_none()); } #[test] fn unnamed_explicit_backtrace_from_source() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr(#[error(backtrace)] BacktraceErr); let err = TestErr(BacktraceErr { backtrace: Backtrace::force_capture(), }); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, request_ref::(&err.0).unwrap()); } #[test] fn unnamed_implicit_different_source_and_backtrace() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr(#[error(source)] BacktraceErr, Backtrace); let err = TestErr( BacktraceErr { backtrace: Backtrace::force_capture(), }, (|| Backtrace::force_capture())(), // ensure backtraces are different ); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .1); assert_bt!(!=, err, request_ref::(&err.0).unwrap()); } #[test] fn unnamed_explicit_different_source_and_backtrace() { derive_display!(TestErr); #[derive(Debug, Error)] struct TestErr(#[error(source)] BacktraceErr, #[error(backtrace)] Backtrace); let err = TestErr( BacktraceErr { backtrace: Backtrace::force_capture(), }, (|| Backtrace::force_capture())(), // ensure backtraces are different ); assert!(err.source().is_some()); assert!(request_ref::(&err).is_some()); assert_eq!(request_value::(&err), Some(42)); assert_bt!(==, err, .1); assert_bt!(!=, err, request_ref::(&err.0).unwrap()); } derive_more-1.0.0/tests/error/nightly/mod.rs000064400000000000000000000052101046102023000172160ustar 00000000000000use std::backtrace::Backtrace; use super::*; /// Asserts that backtrace returned by `Error::backtrace` method equals/not-equals /// backtrace stored in object itself. /// /// Comparison is done by converting backtraces to strings /// and then comparing these strings. /// /// ## Syntax /// /// * Equals: `assert_bt!(==, ...)` /// * Not-equals: `assert_bt!(!=, ...)` /// /// ### Backtrace Access /// /// Shortcut for named-structs with `backtrace` field. /// Access backtrace as `error.backtrace`. /// /// ``` /// assert_bt!(==, error); /// ``` /// /// Full form for named- and tuple-structs. /// Access backtrace as `error.some_other_field` and `error.1` respectively. /// /// ``` /// assert_bt!(!=, error, some_other_field); /// assert_bt!(==, error, 1); /// ``` /// /// Access as a method call. /// Useful for enums (i.e., you can define a method that will match on enum variants /// and return backtrace for each variant). /// Access backtrace as `error.get_stored_backtrace_method()`. /// /// ``` /// assert_bt!(!=, error, .get_stored_backtrace_method); /// ``` macro_rules! assert_bt { (@impl $macro:ident, $error:expr, $backtrace:expr) => { $macro!(::core::error::request_ref::(&$error).unwrap().to_string(), $backtrace.to_string()); }; (@expand $macro:ident, $error:expr, .$backtrace:ident) => { assert_bt!(@impl $macro, $error, $error.$backtrace()) }; (@expand $macro:ident, $error:expr, .$backtrace:tt) => { assert_bt!(@impl $macro, $error, $error.$backtrace) }; (@expand $macro:ident, $error:expr, $backtrace:ident) => { assert_bt!(@impl $macro, $error, $error.$backtrace) }; (@expand $macro:ident, $error:expr, $backtrace:expr) => { assert_bt!(@impl $macro, $error, $backtrace) }; (@expand $macro:ident, $error:expr) => { assert_bt!(@expand $macro, $error, backtrace) }; (==, $($args:tt)*) => { assert_bt!(@expand assert_eq, $($args)*) }; (!=, $($args:tt)*) => { assert_bt!(@expand assert_ne, $($args)*) }; } mod derives_for_enums_with_backtrace; mod derives_for_generic_enums_with_backtrace; mod derives_for_generic_structs_with_backtrace; mod derives_for_structs_with_backtrace; derive_display!(BacktraceErr); #[derive(Debug)] struct BacktraceErr { backtrace: Backtrace, } impl Default for BacktraceErr { fn default() -> Self { Self { backtrace: Backtrace::force_capture(), } } } impl Error for BacktraceErr { fn provide<'a>(&'a self, request: &mut std::error::Request<'a>) { request .provide_ref::(&self.backtrace) .provide_value::(42); } } derive_more-1.0.0/tests/error_tests.rs000064400000000000000000000001631046102023000162050ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(nightly, feature(error_generic_member_access))] mod error; derive_more-1.0.0/tests/from.rs000064400000000000000000001514631046102023000146070ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::{ borrow::Cow, string::{String, ToString}, }; #[cfg(feature = "std")] use std::borrow::Cow; use derive_more::From; use static_assertions::assert_not_impl_any; mod structs { use super::*; mod unit { use super::*; #[derive(Debug, From, PartialEq)] struct Unit; #[derive(Debug, From, PartialEq)] struct Tuple(); #[derive(Debug, From, PartialEq)] struct Struct {} #[test] fn assert() { assert_eq!(Unit, ().into()); assert_eq!(Tuple(), ().into()); assert_eq!(Struct {}, ().into()); } mod generic { use super::*; #[derive(Debug, From, PartialEq)] struct Unit; #[derive(Debug, From, PartialEq)] struct Tuple(); #[derive(Debug, From, PartialEq)] struct Struct {} #[test] fn assert() { assert_eq!(Unit::<1>, ().into()); assert_eq!(Tuple::<1>(), ().into()); assert_eq!(Struct::<1> {}, ().into()); } } } mod single_field { use super::*; #[derive(Debug, From, PartialEq)] struct Tuple(i32); #[derive(Debug, From, PartialEq)] struct Struct { field: i32, } #[test] fn assert() { assert_eq!(Tuple(42), 42.into()); assert_eq!(Struct { field: 42 }, 42.into()); } mod types { use super::*; #[derive(Debug, From, PartialEq)] #[from(i8)] #[from(i16)] struct Tuple(i32); #[derive(Debug, From, PartialEq)] #[from(&str, Cow<'_, str>)] struct Struct { field: String, } #[test] fn assert() { assert_not_impl_any!(Tuple: From); assert_not_impl_any!(Struct: From); assert_eq!(Tuple(42), 42_i8.into()); assert_eq!(Tuple(42), 42_i16.into()); assert_eq!( Struct { field: "42".to_string(), }, "42".into(), ); assert_eq!( Struct { field: "42".to_string(), }, Cow::Borrowed("42").into(), ); } } mod forward { use super::*; #[derive(Debug, From, PartialEq)] #[from(forward)] struct Tuple(i32); #[derive(Debug, From, PartialEq)] #[from(forward)] struct Struct { field: String, } #[test] fn assert() { assert_eq!(Tuple(42), 42_i8.into()); assert_eq!(Tuple(42), 42_i16.into()); assert_eq!(Tuple(42), 42_i32.into()); assert_eq!( Struct { field: "42".to_string(), }, "42".into(), ); assert_eq!( Struct { field: "42".to_string(), }, Cow::Borrowed("42").into(), ); } } mod generic { use super::*; #[derive(Debug, From, PartialEq)] struct Tuple(T); #[derive(Debug, From, PartialEq)] struct Struct { field: T, } #[test] fn assert() { assert_eq!(Tuple(42), 42.into()); assert_eq!(Struct { field: 42 }, 42.into()); } mod reference { use super::*; #[derive(Debug, From, PartialEq)] struct Tuple<'a, T>(&'a T); #[derive(Debug, From, PartialEq)] struct Struct<'a, T> { field: &'a T, } #[test] fn assert() { assert_eq!(Tuple(&42), (&42).into()); assert_eq!(Struct { field: &42 }, (&42).into()); } } mod indirect { use super::*; #[derive(Debug, From, PartialEq)] struct Tuple(&'static T); #[derive(Debug, From, PartialEq)] struct Struct { field: &'static T, } #[test] fn assert() { assert_eq!(Tuple(&42), (&42).into()); assert_eq!(Struct { field: &42 }, (&42).into()); } } mod bounded { use super::*; #[derive(Debug, From, PartialEq)] struct Tuple(T); #[derive(Debug, From, PartialEq)] struct Struct { field: T, } #[test] fn assert() { assert_eq!(Tuple(42), 42.into()); assert_eq!(Struct { field: 42 }, 42.into()); } } mod r#const { use super::*; #[derive(Debug, From, PartialEq)] struct Tuple(T); #[derive(Debug, From, PartialEq)] struct Struct { field: T, } #[test] fn assert() { assert_eq!(Tuple::<1, _>(1), 1.into()); assert_eq!(Struct::<_, 1> { field: 1 }, 1.into()); } } } } mod multi_field { use super::*; #[derive(Debug, From, PartialEq)] struct Tuple(i32, i16); #[derive(Debug, From, PartialEq)] struct Struct { field1: i32, field2: i16, } #[test] fn assert() { assert_eq!(Tuple(0, 1), (0, 1_i16).into()); assert_eq!( Struct { field1: 0, field2: 1, }, (0, 1_i16).into(), ); } mod types { use super::*; #[derive(Debug, From, PartialEq)] #[from((i16, i16))] struct Tuple(i32, i16); #[derive(Debug, From, PartialEq)] #[from((i16, i16))] struct Struct { field1: i32, field2: i16, } #[test] fn assert() { assert_not_impl_any!(Tuple: From<(i32, i16)>); assert_not_impl_any!(Struct: From<(i32, i16)>); assert_eq!(Tuple(0, 1), (0_i16, 1_i16).into()); assert_eq!( Struct { field1: 0, field2: 1 }, (0_i16, 1_i16).into(), ); } } mod forward { use super::*; #[derive(Debug, From, PartialEq)] #[from(forward)] struct Tuple(i32, i16); #[derive(Debug, From, PartialEq)] #[from(forward)] struct Struct { field1: i32, field2: i16, } #[test] fn assert() { assert_eq!(Tuple(0, 1), (0_i8, 1_i8).into()); assert_eq!(Tuple(0, 1), (0_i8, 1_i16).into()); assert_eq!(Tuple(0, 1), (0_i16, 1_i8).into()); assert_eq!(Tuple(0, 1), (0_i16, 1_i16).into()); assert_eq!(Tuple(0, 1), (0_i32, 1_i8).into()); assert_eq!(Tuple(0, 1), (0_i32, 1_i16).into()); assert_eq!( Struct { field1: 0, field2: 1 }, (0_i8, 1_i8).into(), ); assert_eq!( Struct { field1: 0, field2: 1 }, (0_i8, 1_i16).into(), ); assert_eq!( Struct { field1: 0, field2: 1 }, (0_i16, 1_i8).into(), ); assert_eq!( Struct { field1: 0, field2: 1 }, (0_i16, 1_i16).into(), ); assert_eq!( Struct { field1: 0, field2: 1 }, (0_i32, 1_i8).into(), ); assert_eq!( Struct { field1: 0, field2: 1 }, (0_i32, 1_i16).into(), ); } } mod generic { use super::*; #[derive(Debug, From, PartialEq)] struct Tuple(A, B); #[derive(Debug, From, PartialEq)] struct Struct { field1: A, field2: B, } #[test] fn assert() { assert_eq!(Tuple(1, 2_i8), (1, 2_i8).into()); assert_eq!( Struct { field1: 1, field2: 2_i8, }, (1, 2_i8).into(), ); } mod reference { use super::*; #[derive(Debug, From, PartialEq)] struct Tuple<'a, A, B>(&'a A, &'a B); #[derive(Debug, From, PartialEq)] struct Struct<'a, A, B> { field1: &'a A, field2: &'a B, } #[test] fn assert() { assert_eq!(Tuple(&1, &2_i8), (&1, &2_i8).into()); assert_eq!( Struct { field1: &1, field2: &2_i8, }, (&1, &2_i8).into(), ); } } mod bounded { use super::*; #[derive(Debug, From, PartialEq)] struct Tuple(A, B); #[derive(Debug, From, PartialEq)] struct Struct { field1: A, field2: B, } #[test] fn assert() { assert_eq!(Tuple(1, 2_i8), (1, 2_i8).into()); assert_eq!( Struct { field1: 1, field2: 2_i8, }, (1, 2_i8).into(), ); } } mod r#const { use super::*; #[derive(Debug, From, PartialEq)] struct ConstTuple(A, B); #[derive(Debug, From, PartialEq)] struct ConstStruct { field1: A, field2: B, } #[test] fn assert() { assert_eq!(ConstTuple::<1, _, _>(1, 2_i8), (1, 2_i8).into()); assert_eq!( ConstStruct::<1, _, _> { field1: 1, field2: 2_i8, }, (1, 2_i8).into(), ); } } } } } mod enums { use super::*; mod unit_variant { use super::*; #[derive(Debug, From, PartialEq)] enum Enum { #[from] Unit, Unnamed(), Named {}, } #[test] fn assert() { assert_eq!(Enum::Unit, ().into()); } mod generic { use super::*; #[derive(Debug, From, PartialEq)] enum Unit { Variant, } #[derive(Debug, From, PartialEq)] enum Tuple { Variant(), } #[derive(Debug, From, PartialEq)] enum Struct { Variant {}, } assert_not_impl_any!(Unit: From<()>); assert_not_impl_any!(Tuple: From<()>); assert_not_impl_any!(Struct: From<()>); mod r#const { use super::*; #[derive(Debug, From, PartialEq)] enum Unit { Variant, } #[derive(Debug, From, PartialEq)] enum Tuple { Variant(), } #[derive(Debug, From, PartialEq)] enum Struct { Variant {}, } assert_not_impl_any!(Unit<0>: From<()>); assert_not_impl_any!(Tuple<0>: From<()>); assert_not_impl_any!(Struct<0>: From<()>); } } mod from { use super::*; #[derive(Debug, From, PartialEq)] enum Unit { #[from] Variant, AutomaticallySkipped, } #[derive(Debug, From, PartialEq)] enum Tuple { #[from] Variant(), AutomaticallySkipped(), } #[derive(Debug, From, PartialEq)] enum Struct { #[from] Variant {}, AutomaticallySkipped {}, } #[test] fn assert() { assert_eq!(Unit::Variant, ().into()); assert_eq!(Tuple::Variant(), ().into()); assert_eq!(Struct::Variant {}, ().into()); } mod r#const { use super::*; #[derive(Debug, From, PartialEq)] enum Unit { #[from] Variant, } #[derive(Debug, From, PartialEq)] enum Tuple { #[from] Variant(), } #[derive(Debug, From, PartialEq)] enum Struct { #[from] Variant {}, } #[test] fn assert() { assert_eq!(Unit::<0>::Variant, ().into()); assert_eq!(Tuple::<0>::Variant(), ().into()); assert_eq!(Struct::<0>::Variant {}, ().into()); } } } } mod single_field_variant { use super::*; #[derive(Debug, From, PartialEq)] enum Enum { Unnamed(i8), Named { field: i16 }, } #[test] fn assert() { assert_eq!(Enum::Unnamed(1), 1_i8.into()); assert_eq!(Enum::Named { field: 1 }, 1_i16.into()); } mod generic { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: T }, } #[test] fn assert() { assert_eq!(Tuple::Variant(1), 1.into()); assert_eq!(Struct::Variant { field: 1 }, 1.into()); } mod reference { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple<'a, T> { Variant(&'a T), } #[derive(Debug, From, PartialEq)] enum Struct<'a, T> { Variant { field: &'a T }, } #[test] fn assert() { assert_eq!(Tuple::Variant(&1), (&1).into()); assert_eq!(Struct::Variant { field: &1 }, (&1).into()); } } mod indirect { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(&'static T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: &'static T }, } #[test] fn assert() { assert_eq!(Tuple::Variant(&1), (&1).into()); assert_eq!(Struct::Variant { field: &1 }, (&1).into()); } } mod bounded { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: T }, } #[test] fn assert() { assert_eq!(Tuple::Variant(1), 1.into()); assert_eq!(Struct::Variant { field: 1 }, 1.into()); } } mod r#const { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: T }, } #[test] fn assert() { assert_eq!(Tuple::Variant::<_, 1>(1), 1.into()); assert_eq!(Struct::Variant::<1, _> { field: 1 }, 1.into()); } } } mod from { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { #[from] Variant(i8), AutomaticallySkipped(i8), } #[derive(Debug, From, PartialEq)] enum Struct { #[from] Variant { field: i8, }, AutomaticallySkipped { field: i8, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(1), 1_i8.into()); assert_eq!(Struct::Variant { field: 1 }, 1_i8.into()); } } mod skip { use super::*; #[derive(Debug, From, PartialEq)] enum Enum { Unnamed(i8), #[from(skip)] UnnamedSkipped(i8), Named { field: i16, }, #[from(skip)] NamedSkipped { field: i16, }, } #[test] fn assert() { assert_eq!(Enum::Unnamed(1), 1_i8.into()); assert_eq!(Enum::Named { field: 1 }, 1_i16.into()); } mod generic { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(T), #[from(skip)] Skipped(T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: T, }, #[from(skip)] Skipped { field: T, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(1), 1.into()); assert_eq!(Struct::Variant { field: 1 }, 1.into()); } mod reference { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple<'a, T> { Variant(&'a T), #[from(skip)] Skipped(&'a T), } #[derive(Debug, From, PartialEq)] enum Struct<'a, T> { Variant { field: &'a T, }, #[from(skip)] Skipped { field: &'a T, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(&1), (&1).into()); assert_eq!(Struct::Variant { field: &1 }, (&1).into()); } } mod indirect { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(&'static T), #[from(skip)] Skipped(&'static T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: &'static T, }, #[from(skip)] Skipped { field: &'static T, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(&1), (&1).into()); assert_eq!(Struct::Variant { field: &1 }, (&1).into()); } } mod bounded { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(T), #[from(skip)] Skipped(T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: T, }, #[from(skip)] Skipped { field: T, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(1), 1.into()); assert_eq!(Struct::Variant { field: 1 }, 1.into()); } } mod r#const { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(T), #[from(skip)] Skipped(T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: T, }, #[from(skip)] Skipped { field: T, }, } #[test] fn assert() { assert_eq!(Tuple::Variant::<_, 1>(1), 1.into()); assert_eq!(Struct::Variant::<1, _> { field: 1 }, 1.into()); } } mod concrete { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(i32), #[from(skip)] Skipped(T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: i32, }, #[from(skip)] Skipped { field: T, }, } #[test] fn assert() { assert_eq!(Tuple::Variant::(1), 1.into()); assert_eq!(Struct::Variant:: { field: 1 }, 1.into()); } mod reference { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple<'a, T> { Variant(&'a i32), #[from(skip)] Skipped(&'a T), } #[derive(Debug, From, PartialEq)] enum Struct<'a, T> { Variant { field: &'a i32, }, #[from(skip)] Skipped { field: &'a T, }, } #[test] fn assert() { assert_eq!(Tuple::Variant::(&1), (&1).into()); assert_eq!( Struct::Variant:: { field: &1 }, (&1).into() ); } } mod indirect { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(&'static i32), #[from(skip)] Skipped(&'static T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: &'static i32, }, #[from(skip)] Skipped { field: &'static T, }, } #[test] fn assert() { assert_eq!(Tuple::Variant::(&1), (&1).into()); assert_eq!( Struct::Variant:: { field: &1 }, (&1).into() ); } } mod bounded { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(i32), #[from(skip)] Skipped(T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: i32, }, #[from(skip)] Skipped { field: T, }, } #[test] fn assert() { assert_eq!(Tuple::Variant::(1), 1.into()); assert_eq!(Struct::Variant:: { field: 1 }, 1.into()); } } mod r#const { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(i32), #[from(skip)] Skipped(T), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field: i32, }, #[from(skip)] Skipped { field: T, }, } #[test] fn assert() { assert_eq!(Tuple::Variant::(1), 1.into()); assert_eq!( Struct::Variant::<1, i32> { field: 1 }, 1.into() ); } } } } } mod types { use super::*; #[derive(Debug, From, PartialEq)] enum Enum { #[from(i8)] Unnamed(i16), #[from(i16)] Named { field: i32, }, AutomaticallySkipped(i32), } #[test] fn assert() { assert_not_impl_any!(Enum: From); assert_eq!(Enum::Unnamed(1), 1_i8.into()); assert_eq!(Enum::Named { field: 1 }, 1_i16.into()); } } mod forward { use super::*; #[derive(Debug, From, PartialEq)] enum Unnamed { #[from(forward)] Variant(i32), AutomaticallyIgnored(i32), } #[derive(Debug, From, PartialEq)] enum Named { #[from(forward)] Variant { field: i32, }, AutomaticallyIgnored { field: i32, }, } #[test] fn assert() { assert_eq!(Unnamed::Variant(1), 1_i8.into()); assert_eq!(Unnamed::Variant(1), 1_i16.into()); assert_eq!(Unnamed::Variant(1), 1_i32.into()); assert_eq!(Named::Variant { field: 1 }, 1_i8.into()); assert_eq!(Named::Variant { field: 1 }, 1_i16.into()); assert_eq!(Named::Variant { field: 1 }, 1_i32.into()); } } } mod multi_field_variant { use super::*; #[derive(Debug, From, PartialEq)] enum Enum { Tuple(i8, i8), Struct { field1: i16, field2: i16 }, } #[test] fn assert() { assert_eq!(Enum::Tuple(0, 1), (0_i8, 1_i8).into()); assert_eq!( Enum::Struct { field1: 0, field2: 1 }, (0_i16, 1_i16).into(), ); } mod generic { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(A, B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: A, field2: B }, } #[test] fn assert() { assert_eq!(Tuple::Variant(1, 2_i16), (1, 2_i16).into()); assert_eq!( Struct::Variant { field1: 1, field2: 2_i16, }, (1, 2_i16).into(), ); } mod reference { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple<'a, A, B> { Variant(&'a A, &'a B), } #[derive(Debug, From, PartialEq)] enum Struct<'a, A, B> { Variant { field1: &'a A, field2: &'a B }, } #[test] fn assert() { assert_eq!(Tuple::Variant(&1, &2_i16), (&1, &2_i16).into()); assert_eq!( Struct::Variant { field1: &1, field2: &2_i16, }, (&1, &2_i16).into(), ); } } mod indirect { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(&'static A, &'static B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: &'static A, field2: &'static B, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(&1, &2_i16), (&1, &2_i16).into()); assert_eq!( Struct::Variant { field1: &1, field2: &2_i16, }, (&1, &2_i16).into(), ); } } mod bounded { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(A, B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: A, field2: B }, } #[test] fn assert() { assert_eq!(Tuple::Variant(1, 2_i16), (1, 2_i16).into()); assert_eq!( Struct::Variant { field1: 1, field2: 2_i16, }, (1, 2_i16).into(), ); } } mod r#const { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(A, B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: A, field2: B }, } #[test] fn assert() { assert_eq!(Tuple::Variant::<0, _, _>(1, 2_i16), (1, 2_i16).into()); assert_eq!( Struct::<_, 1, _>::Variant { field1: 1, field2: 2_i16, }, (1, 2_i16).into(), ); } } } mod from { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { #[from] Variant(i8, i16), AutomaticallySkipped(i8, i16), } #[derive(Debug, From, PartialEq)] enum Struct { #[from] Variant { field1: i8, field2: i16, }, AutomaticallySkipped { field1: i8, field2: i16, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(1, 2), (1_i8, 2_i16).into()); assert_eq!( Struct::Variant { field1: 1, field2: 2, }, (1_i8, 2_i16).into(), ); } } mod skip { use super::*; #[derive(Debug, From, PartialEq)] enum Enum { Tuple(i8, i8), #[from(skip)] TupleSkipped(i8, i8), Struct { field1: i16, field2: i16, }, #[from(skip)] StructSkipped { field1: i16, field2: i16, }, } #[test] fn assert() { assert_eq!(Enum::Tuple(0, 1), (0_i8, 1_i8).into()); assert_eq!( Enum::Struct { field1: 0, field2: 1 }, (0_i16, 1_i16).into(), ); } mod generic { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(A, B), #[from(skip)] Skipped(A, B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: A, field2: B, }, #[from(skip)] Skipped { field1: A, field2: B, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(1, 2_i16), (1, 2_i16).into()); assert_eq!( Struct::Variant { field1: 1, field2: 2_i16, }, (1, 2_i16).into(), ); } mod reference { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple<'a, A, B> { Variant(&'a A, &'a B), #[from(skip)] Skipped(&'a A, &'a B), } #[derive(Debug, From, PartialEq)] enum Struct<'a, A, B> { Variant { field1: &'a A, field2: &'a B, }, #[from(skip)] Skipped { field1: &'a A, field2: &'a B, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(&1, &2_i16), (&1, &2_i16).into()); assert_eq!( Struct::Variant { field1: &1, field2: &2_i16, }, (&1, &2_i16).into(), ); } } mod indirect { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(&'static A, &'static B), #[from(skip)] Skipped(&'static A, &'static B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: &'static A, field2: &'static B, }, #[from(skip)] Skipped { field1: &'static A, field2: &'static B, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(&1, &2_i16), (&1, &2_i16).into()); assert_eq!( Struct::Variant { field1: &1, field2: &2_i16, }, (&1, &2_i16).into(), ); } } mod bounded { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(A, B), #[from(skip)] Skipped(A, B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: A, field2: B, }, #[from(skip)] Skipped { field1: A, field2: B, }, } #[test] fn assert() { assert_eq!(Tuple::Variant(1, 2_i16), (1, 2_i16).into()); assert_eq!( Struct::Variant { field1: 1, field2: 2_i16, }, (1, 2_i16).into(), ); } } mod r#const { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(A, B), #[from(skip)] Skipped(A, B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: A, field2: B, }, #[from(skip)] Skipped { field1: A, field2: B, }, } #[test] fn assert() { assert_eq!( Tuple::Variant::<0, _, _>(1, 2_i16), (1, 2_i16).into() ); assert_eq!( Struct::<_, 1, _>::Variant { field1: 1, field2: 2_i16, }, (1, 2_i16).into(), ); } } mod concrete { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(i32, i16), #[from(skip)] Skipped(A, B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: i32, field2: i16, }, #[from(skip)] Skipped { field1: A, field2: B, }, } #[test] fn assert() { assert_eq!( Tuple::Variant::(1, 2_i16), (1, 2_i16).into(), ); assert_eq!( Struct::Variant:: { field1: 1, field2: 2_i16, }, (1, 2_i16).into(), ); } mod reference { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple<'a, A, B> { Variant(&'a i32, &'a i16), #[from(skip)] Skipped(&'a A, &'a B), } #[derive(Debug, From, PartialEq)] enum Struct<'a, A, B> { Variant { field1: &'a i32, field2: &'a i16, }, #[from(skip)] Skipped { field1: &'a A, field2: &'a B, }, } #[test] fn assert() { assert_eq!( Tuple::Variant::(&1, &2_i16), (&1, &2_i16).into(), ); assert_eq!( Struct::Variant:: { field1: &1, field2: &2_i16, }, (&1, &2_i16).into(), ); } } mod indirect { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(&'static i32, &'static i16), #[from(skip)] Skipped(&'static A, &'static B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: &'static i32, field2: &'static i16, }, #[from(skip)] Skipped { field1: &'static A, field2: &'static B, }, } #[test] fn assert() { assert_eq!( Tuple::Variant::(&1, &2_i16), (&1, &2_i16).into(), ); assert_eq!( Struct::Variant:: { field1: &1, field2: &2_i16, }, (&1, &2_i16).into(), ); } } mod bounded { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(i32, i16), #[from(skip)] Skipped(A, B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: i32, field2: i16, }, #[from(skip)] Skipped { field1: A, field2: B, }, } #[test] fn assert() { assert_eq!( Tuple::Variant::(1, 2_i16), (1, 2_i16).into(), ); assert_eq!( Struct::Variant:: { field1: 1, field2: 2_i16, }, (1, 2_i16).into(), ); } } mod r#const { use super::*; #[derive(Debug, From, PartialEq)] enum Tuple { Variant(i32, i16), #[from(skip)] Skipped(A, B), } #[derive(Debug, From, PartialEq)] enum Struct { Variant { field1: i32, field2: i16, }, #[from(skip)] Skipped { field1: A, field2: B, }, } #[test] fn assert() { assert_eq!( Tuple::Variant::<0, i32, i16>(1, 2_i16), (1, 2_i16).into() ); assert_eq!( Struct::::Variant { field1: 1, field2: 2_i16, }, (1, 2_i16).into(), ); } } } } } mod types { use super::*; #[derive(Debug, From, PartialEq)] enum Enum { #[from((i8, i8))] Tuple(i16, i16), #[from((i16, i16))] Struct { field1: i32, field2: i32, }, AutomaticallySkipped { field1: i32, field2: i32, }, } #[test] fn assert() { assert_not_impl_any!(Enum: From<(i32, i32)>); assert_eq!(Enum::Tuple(0, 1), (0_i8, 1_i8).into()); assert_eq!( Enum::Struct { field1: 0, field2: 1 }, (0_i16, 1_i16).into(), ); } } mod forward { use super::*; #[derive(Debug, From, PartialEq)] enum Unnamed { #[from(forward)] Variant(i16, i16), AutomaticallyIgnored(i16, i16), } #[derive(Debug, From, PartialEq)] enum Named { #[from(forward)] Variant { field1: i16, field2: i16, }, AutomaticallyIgnored { field1: i16, field2: i16, }, } #[test] fn assert() { assert_eq!(Unnamed::Variant(0, 1), (0_i8, 1_i8).into()); assert_eq!(Unnamed::Variant(0, 1), (0_i8, 1_i16).into()); assert_eq!(Unnamed::Variant(0, 1), (0_i16, 1_i8).into()); assert_eq!(Unnamed::Variant(0, 1), (0_i16, 1_i16).into()); assert_eq!( Named::Variant { field1: 0, field2: 1 }, (0_i8, 1_i8).into(), ); assert_eq!( Named::Variant { field1: 0, field2: 1 }, (0_i8, 1_i16).into(), ); assert_eq!( Named::Variant { field1: 0, field2: 1 }, (0_i16, 1_i8).into(), ); assert_eq!( Named::Variant { field1: 0, field2: 1 }, (0_i16, 1_i16).into(), ); } } } } derive_more-1.0.0/tests/from_str.rs000064400000000000000000000022221046102023000154630ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::string::ToString; use derive_more::FromStr; #[derive(FromStr)] struct MyInt(i32); #[derive(FromStr)] struct Point1D { x: i32, } #[derive(Debug, FromStr, PartialEq, Eq)] enum EnumNoFields { Foo, Bar, Baz, BaZ, } #[test] fn enum_test() { assert_eq!("Foo".parse::().unwrap(), EnumNoFields::Foo); assert_eq!("FOO".parse::().unwrap(), EnumNoFields::Foo); assert_eq!("foo".parse::().unwrap(), EnumNoFields::Foo); assert_eq!( "other".parse::().unwrap_err().to_string(), "Invalid `EnumNoFields` string representation", ); } #[test] fn enum_test_case_sensitive() { assert_eq!("Baz".parse::().unwrap(), EnumNoFields::Baz); assert_eq!("BaZ".parse::().unwrap(), EnumNoFields::BaZ); assert_eq!( "baz".parse::().unwrap_err().to_string(), "Invalid `EnumNoFields` string representation", ); } derive_more-1.0.0/tests/generics.rs000064400000000000000000000124401046102023000154320ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use derive_more::{ Add, AddAssign, Constructor, Deref, DerefMut, Display, Error, From, FromStr, Index, IndexMut, IntoIterator, Mul, MulAssign, Not, Sum, TryInto, }; #[derive( From, FromStr, Display, Index, Not, Add, Mul, Sum, IndexMut, AddAssign, MulAssign, Deref, DerefMut, IntoIterator, Constructor )] #[deref(forward)] #[deref_mut(forward)] #[into_iterator(owned, ref, ref_mut)] struct Wrapped(T); #[derive(Deref, DerefMut)] struct Wrapped2(T); #[derive(From, Not, Add, Mul, AddAssign, MulAssign, Constructor, Sum)] struct WrappedDouble(T, U); #[derive(From)] #[from(forward)] struct WrappedDouble2(T, U); #[cfg(nightly)] #[derive( From, FromStr, Display, Index, Not, Add, Mul, Sum, IndexMut, AddAssign, MulAssign, Deref, DerefMut, IntoIterator, Constructor )] struct WrappedWithConst(T); #[derive( From, FromStr, Display, Index, Not, Add, Mul, IndexMut, AddAssign, MulAssign, Deref, DerefMut, IntoIterator, Constructor, Sum )] #[deref(forward)] #[deref_mut(forward)] #[into_iterator(owned, ref, ref_mut)] struct Struct1 { t: T, } #[derive(Deref, DerefMut)] struct Struct2 { t: T, } #[derive(From, Not, Add, Mul, AddAssign, MulAssign, Constructor, Sum)] struct DoubleStruct { t: T, u: U, } #[derive(From)] #[from(forward)] struct DoubleStruct2 { t: T, u: U, } #[derive(From, Not, Add)] enum TupleEnum { Tuple(T), DoubleTuple(T, U), } #[derive(From)] #[from(forward)] enum TupleEnum2 { DoubleTuple(T, U), TripleTuple(T, U, X), } #[derive(From, Not, Add)] enum StructEnum { Struct { t: T }, DoubleStruct { t: T, u: U }, } #[derive(From)] #[from(forward)] enum StructEnum2 { DoubleStruct { t: T, u: U }, TripleStruct { t: T, u: U, x: X }, } #[derive(Debug, Display, Error)] enum Enum {} #[derive(Debug, Display, Error)] enum EnumGeneric { Inner(E), } #[derive(Debug, Display, Error)] enum EnumConst {} #[derive(Debug, Display, Error)] enum EnumConstDefault {} #[derive(Debug, Display, Error)] enum EnumLifetime<'lt: 'static> { Inner(&'lt Enum), } #[derive(Debug, Display, Error)] enum EnumConstGeneric { Inner(E), } #[derive(Debug, Display, Error)] enum EnumGenericConst { Inner(E), } #[derive(Debug, Display, Error)] enum EnumGenericConstDefault { Inner(E), } #[derive(Debug, Display, Error)] enum EnumLifetimeGeneric<'lt: 'static, E> { Inner(&'lt E), } #[derive(Debug, Display, Error)] enum EnumLifetimeConst<'lt: 'static, const X: usize> { Inner(&'lt EnumConst), } #[derive(Debug, Display, Error)] enum EnumLifetimeConstDefault<'lt: 'static, const X: usize = 42> { Inner(&'lt EnumConst), } #[derive(Debug, Display, Error)] enum EnumLifetimeConstGeneric<'lt: 'static, const X: usize, E> { Inner(&'lt E), } #[derive(Debug, Display, Error)] enum EnumLifetimeGenericConst<'lt: 'static, E, const X: usize> { Inner(&'lt E), } #[derive(Debug, Display, Error)] enum EnumLifetimeGenericConstDefault<'lt: 'static, E, const X: usize = 42> { Inner(&'lt E), } #[derive(Debug, Display, Error)] struct Struct; #[derive(Debug, Display, Error)] struct StructGeneric { inner: E, } #[derive(Debug, Display, Error)] struct StructConst {} #[derive(Debug, Display, Error)] struct StructConstDefault {} #[derive(Debug, Display, Error)] struct StructLifetime<'lt: 'static> { inner: &'lt Enum, } #[derive(Debug, Display, Error)] struct StructConstGeneric { inner: E, } #[derive(Debug, Display, Error)] struct StructGenericConst { inner: E, } #[derive(Debug, Display, Error)] struct StructGenericConstDefault { inner: E, } #[derive(Debug, Display, Error)] struct StructLifetimeGeneric<'lt: 'static, E> { inner: &'lt E, } #[derive(Debug, Display, Error)] struct StructLifetimeConst<'lt: 'static, const X: usize> { inner: &'lt EnumConst, } #[derive(Debug, Display, Error)] struct StructLifetimeConstDefault<'lt: 'static, const X: usize = 42> { inner: &'lt EnumConst, } #[derive(Debug, Display, Error)] struct StructLifetimeConstGeneric<'lt: 'static, const X: usize, E> { inner: &'lt E, } #[derive(Debug, Display, Error)] struct StructLifetimeGenericConst<'lt: 'static, E, const X: usize> { inner: &'lt E, } #[derive(Debug, Display, Error)] struct StructLifetimeGenericConstDefault<'lt: 'static, E, const X: usize = 42> { inner: &'lt E, } #[derive(Debug, Display, Error)] struct StructLifetimeGenericBoundsConstDefault< 'lt: 'static, E: Clone, const X: usize = 42, > { inner: &'lt E, } #[derive(Debug, Display)] struct Wrapper<'a, const Y: usize, U>(&'a [U; Y]); #[derive(Debug, Display, TryInto)] enum Foo<'lt: 'static, T: Clone, const X: usize> { X(Wrapper<'lt, X, T>), } derive_more-1.0.0/tests/index.rs000064400000000000000000000005621046102023000147440ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::vec::Vec; use derive_more::Index; #[derive(Index)] struct MyVec(Vec); #[derive(Index)] struct Numbers { #[index] numbers: Vec, useless: bool, } derive_more-1.0.0/tests/index_mut.rs000064400000000000000000000017241046102023000156320ustar 00000000000000#![allow(dead_code)] // some code is tested for type checking only use derive_more::IndexMut; #[derive(IndexMut)] struct MyVec(Vec); // `Index` implementation is required for `IndexMut`. impl<__IdxT> ::core::ops::Index<__IdxT> for MyVec where Vec: ::core::ops::Index<__IdxT>, { type Output = as ::core::ops::Index<__IdxT>>::Output; #[inline] fn index(&self, idx: __IdxT) -> &Self::Output { as ::core::ops::Index<__IdxT>>::index(&self.0, idx) } } #[derive(IndexMut)] struct Numbers { #[index_mut] numbers: Vec, useless: bool, } // `Index` implementation is required for `IndexMut`. impl<__IdxT> ::core::ops::Index<__IdxT> for Numbers where Vec: ::core::ops::Index<__IdxT>, { type Output = as ::core::ops::Index<__IdxT>>::Output; #[inline] fn index(&self, idx: __IdxT) -> &Self::Output { as ::core::ops::Index<__IdxT>>::index(&self.numbers, idx) } } derive_more-1.0.0/tests/into.rs000064400000000000000000001320661046102023000146130ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::{ borrow::Cow, borrow::ToOwned, boxed::Box, string::{String, ToString}, }; use core::mem; #[cfg(feature = "std")] use std::borrow::Cow; use derive_more::Into; use static_assertions::assert_not_impl_any; /// Nasty [`mem::transmute()`] that works in generic contexts /// by [`mem::forget`]ing stuff. /// /// It's OK for tests! unsafe fn transmute(from: From) -> To { let to = unsafe { mem::transmute_copy(&from) }; mem::forget(from); to } #[derive(Clone, Copy, Debug, PartialEq)] #[repr(transparent)] struct Wrapped(T); #[derive(Clone, Copy, Debug, PartialEq)] #[repr(transparent)] struct Transmuted(T); impl From> for Transmuted { fn from(from: Wrapped) -> Self { // SAFETY: repr(transparent) unsafe { transmute(from) } } } impl From<&Wrapped> for &Transmuted { fn from(from: &Wrapped) -> Self { // SAFETY: repr(transparent) unsafe { transmute(from) } } } impl From<&mut Wrapped> for &mut Transmuted { fn from(from: &mut Wrapped) -> Self { // SAFETY: repr(transparent) unsafe { transmute(from) } } } mod unit { #![allow(clippy::unit_cmp)] // because of type inference in assertions use super::*; #[derive(Debug, Into, PartialEq)] struct Unit; #[derive(Debug, Into, PartialEq)] struct Tuple(); #[derive(Debug, Into, PartialEq)] struct Struct {} #[test] fn assert() { assert_eq!((), Unit.into()); assert_eq!((), Tuple().into()); assert_eq!((), Struct {}.into()); } mod generic { use super::*; #[derive(Debug, Into, PartialEq)] struct Unit; #[derive(Debug, Into, PartialEq)] struct Tuple(); #[derive(Debug, Into, PartialEq)] struct Struct {} #[test] fn assert() { assert_eq!((), Unit::<1>.into()); assert_eq!((), Tuple::<1>().into()); assert_eq!((), Struct::<1> {}.into()); } } } mod single_field { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(i32); #[derive(Debug, Into, PartialEq)] struct Struct { field: i32, } #[test] fn assert() { assert_eq!(42, Tuple(42).into()); assert_eq!(42, Struct { field: 42 }.into()); } mod skip { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(#[into(skip)] i32); #[derive(Debug, Into, PartialEq)] struct Struct { #[into(skip)] field: i32, } #[test] fn assert() { #![allow(clippy::unit_cmp)] // because of type inference in assertions assert_eq!((), Tuple(42).into()); assert_eq!((), Struct { field: 42 }.into()); } } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into(i64)] #[into(i128)] struct Tuple(i32); #[derive(Debug, Into, PartialEq)] #[into(Box, Cow<'_, str>)] struct Struct { field: String, } #[test] fn assert() { assert_not_impl_any!(Tuple: Into); assert_not_impl_any!(Struct: Into); assert_eq!(42_i64, Tuple(42).into()); assert_eq!(42_i128, Tuple(42).into()); assert_eq!( Box::::from("42".to_owned()), Struct { field: "42".to_string(), } .into(), ); assert_eq!( Cow::Borrowed("42"), Cow::::from(Struct { field: "42".to_string(), }), ); } mod ref_ { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref)] struct Unnamed(i32); #[derive(Debug, Into, PartialEq)] #[into(ref)] struct Named { field: i32, } #[test] fn assert() { assert_eq!(&42, <&i32>::from(&Unnamed(42))); assert_eq!(&42, <&i32>::from(&Named { field: 42 })); } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref(i32, Unnamed))] struct Tuple(Unnamed); #[derive(Debug, Into, PartialEq)] #[into(ref(i32, Named))] struct Struct { field: Named, } #[test] fn assert() { assert_eq!(&42, <&i32>::from(&Tuple(Unnamed(42)))); assert_eq!(&Unnamed(42), <&Unnamed>::from(&Tuple(Unnamed(42)))); assert_eq!( &42, <&i32>::from(&Struct { field: Named { field: 42 }, }), ); assert_eq!( &Named { field: 42 }, <&Named>::from(&Struct { field: Named { field: 42 }, }), ); } } } mod ref_mut { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref_mut)] struct Unnamed(i32); #[derive(Debug, Into, PartialEq)] #[into(ref_mut)] struct Named { field: i32, } #[test] fn assert() { assert_eq!(&mut 42, <&mut i32>::from(&mut Unnamed(42))); assert_eq!(&mut 42, <&mut i32>::from(&mut Named { field: 42 })); } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref_mut(i32, Unnamed))] struct Tuple(Unnamed); #[derive(Debug, Into, PartialEq)] #[into(ref_mut(i32, Named))] struct Struct { field: Named, } #[test] fn assert() { assert_eq!(&mut 42, <&mut i32>::from(&mut Tuple(Unnamed(42)))); assert_eq!( &mut Unnamed(42), <&mut Unnamed>::from(&mut Tuple(Unnamed(42))), ); assert_eq!( &mut 42, <&mut i32>::from(&mut Struct { field: Named { field: 42 }, }), ); assert_eq!( &mut Named { field: 42 }, <&mut Named>::from(&mut Struct { field: Named { field: 42 }, }), ); } } } } mod generic { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(Wrapped); #[derive(Debug, Into, PartialEq)] struct Struct { field: Wrapped, } #[test] fn assert() { assert_eq!(Wrapped(42), Tuple(Wrapped(42)).into()); assert_eq!(Wrapped(42), Struct { field: Wrapped(42) }.into()); } mod skip { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(#[into(skip)] Wrapped); #[derive(Debug, Into, PartialEq)] struct Struct { #[into(skip)] field: Wrapped, } #[test] fn assert() { #![allow(clippy::unit_cmp)] // because of type inference in assertions assert_eq!((), Tuple(Wrapped(42)).into()); assert_eq!((), Struct { field: Wrapped(42) }.into()); } } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into(Transmuted)] struct Tuple(Wrapped); #[derive(Debug, Into, PartialEq)] #[into(Transmuted)] struct Struct { field: Wrapped, } #[test] fn assert() { assert_eq!(Transmuted(42), Tuple(Wrapped(42)).into()); assert_eq!(Transmuted(42), Struct { field: Wrapped(42) }.into()); } } mod ref_ { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref)] struct Tuple(Wrapped); #[derive(Debug, Into, PartialEq)] #[into(ref)] struct Struct { field: Wrapped, } #[test] fn assert() { assert_eq!(&Wrapped(42), <&Wrapped<_>>::from(&Tuple(Wrapped(42)))); assert_eq!( &Wrapped(42), <&Wrapped<_>>::from(&Struct { field: Wrapped(42) }) ); } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref(Transmuted))] struct Tuple(Wrapped); #[derive(Debug, Into, PartialEq)] #[into(ref(Transmuted))] struct Struct { field: Wrapped, } #[test] fn assert() { assert_eq!( &Transmuted(42), <&Transmuted<_>>::from(&Tuple(Wrapped(42))), ); assert_eq!( &Transmuted(42), <&Transmuted<_>>::from(&Struct { field: Wrapped(42) }), ); } } } mod ref_mut { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref_mut)] struct Tuple(Wrapped); #[derive(Debug, Into, PartialEq)] #[into(ref_mut)] struct Struct { field: Wrapped, } #[test] fn assert() { assert_eq!( &mut Wrapped(42), <&mut Wrapped<_>>::from(&mut Tuple(Wrapped(42))) ); assert_eq!( &mut Wrapped(42), <&mut Wrapped<_>>::from(&mut Struct { field: Wrapped(42) }), ); } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref_mut(Transmuted))] struct Tuple(Wrapped); #[derive(Debug, Into, PartialEq)] #[into(ref_mut(Transmuted))] struct Struct { field: Wrapped, } #[test] fn assert() { assert_eq!( &mut Transmuted(42), <&mut Transmuted<_>>::from(&mut Tuple(Wrapped(42))), ); assert_eq!( &mut Transmuted(42), <&mut Transmuted<_>>::from(&mut Struct { field: Wrapped(42) }), ); } } } mod indirect { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(&'static Wrapped); #[derive(Debug, Into, PartialEq)] struct Struct { field: &'static Wrapped, } #[test] fn assert() { assert_eq!(&Wrapped(42), <&Wrapped<_>>::from(Tuple(&Wrapped(42)))); assert_eq!( &Wrapped(42), <&Wrapped<_>>::from(Struct { field: &Wrapped(42), }), ); } } mod bounded { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(Wrapped); #[derive(Debug, Into, PartialEq)] struct Struct { field: Wrapped, } #[test] fn assert() { assert_eq!(Wrapped(42), Tuple(Wrapped(42)).into()); assert_eq!(Wrapped(42), Struct { field: Wrapped(42) }.into()); } } mod r#const { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(Wrapped); #[derive(Debug, Into, PartialEq)] struct Struct { field: Wrapped, } #[test] fn assert() { assert_eq!(Wrapped(1), Tuple::<1, _>(Wrapped(1)).into()); assert_eq!(Wrapped(1), Struct::<_, 1> { field: Wrapped(1) }.into()); } } } } mod multi_field { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(i32, i64); #[derive(Debug, Into, PartialEq)] struct Struct { field1: i32, field2: i64, } #[test] fn assert() { assert_eq!((1, 2_i64), Tuple(1, 2_i64).into()); assert_eq!( (1, 2_i64), Struct { field1: 1, field2: 2_i64, } .into(), ); } mod skip { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(i32, #[into(skip)] i64); #[derive(Debug, Into, PartialEq)] struct Struct { #[into(skip)] field1: i32, field2: i64, } #[test] fn assert() { assert_eq!(1, Tuple(1, 2_i64).into()); assert_eq!( 2_i64, Struct { field1: 1, field2: 2_i64, } .into(), ); } } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into((i32, i64))] #[into((i64, i128))] struct Tuple(i16, i32); #[derive(Debug, Into, PartialEq)] #[into((Box, i32), (Cow<'_, str>, i64))] struct Struct { field1: String, field2: i32, } #[test] fn assert() { assert_not_impl_any!(Tuple: Into<(i16, i32)>); assert_not_impl_any!(Struct: Into<(String, i32)>); assert_eq!((1, 2_i64), Tuple(1_i16, 2).into()); assert_eq!((1_i64, 2_i128), Tuple(1_i16, 2).into()); assert_eq!( (Box::::from("42".to_owned()), 1), Struct { field1: "42".to_string(), field2: 1, } .into(), ); assert_eq!( (Cow::Borrowed("42"), 1_i64), Struct { field1: "42".to_string(), field2: 1, } .into(), ); } mod ref_ { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref)] struct Unnamed(i32, i64); #[derive(Debug, Into, PartialEq)] #[into(ref)] struct Named { field1: i32, field2: i64, } #[test] fn assert() { assert_eq!((&1, &2_i64), (&Unnamed(1, 2_i64)).into()); assert_eq!( (&1, &2_i64), (&Named { field1: 1, field2: 2_i64, }) .into(), ); } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref( (Transmuted, Transmuted), (Transmuted, Wrapped)), )] struct Tuple(Wrapped, Wrapped); #[derive(Debug, Into, PartialEq)] #[into(ref( (Transmuted, Transmuted), (Transmuted, Wrapped)), )] struct Struct { field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!( (&Transmuted(1), &Transmuted(2_i64)), (&Tuple(Wrapped(1), Wrapped(2_i64))).into(), ); assert_eq!( (&Transmuted(1), &Wrapped(2_i64)), (&Tuple(Wrapped(1), Wrapped(2_i64))).into(), ); assert_eq!( (&Transmuted(1), &Transmuted(2_i64)), (&Struct { field1: Wrapped(1), field2: Wrapped(2_i64), }) .into(), ); assert_eq!( (&Transmuted(1), &Wrapped(2_i64)), (&Struct { field1: Wrapped(1), field2: Wrapped(2_i64), }) .into(), ); } } } mod ref_mut { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref_mut)] struct Unnamed(i32, i64); #[derive(Debug, Into, PartialEq)] #[into(ref_mut)] struct Named { field1: i32, field2: i64, } #[test] fn assert() { assert_eq!((&mut 1, &mut 2_i64), (&mut Unnamed(1, 2_i64)).into()); assert_eq!( (&mut 1, &mut 2_i64), (&mut Named { field1: 1, field2: 2_i64, }) .into(), ); } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref_mut( (Transmuted, Transmuted), (Transmuted, Wrapped)), )] struct Tuple(Wrapped, Wrapped); #[derive(Debug, Into, PartialEq)] #[into(ref_mut( (Transmuted, Transmuted), (Transmuted, Wrapped)), )] struct Struct { field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!( (&mut Transmuted(1), &mut Transmuted(2_i64)), (&mut Tuple(Wrapped(1), Wrapped(2_i64))).into(), ); assert_eq!( (&mut Transmuted(1), &mut Wrapped(2_i64)), (&mut Tuple(Wrapped(1), Wrapped(2_i64))).into(), ); assert_eq!( (&mut Transmuted(1), &mut Transmuted(2_i64)), (&mut Struct { field1: Wrapped(1), field2: Wrapped(2_i64), }) .into(), ); assert_eq!( (&mut Transmuted(1), &mut Wrapped(2_i64)), (&mut Struct { field1: Wrapped(1), field2: Wrapped(2_i64), }) .into(), ); } } } } mod generic { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(Wrapped, Wrapped); #[derive(Debug, Into, PartialEq)] struct Struct { field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!( (Wrapped(1), Wrapped(2)), Tuple(Wrapped(1), Wrapped(2)).into(), ); assert_eq!( (Wrapped(1), Wrapped(2)), Struct { field1: Wrapped(1), field2: Wrapped(2), } .into(), ); } mod skip { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(Wrapped, #[into(skip)] Wrapped); #[derive(Debug, Into, PartialEq)] struct Struct { #[into(skip)] field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!(Wrapped(1), Tuple(Wrapped(1), Wrapped(2)).into()); assert_eq!( Wrapped(2), Struct { field1: Wrapped(1), field2: Wrapped(2), } .into(), ); } } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into((Transmuted, Transmuted))] struct Tuple(Wrapped, Wrapped); #[derive(Debug, Into, PartialEq)] #[into((Transmuted, Transmuted))] struct Struct { field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!( (Transmuted(1), Transmuted(2)), Tuple(Wrapped(1), Wrapped(2)).into(), ); assert_eq!( (Transmuted(1), Transmuted(2)), Struct { field1: Wrapped(1), field2: Wrapped(2), } .into(), ); } } mod ref_ { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref)] struct Tuple(Wrapped, Wrapped); #[derive(Debug, Into, PartialEq)] #[into(ref)] struct Struct { field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!( (&Wrapped(1), &Wrapped(2)), (&Tuple(Wrapped(1), Wrapped(2))).into(), ); assert_eq!( (&Wrapped(1), &Wrapped(2)), (&Struct { field1: Wrapped(1), field2: Wrapped(2), }) .into(), ); } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref((Transmuted, Transmuted)))] struct Tuple(Wrapped, Wrapped); #[derive(Debug, Into, PartialEq)] #[into(ref((Transmuted, Transmuted)))] struct Struct { field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!( (&Transmuted(1), &Transmuted(2)), (&Tuple(Wrapped(1), Wrapped(2))).into(), ); assert_eq!( (&Transmuted(1), &Transmuted(2)), (&Struct { field1: Wrapped(1), field2: Wrapped(2), }) .into(), ); } } } mod ref_mut { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref_mut)] struct Tuple(Wrapped, Wrapped); #[derive(Debug, Into, PartialEq)] #[into(ref_mut)] struct Struct { field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!( (&mut Wrapped(1), &mut Wrapped(2)), (&mut Tuple(Wrapped(1), Wrapped(2))).into(), ); assert_eq!( (&mut Wrapped(1), &mut Wrapped(2)), (&mut Struct { field1: Wrapped(1), field2: Wrapped(2), }) .into(), ); } mod types { use super::*; #[derive(Debug, Into, PartialEq)] #[into(ref_mut((Transmuted, Transmuted)))] struct Tuple(Wrapped, Wrapped); #[derive(Debug, Into, PartialEq)] #[into(ref_mut((Transmuted, Transmuted)))] struct Struct { field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!( (&mut Transmuted(1), &mut Transmuted(2)), (&mut Tuple(Wrapped(1), Wrapped(2))).into(), ); assert_eq!( (&mut Transmuted(1), &mut Transmuted(2)), (&mut Struct { field1: Wrapped(1), field2: Wrapped(2), }) .into(), ); } } } mod indirect { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple( &'static Wrapped, &'static Wrapped, ); #[derive(Debug, Into, PartialEq)] struct Struct { field1: &'static Wrapped, field2: &'static Wrapped, } #[test] fn assert() { assert_eq!( (&Wrapped(1), &Wrapped(2)), Tuple(&Wrapped(1), &Wrapped(2)).into(), ); assert_eq!( (&Wrapped(1), &Wrapped(2)), (Struct { field1: &Wrapped(1), field2: &Wrapped(2), }) .into(), ); } } mod bounded { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(Wrapped, Wrapped); #[derive(Debug, Into, PartialEq)] struct Struct { field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!( (Wrapped(1), Wrapped(2)), Tuple(Wrapped(1), Wrapped(2)).into(), ); assert_eq!( (Wrapped(1), Wrapped(2)), Struct { field1: Wrapped(1), field2: Wrapped(2), } .into(), ); } } mod r#const { use super::*; #[derive(Debug, Into, PartialEq)] struct Tuple(Wrapped, Wrapped); #[derive(Debug, Into, PartialEq)] struct Struct { field1: Wrapped, field2: Wrapped, } #[test] fn assert() { assert_eq!( (Wrapped(1), Wrapped(2)), Tuple::<1, _, _>(Wrapped(1), Wrapped(2)).into(), ); assert_eq!( (Wrapped(1), Wrapped(2)), Struct::<_, 1, _> { field1: Wrapped(1), field2: Wrapped(2), } .into(), ); } } } } mod with_fields { use super::*; mod only { use super::*; #[derive(Clone, Copy, Debug, Into)] struct Tuple(#[into] i32, f64, #[into] f64); // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl From for (i32, f64, f64) { fn from(value: Tuple) -> Self { (value.0, value.1, value.2) } } // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl From for (i32, f64) { fn from(value: Tuple) -> Self { (value.0, value.2) } } #[test] fn tuple() { let t = Tuple(1, 2.0, 3.0); assert_eq!(1, t.into()); assert_eq!(3.0, t.into()); } #[derive(Clone, Copy, Debug, Into)] struct Struct { #[into] a: i32, b: f64, #[into] c: f64, } // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl From for (i32, f64, f64) { fn from(value: Struct) -> Self { (value.a, value.b, value.c) } } // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl From for (i32, f64) { fn from(value: Struct) -> Self { (value.a, value.c) } } #[test] fn named() { let s = Struct { a: 1, b: 2.0, c: 3.0, }; assert_eq!(1, s.into()); assert_eq!(3.0, s.into()); } mod types { use super::*; #[derive(Clone, Debug, Into)] struct Tuple( #[into(Box, Cow<'_, str>)] String, f64, #[into(f32, f64)] f32, ); // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl From for String { fn from(value: Tuple) -> Self { value.0 } } // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl From for (String, f64, f32) { fn from(value: Tuple) -> Self { (value.0, value.1, value.2) } } #[test] fn tuple() { let f = Tuple("1".to_owned(), 2.0, 3.0); assert_eq!(Box::::from("1".to_owned()), f.clone().into()); assert_eq!(Cow::Borrowed("1"), Cow::::from(f.clone())); assert_eq!(3.0f32, f.clone().into()); assert_eq!(3.0f64, f.into()); } #[derive(Clone, Debug, Into)] struct Struct { #[into(Box, Cow<'_, str>)] a: String, b: f64, #[into(f32, f64)] c: f32, } // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl From for String { fn from(value: Struct) -> Self { value.a } } // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl From for (String, f64, f32) { fn from(value: Struct) -> Self { (value.a, value.b, value.c) } } // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl From for (Box, f32) { fn from(value: Struct) -> Self { (value.a.into(), value.c) } } #[test] fn named() { let s = Struct { a: "1".to_owned(), b: 2.0, c: 3.0, }; assert_eq!(Box::::from("1".to_owned()), s.clone().into()); assert_eq!(Cow::Borrowed("1"), Cow::::from(s.clone())); assert_eq!(3.0f32, s.clone().into()); assert_eq!(3.0f64, s.into()); } mod r#ref { use super::*; #[derive(Debug, Into)] struct Tuple(#[into(ref)] String, f64, #[into(ref)] f64); // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl<'a> From<&'a Tuple> for (&'a String, &'a f64, &'a f64) { fn from(value: &'a Tuple) -> Self { (&value.0, &value.1, &value.2) } } #[test] fn tuple() { let t = Tuple("1".to_owned(), 2.0, 3.0); assert_eq!(&"1".to_owned(), <&String>::from(&t)); assert_eq!(&3.0, <&f64>::from(&t)); } #[derive(Debug, Into)] struct Struct { #[into(ref)] a: String, b: f64, #[into(ref)] c: f64, } // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl<'a> From<&'a Struct> for (&'a String, &'a f64, &'a f64) { fn from(value: &'a Struct) -> Self { (&value.a, &value.b, &value.c) } } // Asserts that macro expansion doesn't generate this impl, by producing a trait // implementations conflict error during compilation, if it does. impl<'a> From<&'a Struct> for (&'a String, &'a f64) { fn from(value: &'a Struct) -> Self { (&value.a, &value.c) } } #[test] fn named() { let s = Struct { a: "1".to_owned(), b: 2.0, c: 3.0, }; assert_eq!(&"1".to_owned(), <&String>::from(&s)); assert_eq!(&3.0, <&f64>::from(&s)); } mod types { use super::*; #[derive(Debug, Into)] struct Tuple( #[into(ref(Transmuted))] Wrapped, #[into(ref(Wrapped))] Wrapped, ); #[test] fn tuple() { let t = Tuple(Wrapped(1), Wrapped(2)); assert_eq!(&Transmuted(1), <&Transmuted>::from(&t)); assert_eq!(&Wrapped(2), <&Wrapped>::from(&t)); } #[derive(Debug, Into)] struct Struct { #[into(ref(Transmuted))] a: Wrapped, #[into(ref(Wrapped))] b: Wrapped, } #[test] fn named() { let s = Struct { a: Wrapped(1), b: Wrapped(2), }; assert_eq!(&Transmuted(1), <&Transmuted>::from(&s)); assert_eq!(&Wrapped(2), <&Wrapped>::from(&s)); } } mod ref_mut { use super::*; #[derive(Debug, Into)] struct Tuple(#[into(ref_mut)] i32, f64, #[into(ref_mut)] f64); #[test] fn tuple() { let mut t = Tuple(1, 2.0, 3.0); assert_eq!(&mut 1, <&mut i32>::from(&mut t)); assert_eq!(&mut 3.0, <&mut f64>::from(&mut t)); } #[derive(Debug, Into)] struct Struct { #[into(ref_mut)] a: i32, b: f64, #[into(ref_mut)] c: f64, } #[test] fn named() { let mut s = Struct { a: 1, b: 2.0, c: 3.0, }; assert_eq!(&mut 1, <&mut i32>::from(&mut s)); assert_eq!(&mut 3.0, <&mut f64>::from(&mut s)); } mod types { use super::*; #[derive(Debug, Into)] struct Tuple( #[into(ref_mut(Transmuted))] Wrapped, #[into(ref_mut(Wrapped))] Wrapped, ); #[test] fn tuple() { let mut t = Tuple(Wrapped(1), Wrapped(2)); assert_eq!( &mut Transmuted(1), <&mut Transmuted>::from(&mut t), ); assert_eq!( &mut Wrapped(2), <&mut Wrapped>::from(&mut t), ); } #[derive(Debug, Into)] struct Struct { #[into(ref_mut(Transmuted))] a: Wrapped, #[into(ref_mut(Wrapped))] b: Wrapped, } #[test] fn named() { let mut s = Struct { a: Wrapped(1), b: Wrapped(2), }; assert_eq!( &mut Transmuted(1), <&mut Transmuted>::from(&mut s), ); assert_eq!( &mut Wrapped(2), <&mut Wrapped>::from(&mut s), ); } } } } } } mod mixed { use super::*; #[derive(Debug, Into)] #[into(ref((Wrapped, Transmuted)))] struct Tuple( #[into(owned, ref(Transmuted))] Wrapped, #[into(skip)] #[into(ref)] Wrapped, #[into(ref_mut(Wrapped, Transmuted))] Wrapped, ); #[test] fn tuple() { let mut t = Tuple(Wrapped(1), Wrapped(2.0), Wrapped(3.0)); assert_eq!(&Transmuted(1), <&Transmuted>::from(&t)); assert_eq!(&mut Transmuted(3.0), <&mut Transmuted>::from(&mut t)); assert_eq!(&mut Wrapped(3.0), <&mut Wrapped>::from(&mut t)); assert_eq!((&Wrapped(1), &Transmuted(3.0)), (&t).into()); assert_eq!(&Wrapped(2.0), <&Wrapped>::from(&t)); assert_eq!(Wrapped(1), t.into()); } #[derive(Debug, Into)] #[into(ref((Wrapped, Transmuted)))] struct Struct { #[into(owned, ref(Transmuted))] a: Wrapped, #[into(skip)] #[into(ref)] b: Wrapped, #[into(ref_mut(Wrapped, Transmuted))] c: Wrapped, } #[test] fn named() { let mut s = Struct { a: Wrapped(1), b: Wrapped(2.0), c: Wrapped(3.0), }; assert_eq!(&Transmuted(1), <&Transmuted>::from(&s)); assert_eq!(&mut Transmuted(3.0), <&mut Transmuted>::from(&mut s)); assert_eq!(&mut Wrapped(3.0), <&mut Wrapped>::from(&mut s)); assert_eq!((&Wrapped(1), &Transmuted(3.0)), (&s).into()); assert_eq!(&Wrapped(2.0), <&Wrapped>::from(&s)); assert_eq!(Wrapped(1), s.into()); } mod separate { use super::*; #[derive(Clone, Copy, Debug, Into)] #[into(ref)] #[into(owned)] #[into((Wrapped, Transmuted))] #[into(ref_mut((Wrapped, Transmuted)))] struct Tuple( #[into(ref)] #[into(ref(Transmuted))] #[into] Wrapped, #[into(ref_mut)] #[into(ref_mut(Transmuted))] #[into(owned)] Wrapped, ); #[test] fn tuple() { let mut t = Tuple(Wrapped(1), Wrapped(2.0)); assert_eq!((&Wrapped(1), &Wrapped(2.0)), (&t).into()); assert_eq!((Wrapped(1), Wrapped(2.0)), t.into()); assert_eq!((Wrapped(1), Transmuted(2.0)), t.into()); assert_eq!((&mut Wrapped(1), &mut Transmuted(2.0)), (&mut t).into()); assert_eq!(&Wrapped(1), <&Wrapped>::from(&t)); assert_eq!(&Transmuted(1), <&Transmuted>::from(&t)); assert_eq!(Wrapped(1), >::from(t)); assert_eq!(&mut Wrapped(2.0), <&mut Wrapped>::from(&mut t)); assert_eq!(&mut Transmuted(2.0), <&mut Transmuted>::from(&mut t)); assert_eq!(Wrapped(2.0), >::from(t)); } #[derive(Clone, Copy, Debug, Into)] #[into(ref)] #[into(owned)] #[into((Wrapped, Transmuted))] #[into(ref_mut((Wrapped, Transmuted)))] struct Struct { #[into(ref)] #[into(ref (Transmuted < i32 >))] #[into] a: Wrapped, #[into(ref_mut)] #[into(ref_mut(Transmuted < f32 >))] #[into(owned)] b: Wrapped, } #[test] fn named() { let mut s = Struct { a: Wrapped(1), b: Wrapped(2.0), }; assert_eq!((&Wrapped(1), &Wrapped(2.0)), (&s).into()); assert_eq!((Wrapped(1), Wrapped(2.0)), s.into()); assert_eq!((Wrapped(1), Transmuted(2.0)), s.into()); assert_eq!((&mut Wrapped(1), &mut Transmuted(2.0)), (&mut s).into()); assert_eq!(&Wrapped(1), <&Wrapped>::from(&s)); assert_eq!(&Transmuted(1), <&Transmuted>::from(&s)); assert_eq!(Wrapped(1), >::from(s)); assert_eq!(&mut Wrapped(2.0), <&mut Wrapped>::from(&mut s)); assert_eq!(&mut Transmuted(2.0), <&mut Transmuted>::from(&mut s),); assert_eq!(Wrapped(2.0), >::from(s)); } } } } derive_more-1.0.0/tests/into_iterator.rs000064400000000000000000000075131046102023000165220ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] #[macro_use] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::vec::Vec; use core::fmt::Debug; use derive_more::IntoIterator; #[track_caller] fn assert_iter>(iter: I, vals: &[T]) { assert_eq!(iter.into_iter().collect::>(), vals); } #[derive(IntoIterator)] #[into_iterator(owned, ref, ref_mut)] struct MyVec(Vec); #[test] fn tuple_single() { let mut vals = vec![1, 2, 3]; let mut iter = MyVec(vals.clone()); assert_iter(&mut iter, &vals.iter_mut().collect::>()); assert_iter(&iter, &vals.iter().collect::>()); assert_iter(iter, &vals); } #[derive(IntoIterator)] #[into_iterator(owned, ref, ref_mut)] struct Numbers { numbers: Vec, } #[test] fn named_single() { let mut vals = vec![1, 2, 3]; let mut iter = Numbers { numbers: vals.clone(), }; assert_iter(&mut iter, &vals.iter_mut().collect::>()); assert_iter(&iter, &vals.iter().collect::>()); assert_iter(iter, &vals); } #[derive(IntoIterator)] struct Numbers2 { #[into_iterator(owned, ref, ref_mut)] numbers: Vec, useless: bool, useless2: bool, } fn named_many() { let mut vals = vec![1, 2, 3]; let mut iter = Numbers2 { numbers: vals.clone(), useless: true, useless2: true, }; assert_iter(&mut iter, &vals.iter_mut().collect::>()); assert_iter(&iter, &vals.iter().collect::>()); assert_iter(iter, &vals); } #[derive(IntoIterator)] struct Numbers3 { #[into_iterator(ref, ref_mut)] numbers: Vec, useless: bool, useless2: bool, } // Test that `owned` is not enabled when `ref`/`ref_mut` are enabled without `owned`. impl ::core::iter::IntoIterator for Numbers3 { type Item = as ::core::iter::IntoIterator>::Item; type IntoIter = as ::core::iter::IntoIterator>::IntoIter; #[inline] fn into_iter(self) -> Self::IntoIter { as ::core::iter::IntoIterator>::into_iter(self.numbers) } } #[derive(IntoIterator)] struct Generic1 { #[into_iterator(owned, ref, ref_mut)] items: Vec, } #[test] fn generic() { let mut vals = vec![1, 2, 3]; let mut iter = Generic1 { items: vals.clone(), }; assert_iter(&mut iter, &vals.iter_mut().collect::>()); assert_iter(&iter, &vals.iter().collect::>()); assert_iter(iter, &vals); } #[derive(IntoIterator)] struct Generic2<'a, T, U: Send> where T: Send, { #[into_iterator(owned, ref, ref_mut)] items: Vec, useless: &'a U, } #[test] fn generic_bounds() { let mut vals = vec![1, 2, 3]; let useless = false; let mut iter = Generic2 { items: vals.clone(), useless: &useless, }; assert_iter(&mut iter, &vals.iter_mut().collect::>()); assert_iter(&iter, &vals.iter().collect::>()); assert_iter(iter, &vals); } #[derive(IntoIterator)] struct Generic3<'a, 'b, T> { #[into_iterator(owned)] items: &'a mut Vec<&'b mut T>, } #[test] fn generic_refs() { let mut numbers = vec![1, 2, 3]; let mut numbers2 = numbers.clone(); let mut number_refs = numbers.iter_mut().collect::>(); let mut number_refs2 = numbers2.iter_mut().collect::>(); assert_iter( Generic3 { items: &mut number_refs, }, &number_refs2.iter_mut().collect::>(), ) } #[derive(IntoIterator)] struct Generic4 { #[into_iterator] items: Vec, useless: bool, } #[test] fn generic_owned() { let numbers = vec![1, 2, 3]; assert_iter( Generic4 { items: numbers.clone(), useless: true, }, &numbers, ); } derive_more-1.0.0/tests/is_variant.rs000064400000000000000000000073161046102023000160000ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use derive_more::IsVariant; #[derive(IsVariant)] enum Either { Left(TLeft), Right(TRight), } const _: () = { let either: Either = Either::Right(7); assert!(either.is_right()); assert!(!either.is_left()); let either: Either = Either::Left(7); assert!(!either.is_right()); assert!(either.is_left()); }; #[derive(IsVariant)] enum Maybe { Nothing, Just(T), } const _: () = { let maybe: Maybe = Maybe::Just(7); assert!(maybe.is_just()); assert!(!maybe.is_nothing()); let maybe: Maybe = Maybe::Nothing; assert!(!maybe.is_just()); assert!(maybe.is_nothing()); }; #[test] pub fn test_is_variant() { assert!(Maybe::<()>::Nothing.is_nothing()); assert!(!Maybe::<()>::Nothing.is_just()); } #[derive(IsVariant)] enum Color { Rgb(u8, u8, u8), Cmyk { c: u8, m: u8, y: u8, k: u8 }, } const _: () = { let color = Color::Rgb(0, 0, 0); assert!(color.is_rgb()); assert!(!color.is_cmyk()); let color = Color::Cmyk { c: 0, m: 0, y: 0, k: 0, }; assert!(!color.is_rgb()); assert!(color.is_cmyk()); }; #[derive(IsVariant)] enum Nonsense<'a, T> { Ref(&'a T), NoRef, #[is_variant(ignore)] NoRefIgnored, } const _: () = { let nonsense: Nonsense = Nonsense::Ref(&7); assert!(nonsense.is_ref()); assert!(!nonsense.is_no_ref()); let nonsense: Nonsense = Nonsense::NoRef; assert!(!nonsense.is_ref()); assert!(nonsense.is_no_ref()); }; #[derive(IsVariant)] enum WithConstraints where T: Copy, { One(T), Two, } const _: () = { let wc: WithConstraints = WithConstraints::One(1); assert!(wc.is_one()); assert!(!wc.is_two()); let wc: WithConstraints = WithConstraints::Two; assert!(!wc.is_one()); assert!(wc.is_two()); }; #[derive(IsVariant)] enum KitchenSink<'a, 'b, T1: Copy, T2: Clone> where T2: Into + 'b, { Left(&'a T1), Right(&'b T2), OwnBoth { left: T1, right: T2 }, Empty, NeverMind(), NothingToSeeHere {}, } const _: () = { let ks: KitchenSink = KitchenSink::Left(&1); assert!(ks.is_left()); assert!(!ks.is_right()); assert!(!ks.is_own_both()); assert!(!ks.is_empty()); assert!(!ks.is_never_mind()); assert!(!ks.is_nothing_to_see_here()); let ks: KitchenSink = KitchenSink::Right(&1); assert!(!ks.is_left()); assert!(ks.is_right()); assert!(!ks.is_own_both()); assert!(!ks.is_empty()); assert!(!ks.is_never_mind()); assert!(!ks.is_nothing_to_see_here()); let ks: KitchenSink = KitchenSink::OwnBoth { left: 1, right: 2 }; assert!(!ks.is_left()); assert!(!ks.is_right()); assert!(ks.is_own_both()); assert!(!ks.is_empty()); assert!(!ks.is_never_mind()); assert!(!ks.is_nothing_to_see_here()); let ks: KitchenSink = KitchenSink::Empty; assert!(!ks.is_left()); assert!(!ks.is_right()); assert!(!ks.is_own_both()); assert!(ks.is_empty()); assert!(!ks.is_never_mind()); assert!(!ks.is_nothing_to_see_here()); let ks: KitchenSink = KitchenSink::NeverMind(); assert!(!ks.is_left()); assert!(!ks.is_right()); assert!(!ks.is_own_both()); assert!(!ks.is_empty()); assert!(ks.is_never_mind()); assert!(!ks.is_nothing_to_see_here()); let ks: KitchenSink = KitchenSink::NothingToSeeHere {}; assert!(!ks.is_left()); assert!(!ks.is_right()); assert!(!ks.is_own_both()); assert!(!ks.is_empty()); assert!(!ks.is_never_mind()); assert!(ks.is_nothing_to_see_here()); }; derive_more-1.0.0/tests/lib.rs000064400000000000000000000162311046102023000144030ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] use derive_more::{ Add, AddAssign, Binary, BitAnd, BitOr, BitXor, Constructor, Deref, DerefMut, Display, Div, From, FromStr, Index, IndexMut, Into, IntoIterator, Mul, MulAssign, Neg, Not, Octal, Product, Rem, Shl, Shr, Sub, Sum, }; #[derive(From)] #[derive(Into)] #[derive(Constructor)] #[derive(Clone, Debug, Eq, PartialEq)] #[derive(Add)] #[derive(Mul)] #[derive(Neg)] #[derive(AddAssign)] #[derive(MulAssign)] #[derive(FromStr)] #[derive(Display)] #[derive(Octal)] #[derive(Binary)] #[derive(Deref, DerefMut)] #[into(owned, ref, ref_mut)] struct MyInt(i32); #[derive(Clone, Debug, Eq, PartialEq)] #[derive(Add)] #[derive(Sum)] #[derive(Mul)] #[derive(MulAssign)] #[derive(Product)] #[mul(forward)] #[mul_assign(forward)] struct MyInt2(i32); #[derive(Debug, Eq, PartialEq)] #[derive(Index, IndexMut)] #[derive(Deref, DerefMut)] #[derive(IntoIterator)] #[deref(forward)] #[deref_mut(forward)] #[into_iterator(owned, ref, ref_mut)] struct MyVec(Vec); #[derive(Debug, Eq, PartialEq)] #[derive(Deref, DerefMut)] #[deref(forward)] #[deref_mut(forward)] struct MyBoxedInt(Box); #[derive(Debug, Eq, PartialEq)] #[derive(Not)] #[derive(From)] struct MyBool(bool); #[derive(From)] #[derive(Into)] #[derive(Constructor)] #[derive(Add)] #[derive(Debug, Eq, PartialEq)] #[derive(Mul)] #[derive(AddAssign)] struct MyUInt(u64, u64); #[derive(From)] #[derive(Into)] #[derive(Constructor)] #[derive(FromStr)] #[derive(Debug, Eq, PartialEq)] #[derive(Display)] struct SimpleStruct { int1: u64, } #[derive(From)] #[derive(Constructor)] #[derive(Add, Sub, Mul, Div, Rem, BitAnd, BitOr, BitXor, Shr, Shl)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Into)] #[derive(AddAssign)] #[into(owned, ref, ref_mut)] struct NormalStruct { int1: u64, int2: u64, } #[derive(From)] #[derive(Debug, Eq, PartialEq)] struct NestedInt(MyInt); #[derive(Debug, Eq, PartialEq)] #[derive(From)] #[derive(Add, Sub)] enum SimpleMyIntEnum { Int(i32), #[from(ignore)] _UnsignedOne(u32), _UnsignedTwo(u32), } #[derive(Debug, Eq, PartialEq)] #[derive(From)] #[derive(Neg)] enum SimpleSignedIntEnum { Int(i32), Int2(i16), } #[derive(Debug, Eq, PartialEq)] #[derive(From)] #[derive(Add, Sub)] #[derive(Neg)] enum SimpleEnum { Int(i32), #[from(ignore)] _Ints(i32, i32), LabeledInts { a: i32, b: i32, }, _SomeUnit, } #[derive(Debug, Eq, PartialEq)] #[derive(From)] #[derive(Add, Sub)] enum MyIntEnum { SmallInt(i32), BigInt(i64), TwoInts(i32, i32), Point2D { x: i64, y: i64, }, #[from(ignore)] _UnsignedOne(u32), _UnsignedTwo(u32), #[from(ignore)] _Uints1(u64, u64), _Uints2 { x: u64, y: u64, }, } #[derive(Debug, Eq, PartialEq)] #[derive(Add, Mul)] struct DoubleUInt(u32, u32); #[derive(Debug, Eq, PartialEq)] #[derive(Add, Mul)] struct DoubleUIntStruct { x: u32, y: u32, } #[derive(Debug, Eq, PartialEq)] #[derive(From, Into, Constructor)] struct Unit; // Tests that we can forward to a path // containing `$crate` macro_rules! use_dollar_crate { () => { struct Foo; #[derive(From)] enum Bar { First(#[from(forward)] $crate::Foo), } }; } use_dollar_crate!(); #[test] fn main() { let mut myint: MyInt = 5.into(); let _: SimpleMyIntEnum = 5i32.into(); let _: MyIntEnum = 5i32.into(); let _: MyIntEnum = 6i64.into(); let _: MyIntEnum = (5i32, 8i32).into(); let _: MyIntEnum = (5i64, 8i64).into(); let int_ref: &i32 = (&myint).into(); assert_eq!(int_ref, &5); let int_ref_mut: &mut i32 = (&mut myint).into(); assert_eq!(int_ref_mut, &mut 5); let mut myint: MyInt = 5.into(); let _: Unit = ().into(); assert!(matches!(Unit.into(), ())); assert_eq!(Unit, Unit::new()); assert_eq!(MyInt(5), 5.into()); assert_eq!(Ok(MyInt(5)), "5".parse()); assert_eq!(5, MyInt(5).into()); assert_eq!(MyInt(5), MyInt::new(5)); assert_eq!(-MyInt(5), (-5).into()); assert_eq!("30", MyInt(30).to_string()); assert_eq!("36", format!("{:o}", MyInt(30))); assert_eq!("100", format!("{:b}", MyInt(4))); assert_eq!(!MyBool(true), false.into()); assert_eq!(MyIntEnum::SmallInt(5), 5.into()); assert_eq!(SimpleStruct { int1: 5 }, 5.into()); assert_eq!(5u64, SimpleStruct { int1: 5 }.into()); assert_eq!(Ok(SimpleStruct { int1: 5 }), "5".parse()); assert_eq!("5", SimpleStruct { int1: 5 }.to_string()); assert_eq!(NormalStruct { int1: 5, int2: 6 }, (5, 6).into()); assert_eq!(SimpleStruct { int1: 5 }, SimpleStruct::new(5)); assert_eq!(NormalStruct { int1: 5, int2: 6 }, NormalStruct::new(5, 6)); assert_eq!((5, 6), NormalStruct::new(5, 6).into()); let mut norm_struct = NormalStruct::new(5, 6); let uints_ref: (&u64, &u64) = (&norm_struct).into(); assert_eq!((&5, &6), uints_ref); let uints_ref_mut: (&mut u64, &mut u64) = (&mut norm_struct).into(); assert_eq!((&mut 5, &mut 6), uints_ref_mut); assert_eq!(MyInt(4) + MyInt(1), 5.into()); myint += MyInt(3); assert_eq!(myint, 8.into()); myint *= 5; assert_eq!(myint, 40.into()); assert_eq!(MyInt(4) + MyInt(1), 5.into()); assert_eq!(MyUInt(4, 5) + MyUInt(1, 2), MyUInt(5, 7)); assert_eq!(MyUInt(4, 5), MyUInt::new(4, 5)); assert_eq!((4, 5), MyUInt(4, 5).into()); let mut s1 = NormalStruct { int1: 1, int2: 2 }; let s2 = NormalStruct { int1: 2, int2: 3 }; let s3 = NormalStruct { int1: 3, int2: 5 }; assert_eq!(s1 + s2, s3); assert_eq!(s3 - s2, s1); s1 += s2; assert_eq!(s1, s3); assert_eq!((SimpleMyIntEnum::Int(6) + 5.into()).unwrap(), 11.into()); assert_eq!((SimpleMyIntEnum::Int(6) - 5.into()).unwrap(), 1.into()); assert_eq!((SimpleMyIntEnum::Int(6) - 5.into()).unwrap(), 1.into()); assert_eq!(-SimpleSignedIntEnum::Int(6), (-6i32).into()); assert_eq!( (SimpleEnum::LabeledInts { a: 6, b: 5 } + SimpleEnum::LabeledInts { a: 1, b: 4 }) .unwrap(), SimpleEnum::LabeledInts { a: 7, b: 9 } ); let _ = (MyIntEnum::SmallInt(5) + 6.into()).unwrap(); assert_eq!((-SimpleEnum::Int(5)).unwrap(), (-5).into()); assert_eq!(MyInt(50), MyInt(5) * 10); assert_eq!(DoubleUInt(5, 6) * 10, DoubleUInt(50, 60)); assert_eq!( DoubleUIntStruct { x: 5, y: 6 } * 10, DoubleUIntStruct { x: 50, y: 60 } ); let mut myint = MyInt(5); assert_eq!(5, *myint); *myint = 7; assert_eq!(MyInt(7), myint); let mut my_vec = MyVec(vec![5, 8]); assert_eq!(5, my_vec[0]); assert_eq!(8, my_vec[1]); my_vec[0] = 20; assert_eq!(20, my_vec[0]); assert_eq!((&my_vec).into_iter().next(), Some(&20)); assert_eq!((&mut my_vec).into_iter().next(), Some(&mut 20)); assert_eq!(my_vec.into_iter().next(), Some(20)); let int_vec = vec![MyInt2(2), MyInt2(3)]; assert_eq!(MyInt2(5), int_vec.clone().into_iter().sum()); assert_eq!(MyInt2(6), int_vec.clone().into_iter().product()); let mut myint2 = MyInt2(8); myint2 *= MyInt2(4); assert_eq!(MyInt2(32), myint2); let mut boxed = MyBoxedInt(Box::new(5)); assert_eq!(5, *boxed); *boxed = 7; assert_eq!(MyBoxedInt(Box::new(7)), boxed) } derive_more-1.0.0/tests/mul.rs000064400000000000000000000004731046102023000144330ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use derive_more::Mul; #[derive(Mul)] struct MyInt(i32); #[derive(Mul)] struct MyInts(i32, i32); #[derive(Mul)] struct Point1D { x: i32, } #[derive(Mul)] struct Point2D { x: i32, y: i32, } derive_more-1.0.0/tests/mul_assign.rs000064400000000000000000000010171046102023000157720ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use core::marker::PhantomData; use derive_more::MulAssign; #[derive(MulAssign)] struct MyInt(i32); #[derive(MulAssign)] struct MyInts(i32, i32); #[derive(MulAssign)] #[mul_assign(forward)] struct MyIntForward(i32); #[derive(MulAssign)] struct Point1D { x: i32, } #[derive(MulAssign)] struct Point2D { x: i32, y: i32, } #[derive(MulAssign)] struct MyInt2 { x: i32, ph: PhantomData, } derive_more-1.0.0/tests/no_std.rs000064400000000000000000000057701046102023000151310ustar 00000000000000#![no_std] #![allow(dead_code)] // some code is tested for type checking only use derive_more::{ Add, AddAssign, Constructor, Deref, DerefMut, Display, From, FromStr, Index, IndexMut, Into, IntoIterator, Mul, MulAssign, Not, Sum, TryInto, }; #[derive( AddAssign, MulAssign, Add, Mul, Not, Index, Display, FromStr, Into, From, IndexMut, Sum, Deref, DerefMut, Constructor )] #[into(owned, ref, ref_mut)] struct MyInts(u64); #[derive(Deref, DerefMut)] #[deref(forward)] #[deref_mut(forward)] struct MyBoxedInt<'a>(&'a mut u64); #[derive( From, FromStr, Display, Index, Not, Add, Mul, Sum, IndexMut, AddAssign, Deref, DerefMut, IntoIterator, Constructor )] #[deref(forward)] #[deref_mut(forward)] #[into_iterator(owned, ref, ref_mut)] struct Wrapped(T); #[derive(Deref, DerefMut)] struct Wrapped2(T); #[derive(From, Not, Add, Mul, AddAssign, Constructor, Sum)] struct WrappedDouble(T, U); #[derive(Add, Not, TryInto)] #[try_into(owned, ref, ref_mut)] enum MixedInts { SmallInt(i32), BigInt(i64), TwoSmallInts(i32, i32), NamedSmallInts { x: i32, y: i32 }, UnsignedOne(u32), UnsignedTwo(u32), } #[derive(Not, Add)] enum EnumWithUnit { SmallInt(i32), Unit, } #[rustversion::nightly] mod error { use derive_more::{Display, Error, From}; #[derive(Default, Debug, Display, Error)] struct Simple; #[derive(Default, Debug, Display, Error)] struct WithSource { source: Simple, } #[derive(Default, Debug, Display, Error)] struct WithExplicitSource { #[error(source)] explicit_source: Simple, } #[derive(Default, Debug, Display, Error)] struct Tuple(Simple); #[derive(Default, Debug, Display, Error)] struct WithoutSource(#[error(not(source))] i32); #[derive(Debug, Display, Error, From)] enum CompoundError { Simple, WithSource { source: Simple, }, WithExplicitSource { #[error(source)] explicit_source: WithSource, }, Tuple(WithExplicitSource), WithoutSource(#[error(not(source))] Tuple), } #[test] fn assert() { assert!(Simple.source().is_none()); assert!(WithSource::default().source().is_some()); assert!(WithExplicitSource::default().source().is_some()); assert!(Tuple::default().source().is_some()); assert!(Tuple::default().source().is_some()); assert!(WithoutSource::default().source().is_none()); assert!(CompoundError::Simple.source().is_none()); assert!(CompoundError::from(Simple).source().is_some()); assert!(CompoundError::from(WithSource::default()) .source() .is_some()); assert!(CompoundError::from(WithExplicitSource::default()) .source() .is_some()); assert!(CompoundError::from(Tuple::default()).source().is_none()); } } derive_more-1.0.0/tests/not.rs000064400000000000000000000007421046102023000144350ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use derive_more::Not; #[derive(Not)] struct MyInts(i32, i32); #[derive(Not)] struct Point2D { x: i32, y: i32, } #[derive(Not)] enum MixedInts { SmallInt(i32), BigInt(i64), TwoSmallInts(i32, i32), NamedSmallInts { x: i32, y: i32 }, UnsignedOne(u32), UnsignedTwo(u32), } #[derive(Not)] enum EnumWithUnit { SmallInt(i32), Unit, } derive_more-1.0.0/tests/sum.rs000064400000000000000000000013341046102023000144370ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use derive_more::Sum; #[derive(Sum)] struct MyInts(i32, i64); // `Add` implementation is required for `Sum`. impl ::core::ops::Add for MyInts { type Output = MyInts; #[inline] fn add(self, rhs: MyInts) -> MyInts { MyInts(self.0.add(rhs.0), self.1.add(rhs.1)) } } #[derive(Sum)] struct Point2D { x: i32, y: i32, } // `Add` implementation is required for `Sum`. impl ::core::ops::Add for Point2D { type Output = Point2D; #[inline] fn add(self, rhs: Point2D) -> Point2D { Point2D { x: self.x.add(rhs.x), y: self.y.add(rhs.y), } } } derive_more-1.0.0/tests/try_from.rs000064400000000000000000000042141046102023000154740ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use derive_more::TryFrom; #[test] fn test_with_repr() { #[derive(TryFrom, Clone, Copy, Debug, Eq, PartialEq)] #[repr(i16)] #[try_from(repr)] enum Enum { A, B = -21, C, D, } assert_eq!(Enum::A, Enum::try_from(0i16).unwrap()); assert_eq!(Enum::B, Enum::try_from(-21).unwrap()); assert_eq!(Enum::C, Enum::try_from(-20).unwrap()); assert_eq!(Enum::D, Enum::try_from(-19).unwrap()); assert!(Enum::try_from(-1).is_err()); } #[test] fn enum_without_repr() { #[derive(TryFrom, Clone, Copy, Debug, Eq, PartialEq)] #[try_from(repr)] enum Enum { A, B = -21, C, D, } assert_eq!(Enum::A, Enum::try_from(0isize).unwrap()); assert_eq!(Enum::B, Enum::try_from(-21).unwrap()); assert_eq!(Enum::C, Enum::try_from(-20).unwrap()); assert_eq!(Enum::D, Enum::try_from(-19).unwrap()); assert!(Enum::try_from(-1).is_err()); } #[test] fn enum_with_complex_repr() { #[derive(TryFrom, Clone, Copy, Debug, Eq, PartialEq)] #[try_from(repr)] #[repr(align(16), i32)] enum Enum { A, B = -21, C, D, } assert_eq!(Enum::A, Enum::try_from(0i32).unwrap()); assert_eq!(Enum::B, Enum::try_from(-21).unwrap()); assert_eq!(Enum::C, Enum::try_from(-20).unwrap()); assert_eq!(Enum::D, Enum::try_from(-19).unwrap()); assert!(Enum::try_from(-1).is_err()); } #[test] fn test_discriminants_on_enum_with_fields() { #[derive(TryFrom, Clone, Copy, Debug, Eq, PartialEq)] #[try_from(repr)] #[repr(i16)] enum Enum { A, Discriminant = 5, Field(usize), Empty {}, FieldWithDiscriminant(u8, i64) = -14, EmptyTuple(), } assert_eq!(Enum::A, Enum::try_from(0).unwrap()); assert_eq!(Enum::Discriminant, Enum::try_from(5).unwrap()); assert!(Enum::try_from(6).is_err()); assert_eq!(Enum::Empty {}, Enum::try_from(7).unwrap()); assert!(Enum::try_from(-14).is_err()); assert_eq!(Enum::EmptyTuple(), Enum::try_from(-13).unwrap()); } derive_more-1.0.0/tests/try_into.rs000064400000000000000000000173531046102023000155120ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::string::ToString; use derive_more::TryInto; // Ensure that the `TryInto` macro is hygienic and doesn't break when `Result` // has been redefined. type Result = (); #[derive(TryInto, Clone, Copy, Debug, Eq, PartialEq)] #[try_into(owned, ref, ref_mut)] enum MixedInts { SmallInt(i32), NamedBigInt { int: i64, }, UnsignedWithIgnoredField(#[try_into(ignore)] bool, i64), NamedUnsignedWithIgnoredField { #[try_into(ignore)] useless: bool, x: i64, }, TwoSmallInts(i32, i32), NamedBigInts { x: i64, y: i64, }, Unsigned(u32), NamedUnsigned { x: u32, }, Unit, #[try_into(ignore)] Unit2, } #[derive(Clone, Copy, Debug, Eq, PartialEq)] struct Wrapper<'a, const Y: usize, U>(&'a [U; Y]); enum Foo<'lt: 'static, T: Clone, const X: usize> { X(Wrapper<'lt, X, T>), } #[test] fn test_try_into() { let mut i = MixedInts::SmallInt(42); assert_eq!(42i32, i.try_into().unwrap()); assert_eq!(&42i32, <_ as TryInto<&i32>>::try_into(&i).unwrap()); assert_eq!( &mut 42i32, <_ as TryInto<&mut i32>>::try_into(&mut i).unwrap() ); assert_eq!( i64::try_from(i).unwrap_err().to_string(), "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64" ); assert_eq!(i64::try_from(i).unwrap_err().input, MixedInts::SmallInt(42)); assert_eq!( <(i32, i32)>::try_from(i).unwrap_err().to_string(), "Only TwoSmallInts can be converted to (i32, i32)" ); assert_eq!( <(i64, i64)>::try_from(i).unwrap_err().to_string(), "Only NamedBigInts can be converted to (i64, i64)" ); assert_eq!( u32::try_from(i).unwrap_err().to_string(), "Only Unsigned, NamedUnsigned can be converted to u32" ); assert_eq!( <()>::try_from(i).unwrap_err().to_string(), "Only Unit can be converted to ()" ); let mut i = MixedInts::NamedBigInt { int: 42 }; assert_eq!( i32::try_from(i).unwrap_err().to_string(), "Only SmallInt can be converted to i32" ); assert_eq!(42i64, i.try_into().unwrap()); assert_eq!(&42i64, <_ as TryInto<&i64>>::try_into(&i).unwrap()); assert_eq!( &mut 42i64, <_ as TryInto<&mut i64>>::try_into(&mut i).unwrap() ); assert_eq!( <(i32, i32)>::try_from(i).unwrap_err().to_string(), "Only TwoSmallInts can be converted to (i32, i32)" ); assert_eq!( <(i64, i64)>::try_from(i).unwrap_err().to_string(), "Only NamedBigInts can be converted to (i64, i64)" ); assert_eq!( u32::try_from(i).unwrap_err().to_string(), "Only Unsigned, NamedUnsigned can be converted to u32" ); assert_eq!( <()>::try_from(i).unwrap_err().to_string(), "Only Unit can be converted to ()" ); let mut i = MixedInts::TwoSmallInts(42, 64); assert_eq!( i32::try_from(i).unwrap_err().to_string(), "Only SmallInt can be converted to i32" ); assert_eq!( i64::try_from(i).unwrap_err().to_string(), "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64" ); assert_eq!((42i32, 64i32), i.try_into().unwrap()); assert_eq!((&42i32, &64i32), (&i).try_into().unwrap()); assert_eq!((&mut 42i32, &mut 64i32), (&mut i).try_into().unwrap()); assert_eq!( <(i64, i64)>::try_from(i).unwrap_err().to_string(), "Only NamedBigInts can be converted to (i64, i64)" ); assert_eq!( u32::try_from(i).unwrap_err().to_string(), "Only Unsigned, NamedUnsigned can be converted to u32" ); assert_eq!( <()>::try_from(i).unwrap_err().to_string(), "Only Unit can be converted to ()" ); let mut i = MixedInts::NamedBigInts { x: 42, y: 64 }; assert_eq!( i32::try_from(i).unwrap_err().to_string(), "Only SmallInt can be converted to i32" ); assert_eq!( i64::try_from(i).unwrap_err().to_string(), "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64" ); assert_eq!( <(i32, i32)>::try_from(i).unwrap_err().to_string(), "Only TwoSmallInts can be converted to (i32, i32)" ); assert_eq!((42i64, 64i64), i.try_into().unwrap()); assert_eq!((&42i64, &64i64), (&i).try_into().unwrap()); assert_eq!((&mut 42i64, &mut 64i64), (&mut i).try_into().unwrap()); assert_eq!( u32::try_from(i).unwrap_err().to_string(), "Only Unsigned, NamedUnsigned can be converted to u32" ); assert_eq!( <()>::try_from(i).unwrap_err().to_string(), "Only Unit can be converted to ()" ); let mut i = MixedInts::Unsigned(42); assert_eq!( i32::try_from(i).unwrap_err().to_string(), "Only SmallInt can be converted to i32" ); assert_eq!( i64::try_from(i).unwrap_err().to_string(), "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64" ); assert_eq!( <(i32, i32)>::try_from(i).unwrap_err().to_string(), "Only TwoSmallInts can be converted to (i32, i32)" ); assert_eq!( <(i64, i64)>::try_from(i).unwrap_err().to_string(), "Only NamedBigInts can be converted to (i64, i64)" ); assert_eq!(42u32, i.try_into().unwrap()); assert_eq!(&42u32, <_ as TryInto<&u32>>::try_into(&i).unwrap()); assert_eq!( &mut 42u32, <_ as TryInto<&mut u32>>::try_into(&mut i).unwrap() ); assert_eq!( <()>::try_from(i).unwrap_err().to_string(), "Only Unit can be converted to ()" ); let mut i = MixedInts::NamedUnsigned { x: 42 }; assert_eq!( i32::try_from(i).unwrap_err().to_string(), "Only SmallInt can be converted to i32" ); assert_eq!( i64::try_from(i).unwrap_err().to_string(), "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64" ); assert_eq!( i64::try_from(i).unwrap_err().to_string(), "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64" ); assert_eq!( <(i32, i32)>::try_from(i).unwrap_err().to_string(), "Only TwoSmallInts can be converted to (i32, i32)" ); assert_eq!( <(i64, i64)>::try_from(i).unwrap_err().to_string(), "Only NamedBigInts can be converted to (i64, i64)" ); assert_eq!(42u32, i.try_into().unwrap()); assert_eq!(&42u32, <_ as TryInto<&u32>>::try_into(&i).unwrap()); assert_eq!( &mut 42u32, <_ as TryInto<&mut u32>>::try_into(&mut i).unwrap() ); assert_eq!( <()>::try_from(i).unwrap_err().to_string(), "Only Unit can be converted to ()" ); let i = MixedInts::Unit; assert_eq!( i32::try_from(i).unwrap_err().to_string(), "Only SmallInt can be converted to i32" ); assert_eq!( i64::try_from(i).unwrap_err().to_string(), "Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnoredField can be converted to i64" ); assert_eq!( <(i32, i32)>::try_from(i).unwrap_err().to_string(), "Only TwoSmallInts can be converted to (i32, i32)" ); assert_eq!( <(i64, i64)>::try_from(i).unwrap_err().to_string(), "Only NamedBigInts can be converted to (i64, i64)" ); assert_eq!( u32::try_from(i).unwrap_err().to_string(), "Only Unsigned, NamedUnsigned can be converted to u32" ); assert!(matches!(i.try_into().unwrap(), ())); } derive_more-1.0.0/tests/try_unwrap.rs000064400000000000000000000050421046102023000160450ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only #[cfg(not(feature = "std"))] extern crate alloc; #[cfg(not(feature = "std"))] use alloc::string::ToString; use derive_more::TryUnwrap; #[derive(TryUnwrap)] enum Either { Left(TLeft), Right(TRight), } #[derive(TryUnwrap)] #[derive(Debug, PartialEq)] #[try_unwrap(ref, ref_mut)] enum Maybe { Nothing, Just(T), } #[derive(TryUnwrap)] enum Color { Rgb(u8, u8, u8), Cmyk(u8, u8, u8, u8), } /// With lifetime #[derive(TryUnwrap)] enum Nonsense<'a, T> { Ref(&'a T), NoRef, #[try_unwrap(ignore)] NoRefIgnored, } #[derive(TryUnwrap)] enum WithConstraints where T: Copy, { One(T), Two, } #[derive(TryUnwrap)] enum KitchenSink<'a, 'b, T1: Copy, T2: Clone> where T2: Into + 'b, { Left(&'a T1), Right(&'b T2), OwnBoth(T1, T2), Empty, NeverMind(), NothingToSeeHere(), } /// Single variant enum #[derive(TryUnwrap)] enum Single { Value(i32), } #[derive(TryUnwrap)] #[derive(Debug, PartialEq)] #[try_unwrap(ref, ref_mut)] enum Tuple { None, Single(T), Double(T, T), Triple(T, T, T), } #[test] pub fn test_try_unwrap() { assert_eq!(Maybe::<()>::Nothing.try_unwrap_nothing().ok(), Some(())); assert_eq!(Maybe::Just(1).try_unwrap_just_ref().ok(), Some(&1)); assert_eq!(Maybe::Just(42).try_unwrap_just_mut().ok(), Some(&mut 42)); assert_eq!( Maybe::<()>::Nothing.try_unwrap_just().map_err(|e| e.input), Err(Maybe::<()>::Nothing), ); assert_eq!( Maybe::Just(1).try_unwrap_nothing_ref().map_err(|e| e.input), Err(&Maybe::Just(1)), ); assert_eq!( Maybe::Just(42) .try_unwrap_nothing_mut() .map_err(|e| e.to_string()), Err( "Attempt to call `Maybe::try_unwrap_nothing_mut()` on a `Maybe::Just` value" .to_string() ), ); } #[test] pub fn test_try_unwrap_mut_1() { let mut value = Tuple::Double(1, 12); if let Ok((a, b)) = value.try_unwrap_double_mut() { *a = 9; *b = 10; } assert_eq!(value, Tuple::Double(9, 10)); } #[test] pub fn test_try_unwrap_mut_2() { let mut value = Tuple::Single(128); if let Ok(x) = value.try_unwrap_single_mut() { *x *= 2; } if let Err(e) = value.try_unwrap_none_mut() { let x = *e.input.try_unwrap_single_ref().unwrap_or(&0); *e.input = Tuple::Double(x - 1, x); } assert_eq!(value, Tuple::Double(255, 256)); } derive_more-1.0.0/tests/unwrap.rs000064400000000000000000000037111046102023000151500ustar 00000000000000#![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] // some code is tested for type checking only use derive_more::Unwrap; #[derive(Unwrap)] enum Either { Left(TLeft), Right(TRight), } #[derive(Unwrap)] #[derive(Debug)] #[unwrap(ref, ref_mut)] enum Maybe { Nothing, Just(T), } #[derive(Unwrap)] enum Color { Rgb(u8, u8, u8), Cmyk(u8, u8, u8, u8), } /// With lifetime #[derive(Unwrap)] enum Nonsense<'a, T> { Ref(&'a T), NoRef, #[unwrap(ignore)] NoRefIgnored, } #[derive(Unwrap)] enum WithConstraints where T: Copy, { One(T), Two, } #[derive(Unwrap)] enum KitchenSink<'a, 'b, T1: Copy, T2: Clone> where T2: Into + 'b, { Left(&'a T1), Right(&'b T2), OwnBoth(T1, T2), Empty, NeverMind(), NothingToSeeHere(), } /// Single variant enum #[derive(Unwrap)] enum Single { Value(i32), } #[derive(Unwrap)] #[derive(Debug, PartialEq)] #[unwrap(ref, ref_mut)] enum Tuple { None, Single(T), Double(T, T), Triple(T, T, T), } #[test] pub fn test_unwrap() { assert!(matches!(Maybe::<()>::Nothing.unwrap_nothing(), ())); assert_eq!(Maybe::Just(1).unwrap_just(), 1); assert_eq!(Maybe::Just(42).unwrap_just_ref(), &42); assert_eq!(Maybe::Just(42).unwrap_just_mut(), &mut 42); } #[test] #[should_panic] pub fn test_unwrap_panic_1() { Maybe::<()>::Nothing.unwrap_just(); } #[test] #[should_panic] pub fn test_unwrap_panic_2() { Maybe::Just(2).unwrap_nothing(); } #[test] #[should_panic] pub fn test_unwrap_ref_panic() { Maybe::Just(2).unwrap_nothing_ref(); } #[test] pub fn test_unwrap_mut_1() { let mut value = Tuple::Double(1, 12); let (a, b) = value.unwrap_double_mut(); *a = 9; *b = 10; assert_eq!(value, Tuple::Double(9, 10)) } #[test] pub fn test_unwrap_mut_2() { let mut value = Tuple::Single(128); let x = value.unwrap_single_mut(); *x *= 2; assert_eq!(value, Tuple::Single(256)); }