chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

View File

@@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"15b6f86bb464b0b3a0ea41accdf7153d721f83835881292f76fca73a6e37b29a",".github/workflows/ci.yml":"d9f8c68f56908f4db84a982f94a5075158be332ecabc9330edae2483c4cda847","CHANGELOG.md":"9aadbd7c8b22fa4574b2080d0baaa908f43b5ed2c320c64ec88476cbf739871b","Cargo.lock":"53ebb1c438812bf2e049126afd9bb833d02278416d49ed436d67b4c5c03f21b1","Cargo.toml":"c6f12ae2dd031cf599ec131d3b6b89fb5de66edc4416b4a8f2f06b3fda889620","Cargo.toml.orig":"8758bd1de805bb131da8871a94d92b266df10766d304a6ddecae0be8b07dde1a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"4e230c5596f208b8b752edaa1ff3ace5b1508da61f2069129fa5a6fbda6f4834","README.tpl":"974701ae7f6d238bd325dd32104a5265841e79a9b79a595f7fdd964711c0cd19","examples/simple.rs":"bca524b36621ac56044cbe3eebf8892f7a3b398fd8f257fc67b17b26ae34bfbf","src/attr.rs":"10b31136a5d46066066ea3988f8b857b554fa62b3737988967ae7c2aaa97a58b","src/expand.rs":"6d201ddf75b065875131f437d5a911bb4b2d3e9fe385eebbfc61101d790549dd","src/fmt.rs":"9c13cbcd337066614bc26ecfd36ea9730c9b8099083a9a7ffd79f8dc17e414f1","src/lib.rs":"01b770363022045aa8de41548b20764db7278ae90add903642312eaa4408d467","tests/compile_tests.rs":"935609d68eaa52e0ce9f29b3dae649787cd1f540f9b4bbadcbefcb8a0febcfc8","tests/happy.rs":"1b4c119184ca3914684c1cafaa25a8fbb9e60ef45eb257ad7ac86b8b2d7a3856","tests/no_std/enum_prefix.rs":"386e18cd6b6d35df0a864473a820aa05872f2f7f8364793adae784203946eb82","tests/no_std/enum_prefix_missing.rs":"f60100eac4b3a0f86c57b2082ee52e94b3fa0b5029e535fd3fd55cc1aeaf308c","tests/no_std/enum_prefix_missing.stderr":"e0e98f4dfc21f8cb133519ff98f10b08d8c76219b54cfbc6436c46ba9c601ead","tests/no_std/multi_line.rs":"b0c0cdc7631234a9b7a49205bb1d6824821153001ab30ddad1948deaaaa363c3","tests/no_std/multi_line.stderr":"08cba6ace9ac1938ea8fe18ed4a536b861ad48a9f9d646b4a7ebfe4bf5da438c","tests/no_std/multi_line_allow.rs":"7f7b300db1336b5d9487f82e10deee6a22a7d749ae3698e13e45455540ed5742","tests/no_std/with.rs":"ba96ba70da11f7d5afb5b43a23d8f1d7d28b1eceda8c84c1595006145b8e15fd","tests/no_std/without.rs":"fa2d73e9d6b3bff8073bc95296aeef69e4e8c20a8e6666c239041564877cfec9","tests/no_std/without.stderr":"be00cd4dd7396f324c1cb6283d02a38ad55e3b4d2684e7a4b6bbd43ed937c7f2","tests/num_in_field.rs":"d0bc3ba7f9aea17d3abee4ac05afe6d4a0112d3527698791e1eeaa3464e2b1d4","tests/std/enum_prefix.rs":"baab2132d9468ec167423048ba5244394238e488523214b9e50adee46920f700","tests/std/enum_prefix_missing.rs":"58c8f7c9d851689ca59caf475c0e5f12674f5a58ecbb025cac232acc68eec8aa","tests/std/enum_prefix_missing.stderr":"a26fa36de033d2b032a1e6475cb8d89ee1266e15647bcfaf192931188b38445b","tests/std/multi_line.rs":"b0c0cdc7631234a9b7a49205bb1d6824821153001ab30ddad1948deaaaa363c3","tests/std/multi_line.stderr":"02ca7d07ae4f72c726457c918506ed38873b5085af53c5b60090b53cf5ae46b0","tests/std/multi_line_allow.rs":"ecacc0120aa127dc289d6333348ab357c74d6cb49851de43e7cf3984facf0abc","tests/std/multiple.rs":"b8dc9939c41b2655600ba1b698dbdbbef6e907bff533b6f2cbc315134013fc84","tests/std/without.rs":"fa2d73e9d6b3bff8073bc95296aeef69e4e8c20a8e6666c239041564877cfec9","tests/std/without.stderr":"606a9470520b99eb17c1e609e1074b3765ccd3ab4f1d0b3c3cc2bda9811884de","tests/variantless.rs":"af6930daa15f488fcc00fd2a623a2662ddb86d071ffe698bd97c13c65b9b50a3","update-readme.sh":"7885d60cba79c3dc2b779b9805d520960cc7d8b82d7f1d0c59deff4140ac857b"},"package":"97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"}

View File

@@ -0,0 +1,6 @@
{
"git": {
"sha1": "e4028851bfb82998300237f7568a45f589a19e40"
},
"path_in_vcs": ""
}

View File

@@ -0,0 +1,120 @@
on:
push:
pull_request:
schedule:
- cron: '0 0 * * *'
name: Continuous integration
jobs:
check:
name: Check
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
- 1.56.0
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
override: true
- uses: actions-rs/cargo@v1
with:
command: check
test:
name: Test Suite
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
- nightly
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
override: true
- uses: Swatinem/rust-cache@v1
- name: Install cargo-nextest
uses: baptiste0928/cargo-install@v1
with:
crate: cargo-nextest
version: 0.9
- uses: actions-rs/cargo@v1
with:
command: nextest
args: run
- uses: actions-rs/cargo@v1
with:
command: nextest
args: run --no-default-features
- uses: actions-rs/cargo@v1
with:
command: test
args: --doc
test-msrv:
name: msrv Test Suite
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.56.0
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
override: true
- uses: Swatinem/rust-cache@v1
- uses: actions-rs/cargo@v1
with:
command: test
- uses: actions-rs/cargo@v1
with:
command: test
args: --no-default-features
fmt:
name: Rustfmt
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
- 1.56.0
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
override: true
- run: rustup component add rustfmt
- uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
clippy:
name: Clippy
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- stable
steps:
- uses: actions/checkout@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
override: true
- run: rustup component add clippy
- uses: actions-rs/cargo@v1
with:
command: clippy
args: -- -D warnings

58
vendor/displaydoc/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,58 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
<!-- next-header -->
## [Unreleased] - ReleaseDate
# [0.2.5] - 2024-06-20
# Changed
- Don't name the output of the const block to work around `non_local_definitions` error (#47)
- Reference the `core` crate correctly to avoid clashes with modules named `core` (#45)
- Explicitly list MSRV in Cargo.toml (#51)
- Bump edition to 2021 (#51)
# [0.2.4] - 2022-05-02
## Added
- Updated `syn` dependency to 2.0
- Support for empty enums
- Implicitly require fmt::Display on all type parameters unless overridden
## Changed
- Bumped MSRV to 1.56
# [0.2.3] - 2021-07-16
## Added
- Added `#[displaydoc("..")]` attribute for overriding a doc comment
# [0.2.2] - 2021-07-01
## Added
- Added prefix feature to use the doc comment from an enum and prepend it
before the error message from each variant.
# [0.2.1] - 2021-03-26
## Added
- Added opt in support for ignoring extra doc attributes
# [0.2.0] - 2021-03-16
## Changed
- (BREAKING) disallow multiple `doc` attributes in display impl
[https://github.com/yaahc/displaydoc/pull/22]. Allowing and ignoring extra
doc attributes made it too easy to accidentally create a broken display
implementation with missing context without realizing it, this change turns
that into a hard error and directs users towards block comments if multiple
lines are needed.
<!-- next-url -->
[Unreleased]: https://github.com/yaahc/displaydoc/compare/v0.2.4...HEAD
[0.2.4]: https://github.com/yaahc/displaydoc/compare/v0.2.3...v0.2.4
[0.2.3]: https://github.com/yaahc/displaydoc/compare/v0.2.2...v0.2.3
[0.2.2]: https://github.com/yaahc/displaydoc/compare/v0.2.1...v0.2.2
[0.2.1]: https://github.com/yaahc/displaydoc/compare/v0.2.0...v0.2.1
[0.2.0]: https://github.com/yaahc/displaydoc/releases/tag/v0.2.0

404
vendor/displaydoc/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,404 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]]
name = "ctor"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
dependencies = [
"quote",
"syn 1.0.109",
]
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
[[package]]
name = "displaydoc"
version = "0.2.5"
dependencies = [
"libc",
"pretty_assertions",
"proc-macro2",
"quote",
"rustversion",
"static_assertions",
"syn 2.0.66",
"thiserror",
"trybuild",
]
[[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 = "libc"
version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "output_vt100"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66"
dependencies = [
"winapi",
]
[[package]]
name = "pretty_assertions"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
dependencies = [
"ansi_term",
"ctor",
"difference",
"output_vt100",
]
[[package]]
name = "proc-macro2"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
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 = "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 = "serde"
version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "serde_json"
version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
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 = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
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 = "thiserror"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "toml"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
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.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"winnow",
]
[[package]]
name = "trybuild"
version = "1.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33a5f13f11071020bb12de7a16b925d2d58636175c20c11dc5f96cb64bb6c9b3"
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 = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[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 = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
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.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[package]]
name = "windows_i686_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[package]]
name = "windows_i686_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
name = "winnow"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1"
dependencies = [
"memchr",
]

115
vendor/displaydoc/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,115 @@
# 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.56.0"
name = "displaydoc"
version = "0.2.5"
authors = ["Jane Lusby <jlusby@yaah.dev>"]
description = """
A derive macro for implementing the display Trait via a doc comment and string interpolation
"""
homepage = "https://github.com/yaahc/displaydoc"
documentation = "https://docs.rs/displaydoc"
readme = "README.md"
keywords = [
"display",
"derive",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/yaahc/displaydoc"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
"--cfg",
"docsrs",
]
[package.metadata.release]
no-dev-version = true
pre-release-hook = ["./update-readme.sh"]
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
replace = "{{version}}"
search = "Unreleased"
[[package.metadata.release.pre-release-replacements]]
exactly = 1
file = "src/lib.rs"
replace = "#![doc(html_root_url = \"https://docs.rs/{{crate_name}}/{{version}}\")]"
search = '#!\[doc\(html_root_url.*'
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
replace = "{{date}}"
search = "ReleaseDate"
[[package.metadata.release.pre-release-replacements]]
exactly = 1
file = "CHANGELOG.md"
replace = """
<!-- next-header -->
# [Unreleased] - ReleaseDate"""
search = "<!-- next-header -->"
[[package.metadata.release.pre-release-replacements]]
exactly = 1
file = "CHANGELOG.md"
replace = "...{{tag_name}}"
search = '\.\.\.HEAD'
[[package.metadata.release.pre-release-replacements]]
exactly = 1
file = "CHANGELOG.md"
replace = """
<!-- next-url -->
[Unreleased]: https://github.com/yaahc/{{crate_name}}/compare/{{tag_name}}...HEAD"""
search = "<!-- next-url -->"
[lib]
path = "src/lib.rs"
proc-macro = true
[dependencies.proc-macro2]
version = "1.0"
[dependencies.quote]
version = "1.0"
[dependencies.syn]
version = "2.0"
[dev-dependencies.libc]
version = "0.2"
default-features = false
[dev-dependencies.pretty_assertions]
version = "0.6.1"
[dev-dependencies.rustversion]
version = "1.0.0"
[dev-dependencies.static_assertions]
version = "1.1"
[dev-dependencies.thiserror]
version = "1.0.24"
[dev-dependencies.trybuild]
version = "1.0"
[features]
default = ["std"]
std = []

201
vendor/displaydoc/LICENSE-APACHE vendored Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

23
vendor/displaydoc/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,23 @@
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.

115
vendor/displaydoc/README.md vendored Normal file
View File

@@ -0,0 +1,115 @@
derive(Display) /// `From<docs>`
===============
[![Latest Version](https://img.shields.io/crates/v/displaydoc.svg)](https://crates.io/crates/displaydoc)
[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/displaydoc)
This library provides a convenient derive macro for the standard library's
[`core::fmt::Display`] trait.
[`core::fmt::Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
```toml
[dependencies]
displaydoc = "0.2"
```
*Compiler support: requires rustc 1.56+*
<br>
### Example
*Demonstration alongside the [`Error`][std::error::Error] derive macro from [`thiserror`](https://docs.rs/thiserror/1.0.25/thiserror/index.html),
to propagate source locations from [`io::Error`][std::io::Error] with the `#[source]` attribute:*
```rust
use std::io;
use displaydoc::Display;
use thiserror::Error;
#[derive(Display, Error, Debug)]
pub enum DataStoreError {
/// data store disconnected
Disconnect(#[source] io::Error),
/// the data for key `{0}` is not available
Redaction(String),
/// invalid header (expected {expected:?}, found {found:?})
InvalidHeader {
expected: String,
found: String,
},
/// unknown data store error
Unknown,
}
let error = DataStoreError::Redaction("CLASSIFIED CONTENT".to_string());
assert!("the data for key `CLASSIFIED CONTENT` is not available" == &format!("{}", error));
```
*Note that although [`io::Error`][std::io::Error] implements `Display`, we do not add it to the
generated message for `DataStoreError::Disconnect`, since it is already made available via
`#[source]`. See further context on avoiding duplication in error reports at the rust blog
[here](https://github.com/yaahc/blog.rust-lang.org/blob/master/posts/inside-rust/2021-05-15-What-the-error-handling-project-group-is-working-towards.md#duplicate-information-issue).*
<br>
### Details
- A `fmt::Display` impl is generated for your enum if you provide
a docstring comment on each variant as shown above in the example. The
`Display` derive macro supports a shorthand for interpolating fields from
the error:
- `/// {var}``write!("{}", self.var)`
- `/// {0}``write!("{}", self.0)`
- `/// {var:?}``write!("{:?}", self.var)`
- `/// {0:?}``write!("{:?}", self.0)`
- This also works with structs and [generic types][crate::Display#generic-type-parameters]:
```rust
/// oh no, an error: {0}
#[derive(Display)]
pub struct Error<E>(pub E);
let error: Error<&str> = Error("muahaha i am an error");
assert!("oh no, an error: muahaha i am an error" == &format!("{}", error));
```
- Two optional attributes can be added to your types next to the derive:
- `#[ignore_extra_doc_attributes]` makes the macro ignore any doc
comment attributes (or `///` lines) after the first. Multi-line
comments using `///` are otherwise treated as an error, so use this
attribute or consider switching to block doc comments (`/** */`).
- `#[prefix_enum_doc_attributes]` combines the doc comment message on
your enum itself with the messages for each variant, in the format
“enum: variant”. When added to an enum, the doc comment on the enum
becomes mandatory. When added to any other type, it has no effect.
- In case you want to have an independent doc comment, the
`#[displaydoc("...")` atrribute may be used on the variant or struct to
override it.
<br>
### FAQ
1. **Is this crate `no_std` compatible?**
* Yes! This crate implements the [`core::fmt::Display`] trait, not the [`std::fmt::Display`] trait, so it should work in `std` and `no_std` environments. Just add `default-features = false`.
2. **Does this crate work with `Path` and `PathBuf` via the `Display` trait?**
* Yuuup. This crate uses @dtolnay's [autoref specialization technique](https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md) to add a special trait for types to get the display impl. It then specializes for `Path` and `PathBuf`, and when either of these types are found, it calls `self.display()` to get a `std::path::Display<'_>` type which can be used with the `Display` format specifier!
#### License
<sup>
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
</sup>
<br>
<sub>
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.
</sub>

23
vendor/displaydoc/README.tpl vendored Normal file
View File

@@ -0,0 +1,23 @@
derive(Display) /// `From<docs>`
===============
[![Latest Version](https://img.shields.io/crates/v/displaydoc.svg)](https://crates.io/crates/displaydoc)
[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/displaydoc)
{{readme}}
#### License
<sup>
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
</sup>
<br>
<sub>
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.
</sub>

36
vendor/displaydoc/examples/simple.rs vendored Normal file
View File

@@ -0,0 +1,36 @@
use displaydoc::Display;
#[derive(Debug, Display)]
pub enum DataStoreError {
/// data store disconnected
Disconnect,
/// the data for key `{0}` is not available
Redaction(String),
/// invalid header (expected {expected:?}, found {found:?})
InvalidHeader { expected: String, found: String },
/// unknown data store error
Unknown,
}
fn main() {
let disconnect = DataStoreError::Disconnect;
println!(
"Enum value `Disconnect` should be printed as:\n\t{}",
disconnect
);
let redaction = DataStoreError::Redaction(String::from("Dummy"));
println!(
"Enum value `Redaction` should be printed as:\n\t{}",
redaction
);
let invalid_header = DataStoreError::InvalidHeader {
expected: String::from("https"),
found: String::from("http"),
};
println!(
"Enum value `InvalidHeader` should be printed as:\n\t{}",
invalid_header
);
}

137
vendor/displaydoc/src/attr.rs vendored Normal file
View File

@@ -0,0 +1,137 @@
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn::{Attribute, LitStr, Meta, Result};
#[derive(Clone)]
pub(crate) struct Display {
pub(crate) fmt: LitStr,
pub(crate) args: TokenStream,
}
pub(crate) struct VariantDisplay {
pub(crate) r#enum: Option<Display>,
pub(crate) variant: Display,
}
impl ToTokens for Display {
fn to_tokens(&self, tokens: &mut TokenStream) {
let fmt = &self.fmt;
let args = &self.args;
tokens.extend(quote! {
write!(formatter, #fmt #args)
});
}
}
impl ToTokens for VariantDisplay {
fn to_tokens(&self, tokens: &mut TokenStream) {
if let Some(ref r#enum) = self.r#enum {
r#enum.to_tokens(tokens);
tokens.extend(quote! { ?; write!(formatter, ": ")?; });
}
self.variant.to_tokens(tokens);
}
}
pub(crate) struct AttrsHelper {
ignore_extra_doc_attributes: bool,
prefix_enum_doc_attributes: bool,
}
impl AttrsHelper {
pub(crate) fn new(attrs: &[Attribute]) -> Self {
let ignore_extra_doc_attributes = attrs
.iter()
.any(|attr| attr.path().is_ident("ignore_extra_doc_attributes"));
let prefix_enum_doc_attributes = attrs
.iter()
.any(|attr| attr.path().is_ident("prefix_enum_doc_attributes"));
Self {
ignore_extra_doc_attributes,
prefix_enum_doc_attributes,
}
}
pub(crate) fn display(&self, attrs: &[Attribute]) -> Result<Option<Display>> {
let displaydoc_attr = attrs.iter().find(|attr| attr.path().is_ident("displaydoc"));
if let Some(displaydoc_attr) = displaydoc_attr {
let lit = displaydoc_attr
.parse_args()
.expect("#[displaydoc(\"foo\")] must contain string arguments");
let mut display = Display {
fmt: lit,
args: TokenStream::new(),
};
display.expand_shorthand();
return Ok(Some(display));
}
let num_doc_attrs = attrs
.iter()
.filter(|attr| attr.path().is_ident("doc"))
.count();
if !self.ignore_extra_doc_attributes && num_doc_attrs > 1 {
panic!("Multi-line comments are disabled by default by displaydoc. Please consider using block doc comments (/** */) or adding the #[ignore_extra_doc_attributes] attribute to your type next to the derive.");
}
for attr in attrs {
if attr.path().is_ident("doc") {
let lit = match &attr.meta {
Meta::NameValue(syn::MetaNameValue {
value:
syn::Expr::Lit(syn::ExprLit {
lit: syn::Lit::Str(lit),
..
}),
..
}) => lit,
_ => unimplemented!(),
};
// Make an attempt at cleaning up multiline doc comments.
let doc_str = lit
.value()
.lines()
.map(|line| line.trim().trim_start_matches('*').trim())
.collect::<Vec<&str>>()
.join("\n");
let lit = LitStr::new(doc_str.trim(), lit.span());
let mut display = Display {
fmt: lit,
args: TokenStream::new(),
};
display.expand_shorthand();
return Ok(Some(display));
}
}
Ok(None)
}
pub(crate) fn display_with_input(
&self,
r#enum: &[Attribute],
variant: &[Attribute],
) -> Result<Option<VariantDisplay>> {
let r#enum = if self.prefix_enum_doc_attributes {
let result = self
.display(r#enum)?
.expect("Missing doc comment on enum with #[prefix_enum_doc_attributes]. Please remove the attribute or add a doc comment to the enum itself.");
Some(result)
} else {
None
};
Ok(self
.display(variant)?
.map(|variant| VariantDisplay { r#enum, variant }))
}
}

409
vendor/displaydoc/src/expand.rs vendored Normal file
View File

@@ -0,0 +1,409 @@
use super::attr::AttrsHelper;
use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote};
use syn::{
punctuated::Punctuated,
token::{Colon, Comma, PathSep, Plus, Where},
Data, DataEnum, DataStruct, DeriveInput, Error, Fields, Generics, Ident, Path, PathArguments,
PathSegment, PredicateType, Result, TraitBound, TraitBoundModifier, Type, TypeParam,
TypeParamBound, TypePath, WhereClause, WherePredicate,
};
use std::collections::HashMap;
pub(crate) fn derive(input: &DeriveInput) -> Result<TokenStream> {
let impls = match &input.data {
Data::Struct(data) => impl_struct(input, data),
Data::Enum(data) => impl_enum(input, data),
Data::Union(_) => Err(Error::new_spanned(input, "Unions are not supported")),
}?;
let helpers = specialization();
Ok(quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
#helpers
#impls
};
})
}
#[cfg(feature = "std")]
fn specialization() -> TokenStream {
quote! {
trait DisplayToDisplayDoc {
fn __displaydoc_display(&self) -> Self;
}
impl<T: ::core::fmt::Display> DisplayToDisplayDoc for &T {
fn __displaydoc_display(&self) -> Self {
self
}
}
// If the `std` feature gets enabled we want to ensure that any crate
// using displaydoc can still reference the std crate, which is already
// being compiled in by whoever enabled the `std` feature in
// `displaydoc`, even if the crates using displaydoc are no_std.
extern crate std;
trait PathToDisplayDoc {
fn __displaydoc_display(&self) -> std::path::Display<'_>;
}
impl PathToDisplayDoc for std::path::Path {
fn __displaydoc_display(&self) -> std::path::Display<'_> {
self.display()
}
}
impl PathToDisplayDoc for std::path::PathBuf {
fn __displaydoc_display(&self) -> std::path::Display<'_> {
self.display()
}
}
}
}
#[cfg(not(feature = "std"))]
fn specialization() -> TokenStream {
quote! {}
}
fn impl_struct(input: &DeriveInput, data: &DataStruct) -> Result<TokenStream> {
let ty = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let where_clause = generate_where_clause(&input.generics, where_clause);
let helper = AttrsHelper::new(&input.attrs);
let display = helper.display(&input.attrs)?.map(|display| {
let pat = match &data.fields {
Fields::Named(fields) => {
let var = fields.named.iter().map(|field| &field.ident);
quote!(Self { #(#var),* })
}
Fields::Unnamed(fields) => {
let var = (0..fields.unnamed.len()).map(|i| format_ident!("_{}", i));
quote!(Self(#(#var),*))
}
Fields::Unit => quote!(_),
};
quote! {
impl #impl_generics ::core::fmt::Display for #ty #ty_generics #where_clause {
fn fmt(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
// NB: This destructures the fields of `self` into named variables (for unnamed
// fields, it uses _0, _1, etc as above). The `#[allow(unused_variables)]`
// section means it doesn't have to parse the individual field references out of
// the docstring.
#[allow(unused_variables)]
let #pat = self;
#display
}
}
}
});
Ok(quote! { #display })
}
/// Create a `where` predicate for `ident`, without any [bound][TypeParamBound]s yet.
fn new_empty_where_type_predicate(ident: Ident) -> PredicateType {
let mut path_segments = Punctuated::<PathSegment, PathSep>::new();
path_segments.push_value(PathSegment {
ident,
arguments: PathArguments::None,
});
PredicateType {
lifetimes: None,
bounded_ty: Type::Path(TypePath {
qself: None,
path: Path {
leading_colon: None,
segments: path_segments,
},
}),
colon_token: Colon {
spans: [Span::call_site()],
},
bounds: Punctuated::<TypeParamBound, Plus>::new(),
}
}
/// Create a `where` clause that we can add [WherePredicate]s to.
fn new_empty_where_clause() -> WhereClause {
WhereClause {
where_token: Where {
span: Span::call_site(),
},
predicates: Punctuated::<WherePredicate, Comma>::new(),
}
}
enum UseGlobalPrefix {
LeadingColon,
#[allow(dead_code)]
NoLeadingColon,
}
/// Create a path with segments composed of [Idents] *without* any [PathArguments].
fn join_paths(name_segments: &[&str], use_global_prefix: UseGlobalPrefix) -> Path {
let mut segments = Punctuated::<PathSegment, PathSep>::new();
assert!(!name_segments.is_empty());
segments.push_value(PathSegment {
ident: Ident::new(name_segments[0], Span::call_site()),
arguments: PathArguments::None,
});
for name in name_segments[1..].iter() {
segments.push_punct(PathSep {
spans: [Span::call_site(), Span::mixed_site()],
});
segments.push_value(PathSegment {
ident: Ident::new(name, Span::call_site()),
arguments: PathArguments::None,
});
}
Path {
leading_colon: match use_global_prefix {
UseGlobalPrefix::LeadingColon => Some(PathSep {
spans: [Span::call_site(), Span::mixed_site()],
}),
UseGlobalPrefix::NoLeadingColon => None,
},
segments,
}
}
/// Push `new_type_predicate` onto the end of `where_clause`.
fn append_where_clause_type_predicate(
where_clause: &mut WhereClause,
new_type_predicate: PredicateType,
) {
// Push a comma at the end if there are already any `where` predicates.
if !where_clause.predicates.is_empty() {
where_clause.predicates.push_punct(Comma {
spans: [Span::call_site()],
});
}
where_clause
.predicates
.push_value(WherePredicate::Type(new_type_predicate));
}
/// Add a requirement for [core::fmt::Display] to a `where` predicate for some type.
fn add_display_constraint_to_type_predicate(
predicate_that_needs_a_display_impl: &mut PredicateType,
) {
// Create a `Path` of `::core::fmt::Display`.
let display_path = join_paths(&["core", "fmt", "Display"], UseGlobalPrefix::LeadingColon);
let display_bound = TypeParamBound::Trait(TraitBound {
paren_token: None,
modifier: TraitBoundModifier::None,
lifetimes: None,
path: display_path,
});
if !predicate_that_needs_a_display_impl.bounds.is_empty() {
predicate_that_needs_a_display_impl.bounds.push_punct(Plus {
spans: [Span::call_site()],
});
}
predicate_that_needs_a_display_impl
.bounds
.push_value(display_bound);
}
/// Map each declared generic type parameter to the set of all trait boundaries declared on it.
///
/// These boundaries may come from the declaration site:
/// pub enum E<T: MyTrait> { ... }
/// or a `where` clause after the parameter declarations:
/// pub enum E<T> where T: MyTrait { ... }
/// This method will return the boundaries from both of those cases.
fn extract_trait_constraints_from_source(
where_clause: &WhereClause,
type_params: &[&TypeParam],
) -> HashMap<Ident, Vec<TraitBound>> {
// Add trait bounds provided at the declaration site of type parameters for the struct/enum.
let mut param_constraint_mapping: HashMap<Ident, Vec<TraitBound>> = type_params
.iter()
.map(|type_param| {
let trait_bounds: Vec<TraitBound> = type_param
.bounds
.iter()
.flat_map(|bound| match bound {
TypeParamBound::Trait(trait_bound) => Some(trait_bound),
_ => None,
})
.cloned()
.collect();
(type_param.ident.clone(), trait_bounds)
})
.collect();
// Add trait bounds from `where` clauses, which may be type parameters or types containing
// those parameters.
for predicate in where_clause.predicates.iter() {
// We only care about type and not lifetime constraints here.
if let WherePredicate::Type(ref pred_ty) = predicate {
let ident = match &pred_ty.bounded_ty {
Type::Path(TypePath { path, qself: None }) => match path.get_ident() {
None => continue,
Some(ident) => ident,
},
_ => continue,
};
// We ignore any type constraints that aren't direct references to type
// parameters of the current enum of struct definition. No types can be
// constrained in a `where` clause unless they are a type parameter or a generic
// type instantiated with one of the type parameters, so by only allowing single
// identifiers, we can be sure that the constrained type is a type parameter
// that is contained in `param_constraint_mapping`.
if let Some((_, ref mut known_bounds)) = param_constraint_mapping
.iter_mut()
.find(|(id, _)| *id == ident)
{
for bound in pred_ty.bounds.iter() {
// We only care about trait bounds here.
if let TypeParamBound::Trait(ref bound) = bound {
known_bounds.push(bound.clone());
}
}
}
}
}
param_constraint_mapping
}
/// Hygienically add `where _: Display` to the set of [TypeParamBound]s for `ident`, creating such
/// a set if necessary.
fn ensure_display_in_where_clause_for_type(where_clause: &mut WhereClause, ident: Ident) {
for pred_ty in where_clause
.predicates
.iter_mut()
// Find the `where` predicate constraining the current type param, if it exists.
.flat_map(|predicate| match predicate {
WherePredicate::Type(pred_ty) => Some(pred_ty),
// We're looking through type constraints, not lifetime constraints.
_ => None,
})
{
// Do a complicated destructuring in order to check if the type being constrained in this
// `where` clause is the type we're looking for, so we can use the mutable reference to
// `pred_ty` if so.
let matches_desired_type = matches!(
&pred_ty.bounded_ty,
Type::Path(TypePath { path, .. }) if Some(&ident) == path.get_ident());
if matches_desired_type {
add_display_constraint_to_type_predicate(pred_ty);
return;
}
}
// If there is no `where` predicate for the current type param, we will construct one.
let mut new_type_predicate = new_empty_where_type_predicate(ident);
add_display_constraint_to_type_predicate(&mut new_type_predicate);
append_where_clause_type_predicate(where_clause, new_type_predicate);
}
/// For all declared type parameters, add a [core::fmt::Display] constraint, unless the type
/// parameter already has any type constraint.
fn ensure_where_clause_has_display_for_all_unconstrained_members(
where_clause: &mut WhereClause,
type_params: &[&TypeParam],
) {
let param_constraint_mapping = extract_trait_constraints_from_source(where_clause, type_params);
for (ident, known_bounds) in param_constraint_mapping.into_iter() {
// If the type parameter has any constraints already, we don't want to touch it, to avoid
// breaking use cases where a type parameter only needs to impl `Debug`, for example.
if known_bounds.is_empty() {
ensure_display_in_where_clause_for_type(where_clause, ident);
}
}
}
/// Generate a `where` clause that ensures all generic type parameters `impl`
/// [core::fmt::Display] unless already constrained.
///
/// This approach allows struct/enum definitions deriving [crate::Display] to avoid hardcoding
/// a [core::fmt::Display] constraint into every type parameter.
///
/// If the type parameter isn't already constrained, we add a `where _: Display` clause to our
/// display implementation to expect to be able to format every enum case or struct member.
///
/// In fact, we would preferably only require `where _: Display` or `where _: Debug` where the
/// format string actually requires it. However, while [`std::fmt` defines a formal syntax for
/// `format!()`][format syntax], it *doesn't* expose the actual logic to parse the format string,
/// which appears to live in [`rustc_parse_format`]. While we use the [`syn`] crate to parse rust
/// syntax, it also doesn't currently provide any method to introspect a `format!()` string. It
/// would be nice to contribute this upstream in [`syn`].
///
/// [format syntax]: std::fmt#syntax
/// [`rustc_parse_format`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_parse_format/index.html
fn generate_where_clause(generics: &Generics, where_clause: Option<&WhereClause>) -> WhereClause {
let mut where_clause = where_clause.cloned().unwrap_or_else(new_empty_where_clause);
let type_params: Vec<&TypeParam> = generics.type_params().collect();
ensure_where_clause_has_display_for_all_unconstrained_members(&mut where_clause, &type_params);
where_clause
}
fn impl_enum(input: &DeriveInput, data: &DataEnum) -> Result<TokenStream> {
let ty = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let where_clause = generate_where_clause(&input.generics, where_clause);
let helper = AttrsHelper::new(&input.attrs);
let displays = data
.variants
.iter()
.map(|variant| helper.display_with_input(&input.attrs, &variant.attrs))
.collect::<Result<Vec<_>>>()?;
if data.variants.is_empty() {
Ok(quote! {
impl #impl_generics ::core::fmt::Display for #ty #ty_generics #where_clause {
fn fmt(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
unreachable!("empty enums cannot be instantiated and thus cannot be printed")
}
}
})
} else if displays.iter().any(Option::is_some) {
let arms = data
.variants
.iter()
.zip(displays)
.map(|(variant, display)| {
let display =
display.ok_or_else(|| Error::new_spanned(variant, "missing doc comment"))?;
let ident = &variant.ident;
Ok(match &variant.fields {
Fields::Named(fields) => {
let var = fields.named.iter().map(|field| &field.ident);
quote!(Self::#ident { #(#var),* } => { #display })
}
Fields::Unnamed(fields) => {
let var = (0..fields.unnamed.len()).map(|i| format_ident!("_{}", i));
quote!(Self::#ident(#(#var),*) => { #display })
}
Fields::Unit => quote!(Self::#ident => { #display }),
})
})
.collect::<Result<Vec<_>>>()?;
Ok(quote! {
impl #impl_generics ::core::fmt::Display for #ty #ty_generics #where_clause {
fn fmt(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
#[allow(unused_variables)]
match self {
#(#arms,)*
}
}
}
})
} else {
Err(Error::new_spanned(input, "Missing doc comments"))
}
}

159
vendor/displaydoc/src/fmt.rs vendored Normal file
View File

@@ -0,0 +1,159 @@
use crate::attr::Display;
use proc_macro2::TokenStream;
use quote::quote_spanned;
use syn::{Ident, LitStr};
macro_rules! peek_next {
($read:ident) => {
match $read.chars().next() {
Some(next) => next,
None => return,
}
};
}
impl Display {
// Transform `"error {var}"` to `"error {}", var`.
pub(crate) fn expand_shorthand(&mut self) {
let span = self.fmt.span();
let fmt = self.fmt.value();
let mut read = fmt.as_str();
let mut out = String::new();
let mut args = TokenStream::new();
while let Some(brace) = read.find('{') {
out += &read[..=brace];
read = &read[brace + 1..];
// skip cases where we find a {{
if read.starts_with('{') {
out.push('{');
read = &read[1..];
continue;
}
let next = peek_next!(read);
let var = match next {
'0'..='9' => take_int(&mut read),
'a'..='z' | 'A'..='Z' | '_' => take_ident(&mut read),
_ => return,
};
let ident = Ident::new(&var, span);
let next = peek_next!(read);
let arg = if cfg!(feature = "std") && next == '}' {
quote_spanned!(span=> , #ident.__displaydoc_display())
} else {
quote_spanned!(span=> , #ident)
};
args.extend(arg);
}
out += read;
self.fmt = LitStr::new(&out, self.fmt.span());
self.args = args;
}
}
fn take_int(read: &mut &str) -> String {
let mut int = String::new();
int.push('_');
for (i, ch) in read.char_indices() {
match ch {
'0'..='9' => int.push(ch),
_ => {
*read = &read[i..];
break;
}
}
}
int
}
fn take_ident(read: &mut &str) -> String {
let mut ident = String::new();
for (i, ch) in read.char_indices() {
match ch {
'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => ident.push(ch),
_ => {
*read = &read[i..];
break;
}
}
}
ident
}
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
use proc_macro2::Span;
fn assert(input: &str, fmt: &str, args: &str) {
let mut display = Display {
fmt: LitStr::new(input, Span::call_site()),
args: TokenStream::new(),
};
display.expand_shorthand();
assert_eq!(fmt, display.fmt.value());
assert_eq!(args, display.args.to_string());
}
#[test]
fn test_expand() {
assert("fn main() {{ }}", "fn main() {{ }}", "");
}
#[test]
#[cfg_attr(not(feature = "std"), ignore)]
fn test_std_expand() {
assert(
"{v} {v:?} {0} {0:?}",
"{} {:?} {} {:?}",
", v . __displaydoc_display () , v , _0 . __displaydoc_display () , _0",
);
assert("error {var}", "error {}", ", var . __displaydoc_display ()");
assert(
"error {var1}",
"error {}",
", var1 . __displaydoc_display ()",
);
assert(
"error {var1var}",
"error {}",
", var1var . __displaydoc_display ()",
);
assert(
"The path {0}",
"The path {}",
", _0 . __displaydoc_display ()",
);
assert("The path {0:?}", "The path {:?}", ", _0");
}
#[test]
#[cfg_attr(feature = "std", ignore)]
fn test_nostd_expand() {
assert(
"{v} {v:?} {0} {0:?}",
"{} {:?} {} {:?}",
", v , v , _0 , _0",
);
assert("error {var}", "error {}", ", var");
assert("The path {0}", "The path {}", ", _0");
assert("The path {0:?}", "The path {:?}", ", _0");
assert("error {var1}", "error {}", ", var1");
assert("error {var1var}", "error {}", ", var1var");
}
}

186
vendor/displaydoc/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,186 @@
//! This library provides a convenient derive macro for the standard library's
//! [`core::fmt::Display`] trait.
//!
//! [`core::fmt::Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html
//!
//! ```toml
//! [dependencies]
//! displaydoc = "0.2"
//! ```
//!
//! *Compiler support: requires rustc 1.56+*
//!
//! <br>
//!
//! ## Example
//!
//! *Demonstration alongside the [`Error`][std::error::Error] derive macro from [`thiserror`](https://docs.rs/thiserror/1.0.25/thiserror/index.html),
//! to propagate source locations from [`io::Error`][std::io::Error] with the `#[source]` attribute:*
//! ```rust
//! use std::io;
//! use displaydoc::Display;
//! use thiserror::Error;
//!
//! #[derive(Display, Error, Debug)]
//! pub enum DataStoreError {
//! /// data store disconnected
//! Disconnect(#[source] io::Error),
//! /// the data for key `{0}` is not available
//! Redaction(String),
//! /// invalid header (expected {expected:?}, found {found:?})
//! InvalidHeader {
//! expected: String,
//! found: String,
//! },
//! /// unknown data store error
//! Unknown,
//! }
//!
//! let error = DataStoreError::Redaction("CLASSIFIED CONTENT".to_string());
//! assert!("the data for key `CLASSIFIED CONTENT` is not available" == &format!("{}", error));
//! ```
//! *Note that although [`io::Error`][std::io::Error] implements `Display`, we do not add it to the
//! generated message for `DataStoreError::Disconnect`, since it is already made available via
//! `#[source]`. See further context on avoiding duplication in error reports at the rust blog
//! [here](https://github.com/yaahc/blog.rust-lang.org/blob/master/posts/inside-rust/2021-05-15-What-the-error-handling-project-group-is-working-towards.md#duplicate-information-issue).*
//!
//! <br>
//!
//! ## Details
//!
//! - A `fmt::Display` impl is generated for your enum if you provide
//! a docstring comment on each variant as shown above in the example. The
//! `Display` derive macro supports a shorthand for interpolating fields from
//! the error:
//! - `/// {var}` ⟶ `write!("{}", self.var)`
//! - `/// {0}` ⟶ `write!("{}", self.0)`
//! - `/// {var:?}` ⟶ `write!("{:?}", self.var)`
//! - `/// {0:?}` ⟶ `write!("{:?}", self.0)`
//! - This also works with structs and [generic types][crate::Display#generic-type-parameters]:
//! ```rust
//! # use displaydoc::Display;
//! /// oh no, an error: {0}
//! #[derive(Display)]
//! pub struct Error<E>(pub E);
//!
//! let error: Error<&str> = Error("muahaha i am an error");
//! assert!("oh no, an error: muahaha i am an error" == &format!("{}", error));
//! ```
//!
//! - Two optional attributes can be added to your types next to the derive:
//!
//! - `#[ignore_extra_doc_attributes]` makes the macro ignore any doc
//! comment attributes (or `///` lines) after the first. Multi-line
//! comments using `///` are otherwise treated as an error, so use this
//! attribute or consider switching to block doc comments (`/** */`).
//!
//! - `#[prefix_enum_doc_attributes]` combines the doc comment message on
//! your enum itself with the messages for each variant, in the format
//! “enum: variant”. When added to an enum, the doc comment on the enum
//! becomes mandatory. When added to any other type, it has no effect.
//!
//! - In case you want to have an independent doc comment, the
//! `#[displaydoc("...")` atrribute may be used on the variant or struct to
//! override it.
//!
//! <br>
//!
//! ## FAQ
//!
//! 1. **Is this crate `no_std` compatible?**
//! * Yes! This crate implements the [`core::fmt::Display`] trait, not the [`std::fmt::Display`] trait, so it should work in `std` and `no_std` environments. Just add `default-features = false`.
//!
//! 2. **Does this crate work with `Path` and `PathBuf` via the `Display` trait?**
//! * Yuuup. This crate uses @dtolnay's [autoref specialization technique](https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md) to add a special trait for types to get the display impl. It then specializes for `Path` and `PathBuf`, and when either of these types are found, it calls `self.display()` to get a `std::path::Display<'_>` type which can be used with the `Display` format specifier!
#![doc(html_root_url = "https://docs.rs/displaydoc/0.2.3")]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(
rust_2018_idioms,
unreachable_pub,
bad_style,
dead_code,
improper_ctypes,
non_shorthand_field_patterns,
no_mangle_generic_items,
overflowing_literals,
path_statements,
patterns_in_fns_without_body,
unconditional_recursion,
unused,
unused_allocation,
unused_comparisons,
unused_parens,
while_true
)]
#![allow(clippy::try_err)]
#[allow(unused_extern_crates)]
extern crate proc_macro;
mod attr;
mod expand;
mod fmt;
use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput};
/// [Custom `#[derive(...)]` macro](https://doc.rust-lang.org/edition-guide/rust-2018/macros/custom-derive.html)
/// for implementing [`fmt::Display`][core::fmt::Display] via doc comment attributes.
///
/// ### Generic Type Parameters
///
/// Type parameters to an enum or struct using this macro should *not* need to
/// have an explicit `Display` constraint at the struct or enum definition
/// site. A `Display` implementation for the `derive`d struct or enum is
/// generated assuming each type parameter implements `Display`, but that should
/// be possible without adding the constraint to the struct definition itself:
/// ```rust
/// use displaydoc::Display;
///
/// /// oh no, an error: {0}
/// #[derive(Display)]
/// pub struct Error<E>(pub E);
///
/// // No need to require `E: Display`, since `displaydoc::Display` adds that implicitly.
/// fn generate_error<E>(e: E) -> Error<E> { Error(e) }
///
/// assert!("oh no, an error: muahaha" == &format!("{}", generate_error("muahaha")));
/// ```
///
/// ### Using [`Debug`][core::fmt::Debug] Implementations with Type Parameters
/// However, if a type parameter must instead be constrained with the
/// [`Debug`][core::fmt::Debug] trait so that some field may be printed with
/// `{:?}`, that constraint must currently still also be specified redundantly
/// at the struct or enum definition site. If a struct or enum field is being
/// formatted with `{:?}` via [`displaydoc`][crate], and a generic type
/// parameter must implement `Debug` to do that, then that struct or enum
/// definition will need to propagate the `Debug` constraint to every type
/// parameter it's instantiated with:
/// ```rust
/// use core::fmt::Debug;
/// use displaydoc::Display;
///
/// /// oh no, an error: {0:?}
/// #[derive(Display)]
/// pub struct Error<E: Debug>(pub E);
///
/// // `E: Debug` now has to propagate to callers.
/// fn generate_error<E: Debug>(e: E) -> Error<E> { Error(e) }
///
/// assert!("oh no, an error: \"cool\"" == &format!("{}", generate_error("cool")));
///
/// // Try this with a struct that doesn't impl `Display` at all, unlike `str`.
/// #[derive(Debug)]
/// pub struct Oh;
/// assert!("oh no, an error: Oh" == &format!("{}", generate_error(Oh)));
/// ```
#[proc_macro_derive(
Display,
attributes(ignore_extra_doc_attributes, prefix_enum_doc_attributes, displaydoc)
)]
pub fn derive_error(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
expand::derive(&input)
.unwrap_or_else(|err| err.to_compile_error())
.into()
}

View File

@@ -0,0 +1,29 @@
#[allow(unused_attributes)]
#[rustversion::attr(not(nightly), ignore)]
#[test]
fn no_std() {
let t = trybuild::TestCases::new();
#[cfg(not(feature = "std"))]
t.compile_fail("tests/no_std/without.rs");
#[cfg(not(feature = "std"))]
t.compile_fail("tests/no_std/multi_line.rs");
#[cfg(not(feature = "std"))]
t.pass("tests/no_std/multi_line_allow.rs");
#[cfg(not(feature = "std"))]
t.compile_fail("tests/no_std/enum_prefix_missing.rs");
#[cfg(not(feature = "std"))]
t.pass("tests/no_std/enum_prefix.rs");
#[cfg(feature = "std")]
t.compile_fail("tests/std/without.rs");
#[cfg(feature = "std")]
t.compile_fail("tests/std/multi_line.rs");
#[cfg(feature = "std")]
t.pass("tests/std/multi_line_allow.rs");
#[cfg(feature = "std")]
t.compile_fail("tests/std/enum_prefix_missing.rs");
#[cfg(feature = "std")]
t.pass("tests/std/enum_prefix.rs");
#[cfg(feature = "std")]
t.pass("tests/std/multiple.rs");
t.pass("tests/no_std/with.rs");
}

152
vendor/displaydoc/tests/happy.rs vendored Normal file
View File

@@ -0,0 +1,152 @@
use displaydoc::Display;
#[cfg(feature = "std")]
use std::path::PathBuf;
#[derive(Display)]
/// Just a basic struct {thing}
struct HappyStruct {
thing: &'static str,
}
#[derive(Display)]
#[ignore_extra_doc_attributes]
/// Just a basic struct {thing}
/// and this line should get ignored
struct HappyStruct2 {
thing: &'static str,
}
#[derive(Display)]
enum Happy {
/// I really like Variant1
Variant1,
/// Variant2 is pretty swell 2
Variant2,
/// Variant3 is okay {sometimes}
Variant3 { sometimes: &'static str },
/**
* Variant4 wants to have a lot of lines
*
* Lets see how this works out for it
*/
Variant4,
/// Variant5 has a parameter {0} and some regular comments
// A regular comment that won't get picked
Variant5(u32),
/// The path {0}
#[cfg(feature = "std")]
Variant6(PathBuf),
/// These docs are ignored
#[displaydoc("Variant7 has a parameter {0} and uses #[displaydoc]")]
/// These docs are also ignored
Variant7(u32),
}
// Used for testing indented doc comments
mod inner_mod {
use super::Display;
#[derive(Display)]
pub enum InnerHappy {
/// I really like Variant1
Variant1,
/// Variant2 is pretty swell 2
Variant2,
/// Variant3 is okay {sometimes}
Variant3 { sometimes: &'static str },
/**
* Variant4 wants to have a lot of lines
*
* Lets see how this works out for it
*/
Variant4,
/// Variant5 has a parameter {0} and some regular comments
// A regular comment that won't get picked
Variant5(u32),
/** what happens if we
* put text on the first line?
*/
Variant6,
/**
what happens if we don't use *?
*/
Variant7,
/**
*
* what about extra new lines?
*/
Variant8,
}
}
fn assert_display<T: std::fmt::Display>(input: T, expected: &'static str) {
let out = format!("{}", input);
assert_eq!(expected, out);
}
#[test]
fn does_it_print() {
assert_display(Happy::Variant1, "I really like Variant1");
assert_display(Happy::Variant2, "Variant2 is pretty swell 2");
assert_display(Happy::Variant3 { sometimes: "hi" }, "Variant3 is okay hi");
assert_display(
Happy::Variant4,
"Variant4 wants to have a lot of lines\n\nLets see how this works out for it",
);
assert_display(
Happy::Variant5(2),
"Variant5 has a parameter 2 and some regular comments",
);
assert_display(
Happy::Variant7(2),
"Variant7 has a parameter 2 and uses #[displaydoc]",
);
assert_display(HappyStruct { thing: "hi" }, "Just a basic struct hi");
assert_display(HappyStruct2 { thing: "hi2" }, "Just a basic struct hi2");
assert_display(inner_mod::InnerHappy::Variant1, "I really like Variant1");
assert_display(
inner_mod::InnerHappy::Variant2,
"Variant2 is pretty swell 2",
);
assert_display(
inner_mod::InnerHappy::Variant3 { sometimes: "hi" },
"Variant3 is okay hi",
);
assert_display(
inner_mod::InnerHappy::Variant4,
"Variant4 wants to have a lot of lines\n\nLets see how this works out for it",
);
assert_display(
inner_mod::InnerHappy::Variant5(2),
"Variant5 has a parameter 2 and some regular comments",
);
assert_display(
inner_mod::InnerHappy::Variant6,
"what happens if we\nput text on the first line?",
);
assert_display(
inner_mod::InnerHappy::Variant7,
"what happens if we don\'t use *?",
);
assert_display(
inner_mod::InnerHappy::Variant8,
"what about extra new lines?",
);
}
#[test]
#[cfg(feature = "std")]
fn does_it_print_path() {
assert_display(
Happy::Variant6(PathBuf::from("/var/log/happy")),
"The path /var/log/happy",
);
}

View File

@@ -0,0 +1,36 @@
#![cfg_attr(not(feature = "std"), allow(internal_features), feature(lang_items, start))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), start)]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
use displaydoc::Display;
/// this type is pretty swell
#[derive(Display)]
#[prefix_enum_doc_attributes]
enum TestType {
/// this variant is too
Variant1,
/// this variant is two
Variant2,
}
static_assertions::assert_impl_all!(TestType: core::fmt::Display);
#[cfg(feature = "std")]
fn main() {}

View File

@@ -0,0 +1,35 @@
#![cfg_attr(not(feature = "std"), allow(internal_features), feature(lang_items, start))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), start)]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
use displaydoc::Display;
#[derive(Display)]
#[prefix_enum_doc_attributes]
enum TestType {
/// this variant is too
Variant1,
/// this variant is two
Variant2,
}
static_assertions::assert_impl_all!(TestType: core::fmt::Display);
#[cfg(feature = "std")]
fn main() {}

View File

@@ -0,0 +1,22 @@
error: proc-macro derive panicked
--> $DIR/enum_prefix_missing.rs:22:10
|
22 | #[derive(Display)]
| ^^^^^^^
|
= help: message: Missing doc comment on enum with #[prefix_enum_doc_attributes]. Please remove the attribute or add a doc comment to the enum itself.
error[E0277]: `TestType` doesn't implement `Display`
--> $DIR/enum_prefix_missing.rs:32:37
|
32 | static_assertions::assert_impl_all!(TestType: core::fmt::Display);
| ^^^^^^^^ `TestType` cannot be formatted with the default formatter
|
= help: the trait `Display` is not implemented for `TestType`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `assert_impl_all`
--> $DIR/enum_prefix_missing.rs:32:1
|
32 | static_assertions::assert_impl_all!(TestType: core::fmt::Display);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,37 @@
#![cfg_attr(not(feature = "std"), allow(internal_features), feature(lang_items, start))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), start)]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
use displaydoc::Display;
/// this type is pretty swell
#[derive(Display)]
enum TestType {
/// This one is okay
Variant1,
/// Multi
/// line
/// doc.
Variant2,
}
static_assertions::assert_impl_all!(TestType: core::fmt::Display);
#[cfg(feature = "std")]
fn main() {}

View File

@@ -0,0 +1,22 @@
error: proc-macro derive panicked
--> $DIR/multi_line.rs:23:10
|
23 | #[derive(Display)]
| ^^^^^^^
|
= help: message: Multi-line comments are disabled by default by displaydoc. Please consider using block doc comments (/** */) or adding the #[ignore_extra_doc_attributes] attribute to your type next to the derive.
error[E0277]: `TestType` doesn't implement `Display`
--> $DIR/multi_line.rs:34:37
|
34 | static_assertions::assert_impl_all!(TestType: core::fmt::Display);
| ^^^^^^^^ `TestType` cannot be formatted with the default formatter
|
= help: the trait `Display` is not implemented for `TestType`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `assert_impl_all`
--> $DIR/multi_line.rs:34:1
|
34 | static_assertions::assert_impl_all!(TestType: core::fmt::Display);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,38 @@
#![cfg_attr(not(feature = "std"), allow(internal_features), feature(lang_items, start))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), start)]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
use displaydoc::Display;
/// this type is pretty swell
#[derive(Display)]
#[ignore_extra_doc_attributes]
enum TestType {
/// This one is okay
Variant1,
/// Multi
/// line
/// doc.
Variant2,
}
static_assertions::assert_impl_all!(TestType: core::fmt::Display);
#[cfg(feature = "std")]
fn main() {}

32
vendor/displaydoc/tests/no_std/with.rs vendored Normal file
View File

@@ -0,0 +1,32 @@
#![feature(lang_items, start)]
#![no_std]
#[start]
#[cfg(not(feature = "std"))]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
#[cfg(feature = "std")]
fn main() {}
use displaydoc::Display;
/// this type is pretty swell
#[derive(Display)]
struct FakeType;
static_assertions::assert_impl_all!(FakeType: core::fmt::Display);

View File

@@ -0,0 +1,28 @@
#![cfg_attr(not(feature = "std"), allow(internal_features), feature(lang_items, start))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), start)]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
use displaydoc::Display;
/// this type is pretty swell
struct FakeType;
static_assertions::assert_impl_all!(FakeType: core::fmt::Display);
#[cfg(feature = "std")]
fn main() {}

View File

@@ -0,0 +1,22 @@
warning: unused import: `displaydoc::Display`
--> $DIR/without.rs:20:5
|
20 | use displaydoc::Display;
| ^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0277]: `FakeType` doesn't implement `Display`
--> $DIR/without.rs:25:37
|
25 | static_assertions::assert_impl_all!(FakeType: core::fmt::Display);
| ^^^^^^^^ `FakeType` cannot be formatted with the default formatter
|
= help: the trait `Display` is not implemented for `FakeType`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `assert_impl_all`
--> $DIR/without.rs:25:1
|
25 | static_assertions::assert_impl_all!(FakeType: core::fmt::Display);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

22
vendor/displaydoc/tests/num_in_field.rs vendored Normal file
View File

@@ -0,0 +1,22 @@
/// {foo1} {foo2}
#[derive(displaydoc::Display)]
pub struct Test {
foo1: String,
foo2: String,
}
fn assert_display<T: std::fmt::Display>(input: T, expected: &'static str) {
let out = format!("{}", input);
assert_eq!(expected, out);
}
#[test]
fn does_it_print() {
assert_display(
Test {
foo1: "hi".into(),
foo2: "hello".into(),
},
"hi hello",
);
}

View File

@@ -0,0 +1,36 @@
#![cfg_attr(not(feature = "std"), feature(lang_items, start))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), start)]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
use displaydoc::Display;
/// this type is pretty swell
#[derive(Display)]
#[prefix_enum_doc_attributes]
enum TestType {
/// this variant is too
Variant1,
/// this variant is two
Variant2,
}
static_assertions::assert_impl_all!(TestType: core::fmt::Display);
#[cfg(feature = "std")]
fn main() {}

View File

@@ -0,0 +1,35 @@
#![cfg_attr(not(feature = "std"), feature(lang_items, start))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), start)]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
use displaydoc::Display;
#[derive(Display)]
#[prefix_enum_doc_attributes]
enum TestType {
/// this variant is too
Variant1,
/// this variant is two
Variant2,
}
static_assertions::assert_impl_all!(TestType: core::fmt::Display);
#[cfg(feature = "std")]
fn main() {}

View File

@@ -0,0 +1,22 @@
error: proc-macro derive panicked
--> $DIR/enum_prefix_missing.rs:22:10
|
22 | #[derive(Display)]
| ^^^^^^^
|
= help: message: Missing doc comment on enum with #[prefix_enum_doc_attributes]. Please remove the attribute or add a doc comment to the enum itself.
error[E0277]: `TestType` doesn't implement `std::fmt::Display`
--> $DIR/enum_prefix_missing.rs:32:37
|
32 | static_assertions::assert_impl_all!(TestType: core::fmt::Display);
| ^^^^^^^^ `TestType` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `TestType`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `assert_impl_all`
--> $DIR/enum_prefix_missing.rs:32:1
|
32 | static_assertions::assert_impl_all!(TestType: core::fmt::Display);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,37 @@
#![cfg_attr(not(feature = "std"), allow(internal_features), feature(lang_items, start))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), start)]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
use displaydoc::Display;
/// this type is pretty swell
#[derive(Display)]
enum TestType {
/// This one is okay
Variant1,
/// Multi
/// line
/// doc.
Variant2,
}
static_assertions::assert_impl_all!(TestType: core::fmt::Display);
#[cfg(feature = "std")]
fn main() {}

View File

@@ -0,0 +1,22 @@
error: proc-macro derive panicked
--> $DIR/multi_line.rs:23:10
|
23 | #[derive(Display)]
| ^^^^^^^
|
= help: message: Multi-line comments are disabled by default by displaydoc. Please consider using block doc comments (/** */) or adding the #[ignore_extra_doc_attributes] attribute to your type next to the derive.
error[E0277]: `TestType` doesn't implement `std::fmt::Display`
--> $DIR/multi_line.rs:34:37
|
34 | static_assertions::assert_impl_all!(TestType: core::fmt::Display);
| ^^^^^^^^ `TestType` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `TestType`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `assert_impl_all`
--> $DIR/multi_line.rs:34:1
|
34 | static_assertions::assert_impl_all!(TestType: core::fmt::Display);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,38 @@
#![cfg_attr(not(feature = "std"), feature(lang_items, start))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), start)]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
use displaydoc::Display;
/// this type is pretty swell
#[derive(Display)]
#[ignore_extra_doc_attributes]
enum TestType {
/// This one is okay
Variant1,
/// Multi
/// line
/// doc.
Variant2,
}
static_assertions::assert_impl_all!(TestType: core::fmt::Display);
#[cfg(feature = "std")]
fn main() {}

38
vendor/displaydoc/tests/std/multiple.rs vendored Normal file
View File

@@ -0,0 +1,38 @@
#![feature(lang_items, start)]
#![no_std]
#[start]
#[cfg(not(feature = "std"))]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
#[cfg(feature = "std")]
fn main() {}
use displaydoc::Display;
/// this type is pretty swell
#[derive(Display)]
struct FakeType;
static_assertions::assert_impl_all!(FakeType: core::fmt::Display);
/// this type is pretty swell2
#[derive(Display)]
struct FakeType2;
static_assertions::assert_impl_all!(FakeType2: core::fmt::Display);

28
vendor/displaydoc/tests/std/without.rs vendored Normal file
View File

@@ -0,0 +1,28 @@
#![cfg_attr(not(feature = "std"), allow(internal_features), feature(lang_items, start))]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg_attr(not(feature = "std"), start)]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
#[cfg(not(feature = "std"))]
pub extern "C" fn rust_eh_personality() {}
#[panic_handler]
#[cfg(not(feature = "std"))]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
}
use displaydoc::Display;
/// this type is pretty swell
struct FakeType;
static_assertions::assert_impl_all!(FakeType: core::fmt::Display);
#[cfg(feature = "std")]
fn main() {}

View File

@@ -0,0 +1,22 @@
warning: unused import: `displaydoc::Display`
--> $DIR/without.rs:20:5
|
20 | use displaydoc::Display;
| ^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0277]: `FakeType` doesn't implement `std::fmt::Display`
--> $DIR/without.rs:25:37
|
25 | static_assertions::assert_impl_all!(FakeType: core::fmt::Display);
| ^^^^^^^^ `FakeType` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `FakeType`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `assert_impl_all`
--> $DIR/without.rs:25:1
|
25 | static_assertions::assert_impl_all!(FakeType: core::fmt::Display);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the macro `static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,6 @@
use displaydoc::Display;
#[derive(Display)]
enum EmptyInside {}
static_assertions::assert_impl_all!(EmptyInside: core::fmt::Display);

5
vendor/displaydoc/update-readme.sh vendored Executable file
View File

@@ -0,0 +1,5 @@
#! /usr/bin/env bash
cargo readme > ./README.md
git add ./README.md
git commit -m "Update readme" || true