Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/eyre/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/eyre/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"CHANGELOG.md":"b980ff14aa7e728c69b6966f68ade64cd6259b89d6b61a099bfd0dd47960990b","Cargo.lock":"4e4e145371cef95fe347e7b14731fbf8f8aef366f45eb45f37760892a966e35b","Cargo.toml":"ad05a3833cfb3693e44c8341e23a85bd88d9578833193341b1b016cdbf99b8fd","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"d6083c077bb087914386be267b52b98bca521f9af5b40b7fd82960d3ae2d2e3a","build.rs":"fbd0d04cc64884da6b65ad460084ad49e56f8a14fba24a256e161cb18b15441c","examples/custom_handler.rs":"33fa83c1ac4a6af8511796cc3b4818d4d4a50fa5eac5b9533a91acd695337169","examples/eyre-usage.rs":"3380d5176d433209eadeb355c2884fd0d46dc6a636b7402fab8fae17f79fa6c0","src/backtrace.rs":"02e509dd794ee2814b1342879414373935bcc33b433e45a58193297e52f95db7","src/chain.rs":"342161434eaa3db018541a24e01531135b471dfac44f7d25c84875c4dc5692d1","src/context.rs":"97f5c3fbe0679db8203ba5983817124df0d888d39e4fc8a55f33f568b4c536e0","src/error.rs":"b2395cb008713ec5112d332c81d0edc293a71bb992dc0d1a42db67ec5301dc10","src/error/pyo3_compat.rs":"6a3b48211b5496944aac8e058cbca85d37f379b3fc18b57c5e00ce56832d47bc","src/fmt.rs":"101f0fc55eba79900dafe04874f2b8f144d5da884b2087b77cda9fc1588d4d8c","src/kind.rs":"12aa656231f87f33367ac1db011dee70f87adff119305cf9d40faf3140234436","src/lib.rs":"32812e58622ad0d0fcc862163fda9c0f13497bc38df5cdd214f04d78a6d069e6","src/macros.rs":"22f30ae6fa6c130db4fa15913caf690cb33429e69cbf9f6371db586f1e0a5002","src/option.rs":"06271311605414d5f850efdf61a8c6976730f90cb03dc0712faa53f051a34509","src/ptr.rs":"81c21f61e9063db1eea3152ced7f01dd02d78ec64d09bf7f8ea0936e1d9772ad","src/wrapper.rs":"1d92365de5b679cc8bd328895724e6f7283e48ebf826bdbfac594813b2f96243","tests/common/mod.rs":"8094c30a551b8d4b04b474e5d4094bfd56f714fd51a8e2f4636eb823c5d08b1c","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/drop/mod.rs":"bd6d59b699a2901de2bda3c40c899af4ee82e4e98617516ea41c327b99af51e1","tests/test_autotrait.rs":"18b0c73026e9bbbc5272e8ed832ccb2522a606b64d50c80316495013f6acc808","tests/test_boxed.rs":"badf6e661aa3076ca644f6c0275991c8d26c5d3684bb2cb260ca2f58482594e8","tests/test_chain.rs":"8c7a75e38d241e9931a3530b30fab80ef87488daeecf87c84f72069d34650188","tests/test_context.rs":"816bdfa55f2fda0abde014817e46227a2da3effa0f697cfa5d2ca218650b946e","tests/test_context_access.rs":"dc490cfc031ac3907314a578c9bb9dfa51be95b041a62f771e39b79d66b763d3","tests/test_convert.rs":"300644b4ebf0cb94b542f6e306779199bc7fce7cc7bec956a1156767d847ae44","tests/test_downcast.rs":"4172648f5f48d489fe5b2e0e962dc2c35624eef5f907192db63f11493a396008","tests/test_fmt.rs":"a1ed4b79bea5f04006868d5145980ea6936d2eb4feee4b87e2c675d4f0b465ff","tests/test_location.rs":"79725e31e961df162b6e1f1194e7a0e5f45740bbeb7700293c2880360050ae28","tests/test_macros.rs":"bd1577f801a24abfb2870de9af9a9224a49025cbc8227a3b237bc73669592ba7","tests/test_no_install.rs":"9b4d695d9c699d5c39c7c4fd178b30fe472e96efbf2e8e4448ce72d6f2b3101b","tests/test_option.rs":"ae49e0b486f35bcd485765b1f6ebd0e02173b574b11c279c5597caf2f84f8c71","tests/test_pyo3.rs":"a1006f46d317e9e7a0c7c57f3502b9af594b62cb717269fee220f175d9ba5f17","tests/test_repr.rs":"a105eba1500a0bd7e36895bf03d43e2c9dbb6c573a0051c80f7ea7bdac103f78","tests/test_source.rs":"7d3cc674b802e46f84230db2e72b9a66b3bff39ae8d0246ab31607a8e6c01f27","tests/test_toolchain.rs":"96f9aacc8d9fe33d6e1d90a8f329d54d7ad5880348c64a87894ca916321c8c10"},"package":"7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"}
|
||||
91
third-party/vendor/eyre/CHANGELOG.md
vendored
Normal file
91
third-party/vendor/eyre/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
# 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.6.12] - 2024-01-31
|
||||
### Fixed
|
||||
- Unsound cast to invalid type during Report downcast [by ten3roberts](https://github.com/eyre-rs/eyre/pull/143)
|
||||
|
||||
## [0.6.11] - 2023-12-13
|
||||
### Fixed
|
||||
- stale references to `Error` in docstrings [by birkenfeld](https://github.com/eyre-rs/eyre/pull/87)
|
||||
|
||||
### Added
|
||||
- one-argument ensure!($expr) [by sharnoff](https://github.com/eyre-rs/eyre/pull/86)
|
||||
- documentation on the performance characteristics of `wrap_err` vs `wrap_err_with` [by akshayknarayan](https://github.com/eyre-rs/eyre/pull/93)
|
||||
- tl;dr: `wrap_err_with` is faster unless the constructed error object already exists
|
||||
- ~~automated conversion to external errors for ensure! and bail! [by j-baker](https://github.com/eyre-rs/eyre/pull/95)~~ breaking change: shelved for next major release
|
||||
- eyre::Ok for generating eyre::Ok() without fully specifying the type [by kylewlacy](https://github.com/eyre-rs/eyre/pull/91)
|
||||
- `OptionExt::ok_or_eyre` for yielding static `Report`s from `None` [by LeoniePhiline](https://github.com/eyre-rs/eyre/pull/125)
|
||||
|
||||
### New Contributors
|
||||
- @sharnoff made their first contribution in https://github.com/eyre-rs/eyre/pull/86
|
||||
- @akshayknarayan made their first contribution in https://github.com/eyre-rs/eyre/pull/93
|
||||
- @j-baker made their first contribution in https://github.com/eyre-rs/eyre/pull/95
|
||||
- @kylewlacy made their first contribution in https://github.com/eyre-rs/eyre/pull/91
|
||||
- @LeoniePhiline made their first contribution in https://github.com/eyre-rs/eyre/pull/129
|
||||
|
||||
~~## [0.6.10] - 2023-12-07~~ Yanked
|
||||
|
||||
## [0.6.9] - 2023-11-17
|
||||
### Fixed
|
||||
- stacked borrows when dropping [by TimDiekmann](https://github.com/eyre-rs/eyre/pull/81)
|
||||
- miri validation errors through now stricter provenance [by ten3roberts](https://github.com/eyre-rs/eyre/pull/103)
|
||||
- documentation on no_std support [by thenorili](https://github.com/eyre-rs/eyre/pull/111)
|
||||
|
||||
### Added
|
||||
- monorepo for eyre-related crates [by pksunkara](https://github.com/eyre-rs/eyre/pull/104), [[2]](https://github.com/eyre-rs/eyre/pull/105)[[3]](https://github.com/eyre-rs/eyre/pull/107)
|
||||
- CONTRIBUTING.md [by yaahc](https://github.com/eyre-rs/eyre/pull/99)
|
||||
|
||||
## [0.6.8] - 2022-04-04
|
||||
### Added
|
||||
- `#[must_use]` to `Report`
|
||||
- `must-install` feature to help reduce binary sizes when using a custom `EyreHandler`
|
||||
|
||||
## [0.6.7] - 2022-02-24
|
||||
### Fixed
|
||||
- missing track_caller annotation to new format arg capture constructor
|
||||
|
||||
## [0.6.6] - 2022-01-19
|
||||
### Added
|
||||
- support for format arguments capture on 1.58 and later
|
||||
|
||||
## [0.6.5] - 2021-01-05
|
||||
### Added
|
||||
- optional support for converting into `pyo3` exceptions
|
||||
|
||||
## [0.6.4] - 2021-01-04
|
||||
### Fixed
|
||||
- missing track_caller annotations to `wrap_err` related trait methods
|
||||
|
||||
## [0.6.3] - 2020-11-10
|
||||
### Fixed
|
||||
- missing track_caller annotation to autoref specialization functions
|
||||
|
||||
## [0.6.2] - 2020-10-27
|
||||
### Fixed
|
||||
- missing track_caller annotation to new_adhoc function
|
||||
|
||||
## [0.6.1] - 2020-09-28
|
||||
### Added
|
||||
- support for track_caller on rust versions where it is available
|
||||
|
||||
|
||||
<!-- next-url -->
|
||||
[Unreleased]: https://github.com/eyre-rs/eyre/compare/v0.6.11...HEAD
|
||||
[0.6.11]: https://github.com/eyre-rs/eyre/compare/v0.6.9...v0.6.11
|
||||
[0.6.9]: https://github.com/eyre-rs/eyre/compare/v0.6.8...v0.6.9
|
||||
[0.6.8]: https://github.com/eyre-rs/eyre/compare/v0.6.7...v0.6.8
|
||||
[0.6.7]: https://github.com/eyre-rs/eyre/compare/v0.6.6...v0.6.7
|
||||
[0.6.6]: https://github.com/eyre-rs/eyre/compare/v0.6.5...v0.6.6
|
||||
[0.6.5]: https://github.com/eyre-rs/eyre/compare/v0.6.4...v0.6.5
|
||||
[0.6.4]: https://github.com/eyre-rs/eyre/compare/v0.6.3...v0.6.4
|
||||
[0.6.3]: https://github.com/eyre-rs/eyre/compare/v0.6.2...v0.6.3
|
||||
[0.6.2]: https://github.com/eyre-rs/eyre/compare/v0.6.1...v0.6.2
|
||||
[0.6.1]: https://github.com/eyre-rs/eyre/releases/tag/v0.6.1
|
||||
504
third-party/vendor/eyre/Cargo.lock
generated
vendored
Normal file
504
third-party/vendor/eyre/Cargo.lock
generated
vendored
Normal file
|
|
@ -0,0 +1,504 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "basic-toml"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f2139706359229bfa8f19142ac1155b4b80beafb7a60471ac5dd109d4a19778"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "dissimilar"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632"
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.12"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"backtrace",
|
||||
"futures",
|
||||
"indenter",
|
||||
"once_cell",
|
||||
"pyo3",
|
||||
"rustversion",
|
||||
"syn",
|
||||
"thiserror",
|
||||
"trybuild",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "indenter"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.150"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
|
||||
dependencies = [
|
||||
"instant",
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04e8453b658fe480c3e70c8ed4e3d3ec33eb74988bd186561b0cc66b85c3bc4b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset",
|
||||
"parking_lot",
|
||||
"pyo3-build-config",
|
||||
"pyo3-ffi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a96fe70b176a89cff78f2fa7b3c930081e163d5379b4dcdf993e3ae29ca662e5"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-ffi"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "214929900fd25e6604661ed9cf349727c8920d47deff196c4e28165a6ef2a96b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pyo3-build-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.193"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a"
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trybuild"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "196a58260a906cedb9bf6d8034b6379d0c11f552416960452f267402ceeddff1"
|
||||
dependencies = [
|
||||
"basic-toml",
|
||||
"dissimilar",
|
||||
"glob",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[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.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
84
third-party/vendor/eyre/Cargo.toml
vendored
Normal file
84
third-party/vendor/eyre/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
# 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 = "2018"
|
||||
rust-version = "1.65.0"
|
||||
name = "eyre"
|
||||
version = "0.6.12"
|
||||
authors = [
|
||||
"David Tolnay <dtolnay@gmail.com>",
|
||||
"Jane Lusby <jlusby42@gmail.com>",
|
||||
]
|
||||
description = "Flexible concrete Error Reporting type built on std::error::Error with customizable Reports"
|
||||
documentation = "https://docs.rs/eyre"
|
||||
readme = "README.md"
|
||||
categories = ["rust-patterns"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/eyre-rs/eyre"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"doc_cfg",
|
||||
]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[package.metadata.workspaces]
|
||||
independent = true
|
||||
|
||||
[dependencies.indenter]
|
||||
version = "0.3.0"
|
||||
|
||||
[dependencies.once_cell]
|
||||
version = "1.18.0"
|
||||
|
||||
[dependencies.pyo3]
|
||||
version = "0.20"
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.anyhow]
|
||||
version = "1.0.28"
|
||||
|
||||
[dev-dependencies.backtrace]
|
||||
version = "0.3.46"
|
||||
|
||||
[dev-dependencies.futures]
|
||||
version = "0.3"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.pyo3]
|
||||
version = "0.20"
|
||||
features = ["auto-initialize"]
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.rustversion]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.syn]
|
||||
version = "2.0"
|
||||
features = ["full"]
|
||||
|
||||
[dev-dependencies.thiserror]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.trybuild]
|
||||
version = "1.0.19"
|
||||
features = ["diff"]
|
||||
|
||||
[features]
|
||||
auto-install = []
|
||||
default = [
|
||||
"auto-install",
|
||||
"track-caller",
|
||||
]
|
||||
track-caller = []
|
||||
201
third-party/vendor/eyre/LICENSE-APACHE
vendored
Normal file
201
third-party/vendor/eyre/LICENSE-APACHE
vendored
Normal 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
third-party/vendor/eyre/LICENSE-MIT
vendored
Normal file
23
third-party/vendor/eyre/LICENSE-MIT
vendored
Normal 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.
|
||||
269
third-party/vendor/eyre/README.md
vendored
Normal file
269
third-party/vendor/eyre/README.md
vendored
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
eyre
|
||||
====
|
||||
|
||||
[![Build Status][actions-badge]][actions-url]
|
||||
[](https://crates.io/crates/eyre)
|
||||
[](https://docs.rs/eyre)
|
||||
[![Discord chat][discord-badge]][discord-url]
|
||||
|
||||
[actions-badge]: https://github.com/eyre-rs/eyre/workflows/Continuous%20integration/badge.svg
|
||||
[actions-url]: https://github.com/eyre-rs/eyre/actions?query=workflow%3A%22Continuous+integration%22
|
||||
[discord-badge]: https://img.shields.io/discord/960645145018110012?label=eyre%20community%20discord
|
||||
[discord-url]: https://discord.gg/z94RqmUTKB
|
||||
|
||||
This library provides [`eyre::Report`][Report], a trait object based
|
||||
error handling type for easy idiomatic error handling and reporting in Rust
|
||||
applications.
|
||||
|
||||
This crate is a fork of [`anyhow`] with support for customized
|
||||
error reports. For more details on customization checkout the docs on
|
||||
[`eyre::EyreHandler`].
|
||||
|
||||
## Custom Report Handlers
|
||||
|
||||
The heart of this crate is its ability to swap out the Handler type to change
|
||||
what information is carried alongside errors and how the end report is
|
||||
formatted. This crate is meant to be used alongside companion crates that
|
||||
customize its behavior. Below is a list of known crates that export report
|
||||
handlers for eyre and short summaries of what features they provide.
|
||||
|
||||
- [`stable-eyre`]: Switches the backtrace type from `std`'s to `backtrace-rs`'s
|
||||
so that it can be captured on stable. The report format is identical to
|
||||
`DefaultHandler`'s report format.
|
||||
- [`color-eyre`]: Captures a `backtrace::Backtrace` and a
|
||||
`tracing_error::SpanTrace`. Provides a `Help` trait for attaching warnings
|
||||
and suggestions to error reports. The end report is then pretty printed with
|
||||
the help of [`color-backtrace`], [`color-spantrace`], and `ansi_term`. Check
|
||||
out the README on [`color-eyre`] for details on the report format.
|
||||
- [`simple-eyre`]: A minimal `EyreHandler` that captures no additional
|
||||
information, for when you do not wish to capture `Backtrace`s with errors.
|
||||
- [`jane-eyre`]: A report handler crate that exists purely for the pun of it.
|
||||
Currently just re-exports `color-eyre`.
|
||||
|
||||
## Usage Recommendations and Stability Considerations
|
||||
|
||||
**We recommend users do not re-export types from this library as part their own
|
||||
public API for libraries with external users.** The main reason for this is
|
||||
that it will make your library API break if we ever bump the major version
|
||||
number on eyre and your users upgrade the eyre version they use in their
|
||||
application code before you upgrade your own eyre dep version[^1].
|
||||
|
||||
However, even beyond this API stability hazard, there are other good reasons to
|
||||
avoid using `eyre::Report` as your public error type.
|
||||
|
||||
- You export an undocumented error interface that is otherwise still accessible
|
||||
via downcast, making it hard for users to react to specific errors while not
|
||||
preventing them from depending on details you didn't mean to make part of
|
||||
your public API.
|
||||
- This in turn makes the error types of all libraries you use a part of your
|
||||
public API as well, and makes changing any of those libraries into an
|
||||
undetectable runtime breakage.
|
||||
- If many of your errors are constructed from strings you encourage your users
|
||||
to use string comparision for reacting to specific errors which is brittle
|
||||
and turns updating error messages into a potentially undetectable runtime
|
||||
breakage.
|
||||
|
||||
## Details
|
||||
|
||||
- Use `Result<T, eyre::Report>`, or equivalently `eyre::Result<T>`, as the
|
||||
return type of any fallible function.
|
||||
|
||||
Within the function, use `?` to easily propagate any error that implements the
|
||||
`std::error::Error` trait.
|
||||
|
||||
```rust
|
||||
use eyre::Result;
|
||||
|
||||
fn get_cluster_info() -> Result<ClusterMap> {
|
||||
let config = std::fs::read_to_string("cluster.json")?;
|
||||
let map: ClusterMap = serde_json::from_str(&config)?;
|
||||
Ok(map)
|
||||
}
|
||||
```
|
||||
|
||||
- Wrap a lower level error with a new error created from a message to help the
|
||||
person troubleshooting understand the chain of failures that occurred. A
|
||||
low-level error like "No such file or directory" can be annoying to debug
|
||||
without more information about what higher level step the application was in
|
||||
the middle of.
|
||||
|
||||
```rust
|
||||
use eyre::{WrapErr, Result};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
...
|
||||
it.detach().wrap_err("Failed to detach the important thing")?;
|
||||
|
||||
let content = std::fs::read(path)
|
||||
.wrap_err_with(|| format!("Failed to read instrs from {}", path))?;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
```console
|
||||
Error: Failed to read instrs from ./path/to/instrs.json
|
||||
|
||||
Caused by:
|
||||
No such file or directory (os error 2)
|
||||
```
|
||||
|
||||
- Downcasting is supported and can be by value, by shared reference, or by
|
||||
mutable reference as needed.
|
||||
|
||||
```rust
|
||||
// If the error was caused by redaction, then return a
|
||||
// tombstone instead of the content.
|
||||
match root_cause.downcast_ref::<DataStoreError>() {
|
||||
Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
|
||||
None => Err(error),
|
||||
}
|
||||
```
|
||||
|
||||
- If using the nightly channel, a backtrace is captured and printed with the
|
||||
error if the underlying error type does not already provide its own. In order
|
||||
to see backtraces, they must be enabled through the environment variables
|
||||
described in [`std::backtrace`]:
|
||||
|
||||
- If you want panics and errors to both have backtraces, set
|
||||
`RUST_BACKTRACE=1`;
|
||||
- If you want only errors to have backtraces, set `RUST_LIB_BACKTRACE=1`;
|
||||
- If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
|
||||
`RUST_LIB_BACKTRACE=0`.
|
||||
|
||||
The tracking issue for this feature is [rust-lang/rust#53487].
|
||||
|
||||
[`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables
|
||||
[rust-lang/rust#53487]: https://github.com/rust-lang/rust/issues/53487
|
||||
|
||||
- Eyre works with any error type that has an impl of `std::error::Error`,
|
||||
including ones defined in your crate. We do not bundle a `derive(Error)` macro
|
||||
but you can write the impls yourself or use a standalone macro like
|
||||
[thiserror].
|
||||
|
||||
```rust
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum FormatError {
|
||||
#[error("Invalid header (expected {expected:?}, got {found:?})")]
|
||||
InvalidHeader {
|
||||
expected: String,
|
||||
found: String,
|
||||
},
|
||||
#[error("Missing attribute: {0}")]
|
||||
MissingAttribute(String),
|
||||
}
|
||||
```
|
||||
|
||||
- One-off error messages can be constructed using the `eyre!` macro, which
|
||||
supports string interpolation and produces an `eyre::Report`.
|
||||
|
||||
```rust
|
||||
return Err(eyre!("Missing attribute: {}", missing));
|
||||
```
|
||||
|
||||
- On newer versions of the compiler (e.g. 1.58 and later) this macro also
|
||||
supports format args captures.
|
||||
|
||||
```rust
|
||||
return Err(eyre!("Missing attribute: {missing}"));
|
||||
```
|
||||
|
||||
## No-std support
|
||||
|
||||
No-std support was removed in 2020 in [commit 608a16a] due to unaddressed upstream breakages.
|
||||
[commit 608a16a]:
|
||||
https://github.com/eyre-rs/eyre/pull/29/commits/608a16aa2c2c27eca6c88001cc94c6973c18f1d5
|
||||
|
||||
## Comparison to failure
|
||||
|
||||
The `eyre::Report` type works something like `failure::Error`, but unlike
|
||||
failure ours is built around the standard library's `std::error::Error` trait
|
||||
rather than a separate trait `failure::Fail`. The standard library has adopted
|
||||
the necessary improvements for this to be possible as part of [RFC 2504].
|
||||
|
||||
[RFC 2504]: https://github.com/rust-lang/rfcs/blob/master/text/2504-fix-error.md
|
||||
|
||||
## Comparison to thiserror
|
||||
|
||||
Use `eyre` if you don't think you'll do anything with an error other than
|
||||
report it. This is common in application code. Use `thiserror` if you think
|
||||
you need an error type that can be handled via match or reported. This is
|
||||
common in library crates where you don't know how your users will handle
|
||||
your errors.
|
||||
|
||||
[thiserror]: https://github.com/dtolnay/thiserror
|
||||
|
||||
## Compatibility with `anyhow`
|
||||
|
||||
This crate does its best to be usable as a drop in replacement of `anyhow` and
|
||||
vice-versa by `re-exporting` all of the renamed APIs with the names used in
|
||||
`anyhow`, though there are some differences still.
|
||||
|
||||
#### `Context` and `Option`
|
||||
|
||||
As part of renaming `Context` to `WrapErr` we also intentionally do not
|
||||
implement `WrapErr` for `Option`. This decision was made because `wrap_err`
|
||||
implies that you're creating a new error that saves the old error as its
|
||||
`source`. With `Option` there is no source error to wrap, so `wrap_err` ends up
|
||||
being somewhat meaningless.
|
||||
|
||||
Instead `eyre` offers [`OptionExt::ok_or_eyre`] to yield _static_ errors from `None`,
|
||||
and intends for users to use the combinator functions provided by
|
||||
`std`, converting `Option`s to `Result`s, for _dynamic_ errors.
|
||||
So where you would write this with
|
||||
anyhow:
|
||||
|
||||
[`OptionExt::ok_or_eyre`]: https://docs.rs/eyre/latest/eyre/trait.OptionExt.html#tymethod.ok_or_eyre
|
||||
|
||||
```rust
|
||||
use anyhow::Context;
|
||||
|
||||
let opt: Option<()> = None;
|
||||
let result_static = opt.context("static error message");
|
||||
let result_dynamic = opt.with_context(|| format!("{} error message", "dynamic"));
|
||||
```
|
||||
|
||||
With `eyre` we want users to write:
|
||||
|
||||
```rust
|
||||
use eyre::{eyre, OptionExt, Result};
|
||||
|
||||
let opt: Option<()> = None;
|
||||
let result_static: Result<()> = opt.ok_or_eyre("static error message");
|
||||
let result_dynamic: Result<()> = opt.ok_or_else(|| eyre!("{} error message", "dynamic"));
|
||||
```
|
||||
|
||||
**NOTE**: However, to help with porting we do provide a `ContextCompat` trait which
|
||||
implements `context` for options which you can import to make existing
|
||||
`.context` calls compile.
|
||||
|
||||
[Report]: https://docs.rs/eyre/*/eyre/struct.Report.html
|
||||
[`eyre::EyreHandler`]: https://docs.rs/eyre/*/eyre/trait.EyreHandler.html
|
||||
[`eyre::WrapErr`]: https://docs.rs/eyre/*/eyre/trait.WrapErr.html
|
||||
[`anyhow::Context`]: https://docs.rs/anyhow/*/anyhow/trait.Context.html
|
||||
[`anyhow`]: https://github.com/dtolnay/anyhow
|
||||
[`tracing_error::SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html
|
||||
[`stable-eyre`]: https://github.com/eyre-rs/stable-eyre
|
||||
[`color-eyre`]: https://github.com/eyre-rs/color-eyre
|
||||
[`jane-eyre`]: https://github.com/yaahc/jane-eyre
|
||||
[`simple-eyre`]: https://github.com/eyre-rs/simple-eyre
|
||||
[`color-spantrace`]: https://github.com/eyre-rs/color-spantrace
|
||||
[`color-backtrace`]: https://github.com/athre0z/color-backtrace
|
||||
|
||||
[^1]: example and explanation of breakage https://github.com/eyre-rs/eyre/issues/30#issuecomment-647650361
|
||||
|
||||
#### 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>
|
||||
132
third-party/vendor/eyre/build.rs
vendored
Normal file
132
third-party/vendor/eyre/build.rs
vendored
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::process::{Command, ExitStatus};
|
||||
use std::str;
|
||||
|
||||
// This code exercises the surface area that we expect of the std Backtrace
|
||||
// type. If the current toolchain is able to compile it, we go ahead and use
|
||||
// backtrace in eyre.
|
||||
const BACKTRACE_PROBE: &str = r#"
|
||||
#![feature(backtrace)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::backtrace::{Backtrace, BacktraceStatus};
|
||||
use std::error::Error;
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct E;
|
||||
|
||||
impl Display for E {
|
||||
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for E {
|
||||
fn backtrace(&self) -> Option<&Backtrace> {
|
||||
let backtrace = Backtrace::capture();
|
||||
match backtrace.status() {
|
||||
BacktraceStatus::Captured | BacktraceStatus::Disabled | _ => {}
|
||||
}
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
const TRACK_CALLER_PROBE: &str = r#"
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[track_caller]
|
||||
fn foo() {
|
||||
let _location = std::panic::Location::caller();
|
||||
}
|
||||
"#;
|
||||
|
||||
fn main() {
|
||||
match compile_probe(BACKTRACE_PROBE) {
|
||||
Some(status) if status.success() => println!("cargo:rustc-cfg=backtrace"),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match compile_probe(TRACK_CALLER_PROBE) {
|
||||
Some(status) if status.success() => println!("cargo:rustc-cfg=track_caller"),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let version = match rustc_version_info() {
|
||||
Some(version) => version,
|
||||
None => return,
|
||||
};
|
||||
|
||||
version.toolchain.set_feature();
|
||||
|
||||
if version.minor < 52 {
|
||||
println!("cargo:rustc-cfg=eyre_no_fmt_arguments_as_str");
|
||||
}
|
||||
|
||||
if version.minor < 58 {
|
||||
println!("cargo:rustc-cfg=eyre_no_fmt_args_capture");
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_probe(probe: &str) -> Option<ExitStatus> {
|
||||
let rustc = env::var_os("RUSTC")?;
|
||||
let out_dir = env::var_os("OUT_DIR")?;
|
||||
let probefile = Path::new(&out_dir).join("probe.rs");
|
||||
fs::write(&probefile, probe).ok()?;
|
||||
Command::new(rustc)
|
||||
.arg("--edition=2018")
|
||||
.arg("--crate-name=eyre_build")
|
||||
.arg("--crate-type=lib")
|
||||
.arg("--emit=metadata")
|
||||
.arg("--out-dir")
|
||||
.arg(out_dir)
|
||||
.arg(probefile)
|
||||
.status()
|
||||
.ok()
|
||||
}
|
||||
|
||||
// TODO factor this toolchain parsing and related tests into its own file
|
||||
#[derive(PartialEq)]
|
||||
enum Toolchain {
|
||||
Stable,
|
||||
Beta,
|
||||
Nightly,
|
||||
}
|
||||
impl Toolchain {
|
||||
fn set_feature(self) {
|
||||
match self {
|
||||
Toolchain::Nightly => println!("cargo:rustc-cfg=nightly"),
|
||||
Toolchain::Beta => println!("cargo:rustc-cfg=beta"),
|
||||
Toolchain::Stable => println!("cargo:rustc-cfg=stable"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct VersionInfo {
|
||||
minor: u32,
|
||||
toolchain: Toolchain,
|
||||
}
|
||||
|
||||
fn rustc_version_info() -> Option<VersionInfo> {
|
||||
let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc"));
|
||||
let output = Command::new(rustc).arg("--version").output().ok()?;
|
||||
let version = str::from_utf8(&output.stdout).ok()?;
|
||||
let mut pieces = version.split(['.', ' ', '-']);
|
||||
if pieces.next() != Some("rustc") {
|
||||
return None;
|
||||
}
|
||||
let _major: u32 = pieces.next()?.parse().ok()?;
|
||||
let minor = pieces.next()?.parse().ok()?;
|
||||
let _patch: u32 = pieces.next()?.parse().ok()?;
|
||||
let toolchain = match pieces.next() {
|
||||
Some("beta") => Toolchain::Beta,
|
||||
Some("nightly") => Toolchain::Nightly,
|
||||
_ => Toolchain::Stable,
|
||||
};
|
||||
let version = VersionInfo { minor, toolchain };
|
||||
Some(version)
|
||||
}
|
||||
81
third-party/vendor/eyre/examples/custom_handler.rs
vendored
Normal file
81
third-party/vendor/eyre/examples/custom_handler.rs
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
use backtrace::Backtrace;
|
||||
use eyre::EyreHandler;
|
||||
use std::error::Error;
|
||||
use std::{fmt, iter};
|
||||
|
||||
fn main() -> eyre::Result<()> {
|
||||
// Install our custom eyre report hook for constructing our custom Handlers
|
||||
install().unwrap();
|
||||
|
||||
// construct a report with, hopefully, our custom handler!
|
||||
let mut report = eyre::eyre!("hello from custom error town!");
|
||||
|
||||
// manually set the custom msg for this report after it has been constructed
|
||||
if let Some(handler) = report.handler_mut().downcast_mut::<Handler>() {
|
||||
handler.custom_msg = Some("you're the best users, you know that right???");
|
||||
}
|
||||
|
||||
// print that shit!!
|
||||
Err(report)
|
||||
}
|
||||
|
||||
// define a handler that captures backtraces unless told not to
|
||||
fn install() -> Result<(), impl Error> {
|
||||
let capture_backtrace = std::env::var("RUST_BACKWARDS_TRACE")
|
||||
.map(|val| val != "0")
|
||||
.unwrap_or(true);
|
||||
|
||||
let hook = Hook { capture_backtrace };
|
||||
|
||||
eyre::set_hook(Box::new(move |e| Box::new(hook.make_handler(e))))
|
||||
}
|
||||
|
||||
struct Hook {
|
||||
capture_backtrace: bool,
|
||||
}
|
||||
|
||||
impl Hook {
|
||||
fn make_handler(&self, _error: &(dyn Error + 'static)) -> Handler {
|
||||
let backtrace = if self.capture_backtrace {
|
||||
Some(Backtrace::new())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Handler {
|
||||
backtrace,
|
||||
custom_msg: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Handler {
|
||||
// custom configured backtrace capture
|
||||
backtrace: Option<Backtrace>,
|
||||
// customizable message payload associated with reports
|
||||
custom_msg: Option<&'static str>,
|
||||
}
|
||||
|
||||
impl EyreHandler for Handler {
|
||||
fn debug(&self, error: &(dyn Error + 'static), f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if f.alternate() {
|
||||
return fmt::Debug::fmt(error, f);
|
||||
}
|
||||
|
||||
let errors = iter::successors(Some(error), |error| (*error).source());
|
||||
|
||||
for (ind, error) in errors.enumerate() {
|
||||
write!(f, "\n{:>4}: {}", ind, error)?;
|
||||
}
|
||||
|
||||
if let Some(backtrace) = self.backtrace.as_ref() {
|
||||
writeln!(f, "\n\nBacktrace:\n{:?}", backtrace)?;
|
||||
}
|
||||
|
||||
if let Some(msg) = self.custom_msg.as_ref() {
|
||||
writeln!(f, "\n\n{}", msg)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
7
third-party/vendor/eyre/examples/eyre-usage.rs
vendored
Normal file
7
third-party/vendor/eyre/examples/eyre-usage.rs
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
use eyre::{eyre, Report, WrapErr};
|
||||
|
||||
fn main() -> Result<(), Report> {
|
||||
let e: Report = eyre!("oh no this program is just bad!");
|
||||
|
||||
Err(e).wrap_err("usage example successfully experienced a failure")
|
||||
}
|
||||
22
third-party/vendor/eyre/src/backtrace.rs
vendored
Normal file
22
third-party/vendor/eyre/src/backtrace.rs
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#[cfg(backtrace)]
|
||||
pub(crate) use std::backtrace::Backtrace;
|
||||
|
||||
#[cfg(not(backtrace))]
|
||||
pub(crate) enum Backtrace {}
|
||||
|
||||
#[cfg(backtrace)]
|
||||
macro_rules! backtrace_if_absent {
|
||||
($err:expr) => {
|
||||
match $err.backtrace() {
|
||||
Some(_) => None,
|
||||
None => Some(Backtrace::capture()),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(backtrace))]
|
||||
macro_rules! backtrace_if_absent {
|
||||
($err:expr) => {
|
||||
None
|
||||
};
|
||||
}
|
||||
109
third-party/vendor/eyre/src/chain.rs
vendored
Normal file
109
third-party/vendor/eyre/src/chain.rs
vendored
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
use self::ChainState::*;
|
||||
use crate::StdError;
|
||||
|
||||
use std::vec;
|
||||
|
||||
pub(crate) use crate::Chain;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum ChainState<'a> {
|
||||
Linked {
|
||||
next: Option<&'a (dyn StdError + 'static)>,
|
||||
},
|
||||
Buffered {
|
||||
rest: vec::IntoIter<&'a (dyn StdError + 'static)>,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a> Chain<'a> {
|
||||
/// Construct an iterator over a chain of errors via the `source` method
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::error::Error;
|
||||
/// use std::fmt::{self, Write};
|
||||
/// use eyre::Chain;
|
||||
/// use indenter::indented;
|
||||
///
|
||||
/// fn report(error: &(dyn Error + 'static), f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
/// let mut errors = Chain::new(error).enumerate();
|
||||
/// for (i, error) in errors {
|
||||
/// writeln!(f)?;
|
||||
/// write!(indented(f).ind(i), "{}", error)?;
|
||||
/// }
|
||||
///
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub fn new(head: &'a (dyn StdError + 'static)) -> Self {
|
||||
Chain {
|
||||
state: ChainState::Linked { next: Some(head) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Chain<'a> {
|
||||
type Item = &'a (dyn StdError + 'static);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match &mut self.state {
|
||||
Linked { next } => {
|
||||
let error = (*next)?;
|
||||
*next = error.source();
|
||||
Some(error)
|
||||
}
|
||||
Buffered { rest } => rest.next(),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = self.len();
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
|
||||
impl DoubleEndedIterator for Chain<'_> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
match &mut self.state {
|
||||
Linked { mut next } => {
|
||||
let mut rest = Vec::new();
|
||||
while let Some(cause) = next {
|
||||
next = cause.source();
|
||||
rest.push(cause);
|
||||
}
|
||||
let mut rest = rest.into_iter();
|
||||
let last = rest.next_back();
|
||||
self.state = Buffered { rest };
|
||||
last
|
||||
}
|
||||
Buffered { rest } => rest.next_back(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for Chain<'_> {
|
||||
fn len(&self) -> usize {
|
||||
match &self.state {
|
||||
Linked { mut next } => {
|
||||
let mut len = 0;
|
||||
while let Some(cause) = next {
|
||||
next = cause.source();
|
||||
len += 1;
|
||||
}
|
||||
len
|
||||
}
|
||||
Buffered { rest } => rest.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Chain<'_> {
|
||||
fn default() -> Self {
|
||||
Chain {
|
||||
state: ChainState::Buffered {
|
||||
rest: Vec::new().into_iter(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
192
third-party/vendor/eyre/src/context.rs
vendored
Normal file
192
third-party/vendor/eyre/src/context.rs
vendored
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
use crate::error::{ContextError, ErrorImpl};
|
||||
use crate::{ContextCompat, Report, StdError, WrapErr};
|
||||
use core::fmt::{self, Debug, Display, Write};
|
||||
|
||||
#[cfg(backtrace)]
|
||||
use std::backtrace::Backtrace;
|
||||
|
||||
mod ext {
|
||||
use super::*;
|
||||
|
||||
pub trait StdError {
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
fn ext_report<D>(self, msg: D) -> Report
|
||||
where
|
||||
D: Display + Send + Sync + 'static;
|
||||
}
|
||||
|
||||
impl<E> StdError for E
|
||||
where
|
||||
E: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
fn ext_report<D>(self, msg: D) -> Report
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
{
|
||||
Report::from_msg(msg, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for Report {
|
||||
fn ext_report<D>(self, msg: D) -> Report
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
{
|
||||
self.wrap_err(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> WrapErr<T, E> for Result<T, E>
|
||||
where
|
||||
E: ext::StdError + Send + Sync + 'static,
|
||||
{
|
||||
fn wrap_err<D>(self, msg: D) -> Result<T, Report>
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
{
|
||||
match self {
|
||||
Ok(t) => Ok(t),
|
||||
Err(e) => Err(e.ext_report(msg)),
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap_err_with<D, F>(self, msg: F) -> Result<T, Report>
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
F: FnOnce() -> D,
|
||||
{
|
||||
match self {
|
||||
Ok(t) => Ok(t),
|
||||
Err(e) => Err(e.ext_report(msg())),
|
||||
}
|
||||
}
|
||||
|
||||
fn context<D>(self, msg: D) -> Result<T, Report>
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
{
|
||||
self.wrap_err(msg)
|
||||
}
|
||||
|
||||
fn with_context<D, F>(self, msg: F) -> Result<T, Report>
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
F: FnOnce() -> D,
|
||||
{
|
||||
self.wrap_err_with(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ContextCompat<T> for Option<T> {
|
||||
fn wrap_err<D>(self, msg: D) -> Result<T, Report>
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
{
|
||||
self.context(msg)
|
||||
}
|
||||
|
||||
fn wrap_err_with<D, F>(self, msg: F) -> Result<T, Report>
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
F: FnOnce() -> D,
|
||||
{
|
||||
self.with_context(msg)
|
||||
}
|
||||
|
||||
fn context<D>(self, msg: D) -> Result<T, Report>
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
{
|
||||
match self {
|
||||
Some(t) => Ok(t),
|
||||
None => Err(Report::from_display(msg)),
|
||||
}
|
||||
}
|
||||
|
||||
fn with_context<D, F>(self, msg: F) -> Result<T, Report>
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
F: FnOnce() -> D,
|
||||
{
|
||||
match self {
|
||||
Some(t) => Ok(t),
|
||||
None => Err(Report::from_display(msg())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D, E> Debug for ContextError<D, E>
|
||||
where
|
||||
D: Display,
|
||||
E: Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Error")
|
||||
.field("msg", &Quoted(&self.msg))
|
||||
.field("source", &self.error)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D, E> Display for ContextError<D, E>
|
||||
where
|
||||
D: Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Display::fmt(&self.msg, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D, E> StdError for ContextError<D, E>
|
||||
where
|
||||
D: Display,
|
||||
E: StdError + 'static,
|
||||
{
|
||||
#[cfg(backtrace)]
|
||||
fn backtrace(&self) -> Option<&Backtrace> {
|
||||
self.error.backtrace()
|
||||
}
|
||||
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
Some(&self.error)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D> StdError for ContextError<D, Report>
|
||||
where
|
||||
D: Display,
|
||||
{
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
Some(ErrorImpl::error(self.error.inner.as_ref()))
|
||||
}
|
||||
}
|
||||
|
||||
struct Quoted<D>(D);
|
||||
|
||||
impl<D> Debug for Quoted<D>
|
||||
where
|
||||
D: Display,
|
||||
{
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
formatter.write_char('"')?;
|
||||
Quoted(&mut *formatter).write_fmt(format_args!("{}", self.0))?;
|
||||
formatter.write_char('"')?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Quoted<&mut fmt::Formatter<'_>> {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
Display::fmt(&s.escape_debug(), self.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod private {
|
||||
use super::*;
|
||||
|
||||
pub trait Sealed {}
|
||||
|
||||
impl<T, E> Sealed for Result<T, E> where E: ext::StdError {}
|
||||
impl<T> Sealed for Option<T> {}
|
||||
}
|
||||
912
third-party/vendor/eyre/src/error.rs
vendored
Normal file
912
third-party/vendor/eyre/src/error.rs
vendored
Normal file
|
|
@ -0,0 +1,912 @@
|
|||
use crate::chain::Chain;
|
||||
use crate::ptr::{MutPtr, OwnedPtr, RefPtr};
|
||||
use crate::EyreHandler;
|
||||
use crate::{Report, StdError};
|
||||
use core::any::TypeId;
|
||||
use core::fmt::{self, Debug, Display};
|
||||
use core::mem::{self, ManuallyDrop};
|
||||
use core::ptr::{self, NonNull};
|
||||
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
impl Report {
|
||||
/// Create a new error object from any error type.
|
||||
///
|
||||
/// The error type must be threadsafe and `'static`, so that the `Report`
|
||||
/// will be as well.
|
||||
///
|
||||
/// If the error type does not provide a backtrace, a backtrace will be
|
||||
/// created here to ensure that a backtrace exists.
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub fn new<E>(error: E) -> Self
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
Report::from_std(error)
|
||||
}
|
||||
|
||||
/// Create a new error object from a printable error message.
|
||||
///
|
||||
/// If the argument implements std::error::Error, prefer `Report::new`
|
||||
/// instead which preserves the underlying error's cause chain and
|
||||
/// backtrace. If the argument may or may not implement std::error::Error
|
||||
/// now or in the future, use `eyre!(err)` which handles either way
|
||||
/// correctly.
|
||||
///
|
||||
/// `Report::msg("...")` is equivalent to `eyre!("...")` but occasionally
|
||||
/// convenient in places where a function is preferable over a macro, such
|
||||
/// as iterator or stream combinators:
|
||||
///
|
||||
/// ```
|
||||
/// # mod ffi {
|
||||
/// # pub struct Input;
|
||||
/// # pub struct Output;
|
||||
/// # pub async fn do_some_work(_: Input) -> Result<Output, &'static str> {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # use ffi::{Input, Output};
|
||||
/// #
|
||||
/// use eyre::{Report, Result};
|
||||
/// use futures::stream::{Stream, StreamExt, TryStreamExt};
|
||||
///
|
||||
/// async fn demo<S>(stream: S) -> Result<Vec<Output>>
|
||||
/// where
|
||||
/// S: Stream<Item = Input>,
|
||||
/// {
|
||||
/// stream
|
||||
/// .then(ffi::do_some_work) // returns Result<Output, &str>
|
||||
/// .map_err(Report::msg)
|
||||
/// .try_collect()
|
||||
/// .await
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub fn msg<M>(message: M) -> Self
|
||||
where
|
||||
M: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
Report::from_adhoc(message)
|
||||
}
|
||||
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
/// Creates a new error from an implementor of [`std::error::Error`]
|
||||
pub(crate) fn from_std<E>(error: E) -> Self
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<E>,
|
||||
object_ref: object_ref::<E>,
|
||||
object_mut: object_mut::<E>,
|
||||
object_boxed: object_boxed::<E>,
|
||||
object_downcast: object_downcast::<E>,
|
||||
object_downcast_mut: object_downcast_mut::<E>,
|
||||
object_drop_rest: object_drop_front::<E>,
|
||||
};
|
||||
|
||||
// Safety: passing vtable that operates on the right type E.
|
||||
let handler = Some(crate::capture_handler(&error));
|
||||
|
||||
unsafe { Report::construct(error, vtable, handler) }
|
||||
}
|
||||
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub(crate) fn from_adhoc<M>(message: M) -> Self
|
||||
where
|
||||
M: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
use crate::wrapper::MessageError;
|
||||
let error: MessageError<M> = MessageError(message);
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<MessageError<M>>,
|
||||
object_ref: object_ref::<MessageError<M>>,
|
||||
object_mut: object_mut::<MessageError<M>>,
|
||||
object_boxed: object_boxed::<MessageError<M>>,
|
||||
object_downcast: object_downcast::<M>,
|
||||
object_downcast_mut: object_downcast_mut::<M>,
|
||||
object_drop_rest: object_drop_front::<M>,
|
||||
};
|
||||
|
||||
// Safety: MessageError is repr(transparent) so it is okay for the
|
||||
// vtable to allow casting the MessageError<M> to M.
|
||||
let handler = Some(crate::capture_handler(&error));
|
||||
|
||||
unsafe { Report::construct(error, vtable, handler) }
|
||||
}
|
||||
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub(crate) fn from_display<M>(message: M) -> Self
|
||||
where
|
||||
M: Display + Send + Sync + 'static,
|
||||
{
|
||||
use crate::wrapper::{DisplayError, NoneError};
|
||||
let error: DisplayError<M> = DisplayError(message);
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<DisplayError<M>>,
|
||||
object_ref: object_ref::<DisplayError<M>>,
|
||||
object_mut: object_mut::<DisplayError<M>>,
|
||||
object_boxed: object_boxed::<DisplayError<M>>,
|
||||
object_downcast: object_downcast::<M>,
|
||||
object_downcast_mut: object_downcast_mut::<M>,
|
||||
object_drop_rest: object_drop_front::<M>,
|
||||
};
|
||||
|
||||
// Safety: DisplayError is repr(transparent) so it is okay for the
|
||||
// vtable to allow casting the DisplayError<M> to M.
|
||||
let handler = Some(crate::capture_handler(&NoneError));
|
||||
|
||||
unsafe { Report::construct(error, vtable, handler) }
|
||||
}
|
||||
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub(crate) fn from_msg<D, E>(msg: D, error: E) -> Self
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
let error: ContextError<D, E> = ContextError { msg, error };
|
||||
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<ContextError<D, E>>,
|
||||
object_ref: object_ref::<ContextError<D, E>>,
|
||||
object_mut: object_mut::<ContextError<D, E>>,
|
||||
object_boxed: object_boxed::<ContextError<D, E>>,
|
||||
object_downcast: context_downcast::<D, E>,
|
||||
object_downcast_mut: context_downcast_mut::<D, E>,
|
||||
object_drop_rest: context_drop_rest::<D, E>,
|
||||
};
|
||||
|
||||
// Safety: passing vtable that operates on the right type.
|
||||
let handler = Some(crate::capture_handler(&error));
|
||||
|
||||
unsafe { Report::construct(error, vtable, handler) }
|
||||
}
|
||||
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub(crate) fn from_boxed(error: Box<dyn StdError + Send + Sync>) -> Self {
|
||||
use crate::wrapper::BoxedError;
|
||||
let error = BoxedError(error);
|
||||
let handler = Some(crate::capture_handler(&error));
|
||||
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<BoxedError>,
|
||||
object_ref: object_ref::<BoxedError>,
|
||||
object_mut: object_mut::<BoxedError>,
|
||||
object_boxed: object_boxed::<BoxedError>,
|
||||
object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>,
|
||||
object_downcast_mut: object_downcast_mut::<Box<dyn StdError + Send + Sync>>,
|
||||
object_drop_rest: object_drop_front::<Box<dyn StdError + Send + Sync>>,
|
||||
};
|
||||
|
||||
// Safety: BoxedError is repr(transparent) so it is okay for the vtable
|
||||
// to allow casting to Box<dyn StdError + Send + Sync>.
|
||||
unsafe { Report::construct(error, vtable, handler) }
|
||||
}
|
||||
|
||||
// Takes backtrace as argument rather than capturing it here so that the
|
||||
// user sees one fewer layer of wrapping noise in the backtrace.
|
||||
//
|
||||
// Unsafe because the given vtable must have sensible behavior on the error
|
||||
// value of type E.
|
||||
unsafe fn construct<E>(
|
||||
error: E,
|
||||
vtable: &'static ErrorVTable,
|
||||
handler: Option<Box<dyn EyreHandler>>,
|
||||
) -> Self
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
let inner = ErrorImpl {
|
||||
header: ErrorHeader { vtable, handler },
|
||||
_object: error,
|
||||
};
|
||||
|
||||
// Construct a new owned allocation through a raw pointer
|
||||
//
|
||||
// This does not keep the allocation around as a `Box` which would invalidate an
|
||||
// references when moved
|
||||
let ptr = OwnedPtr::<ErrorImpl<E>>::new(inner);
|
||||
|
||||
// Safety: the type
|
||||
let ptr = ptr.cast::<ErrorImpl<()>>();
|
||||
Report { inner: ptr }
|
||||
}
|
||||
|
||||
/// Create a new error from an error message to wrap the existing error.
|
||||
///
|
||||
/// For attaching a higher level error message to a `Result` as it is propagated, the
|
||||
/// [`WrapErr`][crate::WrapErr] extension trait may be more convenient than this function.
|
||||
///
|
||||
/// The primary reason to use `error.wrap_err(...)` instead of `result.wrap_err(...)` via the
|
||||
/// `WrapErr` trait would be if the message needs to depend on some data held by the underlying
|
||||
/// error:
|
||||
///
|
||||
/// ```
|
||||
/// # use std::fmt::{self, Debug, Display};
|
||||
/// #
|
||||
/// # type T = ();
|
||||
/// #
|
||||
/// # impl std::error::Error for ParseError {}
|
||||
/// # impl Debug for ParseError {
|
||||
/// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// # }
|
||||
/// # impl Display for ParseError {
|
||||
/// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// use eyre::Result;
|
||||
/// use std::fs::File;
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// struct ParseError {
|
||||
/// line: usize,
|
||||
/// column: usize,
|
||||
/// }
|
||||
///
|
||||
/// fn parse_impl(file: File) -> Result<T, ParseError> {
|
||||
/// # const IGNORE: &str = stringify! {
|
||||
/// ...
|
||||
/// # };
|
||||
/// # unimplemented!()
|
||||
/// }
|
||||
///
|
||||
/// pub fn parse(path: impl AsRef<Path>) -> Result<T> {
|
||||
/// let file = File::open(&path)?;
|
||||
/// parse_impl(file).map_err(|error| {
|
||||
/// let message = format!(
|
||||
/// "only the first {} lines of {} are valid",
|
||||
/// error.line, path.as_ref().display(),
|
||||
/// );
|
||||
/// eyre::Report::new(error).wrap_err(message)
|
||||
/// })
|
||||
/// }
|
||||
/// ```
|
||||
pub fn wrap_err<D>(mut self, msg: D) -> Self
|
||||
where
|
||||
D: Display + Send + Sync + 'static,
|
||||
{
|
||||
// Safety: this access a `ErrorImpl<unknown>` as a valid reference to a `ErrorImpl<()>`
|
||||
//
|
||||
// As the generic is at the end of the struct and the struct is `repr(C)` this reference
|
||||
// will be within bounds of the original pointer, and the field will have the same offset
|
||||
let handler = header_mut(self.inner.as_mut()).handler.take();
|
||||
let error: ContextError<D, Report> = ContextError { msg, error: self };
|
||||
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<ContextError<D, Report>>,
|
||||
object_ref: object_ref::<ContextError<D, Report>>,
|
||||
object_mut: object_mut::<ContextError<D, Report>>,
|
||||
object_boxed: object_boxed::<ContextError<D, Report>>,
|
||||
object_downcast: context_chain_downcast::<D>,
|
||||
object_downcast_mut: context_chain_downcast_mut::<D>,
|
||||
object_drop_rest: context_chain_drop_rest::<D>,
|
||||
};
|
||||
|
||||
// Safety: passing vtable that operates on the right type.
|
||||
unsafe { Report::construct(error, vtable, handler) }
|
||||
}
|
||||
|
||||
/// Access the vtable for the current error object.
|
||||
fn vtable(&self) -> &'static ErrorVTable {
|
||||
header(self.inner.as_ref()).vtable
|
||||
}
|
||||
|
||||
/// An iterator of the chain of source errors contained by this Report.
|
||||
///
|
||||
/// This iterator will visit every error in the cause chain of this error
|
||||
/// object, beginning with the error that this error object was created
|
||||
/// from.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use eyre::Report;
|
||||
/// use std::io;
|
||||
///
|
||||
/// pub fn underlying_io_error_kind(error: &Report) -> Option<io::ErrorKind> {
|
||||
/// for cause in error.chain() {
|
||||
/// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
|
||||
/// return Some(io_error.kind());
|
||||
/// }
|
||||
/// }
|
||||
/// None
|
||||
/// }
|
||||
/// ```
|
||||
pub fn chain(&self) -> Chain<'_> {
|
||||
ErrorImpl::chain(self.inner.as_ref())
|
||||
}
|
||||
|
||||
/// The lowest level cause of this error — this error's cause's
|
||||
/// cause's cause etc.
|
||||
///
|
||||
/// The root cause is the last error in the iterator produced by
|
||||
/// [`chain()`][Report::chain].
|
||||
pub fn root_cause(&self) -> &(dyn StdError + 'static) {
|
||||
let mut chain = self.chain();
|
||||
let mut root_cause = chain.next().unwrap();
|
||||
for cause in chain {
|
||||
root_cause = cause;
|
||||
}
|
||||
root_cause
|
||||
}
|
||||
|
||||
/// Returns true if `E` is the type held by this error object.
|
||||
///
|
||||
/// For errors constructed from messages, this method returns true if `E` matches the type of
|
||||
/// the message `D` **or** the type of the error on which the message has been attached. For
|
||||
/// details about the interaction between message and downcasting, [see here].
|
||||
///
|
||||
/// [see here]: trait.WrapErr.html#effect-on-downcasting
|
||||
pub fn is<E>(&self) -> bool
|
||||
where
|
||||
E: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
self.downcast_ref::<E>().is_some()
|
||||
}
|
||||
|
||||
/// Attempt to downcast the error object to a concrete type.
|
||||
pub fn downcast<E>(self) -> Result<E, Self>
|
||||
where
|
||||
E: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
let target = TypeId::of::<E>();
|
||||
unsafe {
|
||||
// Use vtable to find NonNull<()> which points to a value of type E
|
||||
// somewhere inside the data structure.
|
||||
let addr = match (self.vtable().object_downcast)(self.inner.as_ref(), target) {
|
||||
Some(addr) => addr,
|
||||
None => return Err(self),
|
||||
};
|
||||
|
||||
// Prepare to read E out of the data structure. We'll drop the rest
|
||||
// of the data structure separately so that E is not dropped.
|
||||
let outer = ManuallyDrop::new(self);
|
||||
|
||||
// Read E from where the vtable found it.
|
||||
let error = ptr::read(addr.cast::<E>().as_ptr());
|
||||
|
||||
// Read Box<ErrorImpl<()>> from self. Can't move it out because
|
||||
// Report has a Drop impl which we want to not run.
|
||||
let inner = ptr::read(&outer.inner);
|
||||
|
||||
// Drop rest of the data structure outside of E.
|
||||
(outer.vtable().object_drop_rest)(inner, target);
|
||||
|
||||
Ok(error)
|
||||
}
|
||||
}
|
||||
|
||||
/// Downcast this error object by reference.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use eyre::{Report, eyre};
|
||||
/// # use std::fmt::{self, Display};
|
||||
/// # use std::task::Poll;
|
||||
/// #
|
||||
/// # #[derive(Debug)]
|
||||
/// # enum DataStoreError {
|
||||
/// # Censored(()),
|
||||
/// # }
|
||||
/// #
|
||||
/// # impl Display for DataStoreError {
|
||||
/// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # impl std::error::Error for DataStoreError {}
|
||||
/// #
|
||||
/// # const REDACTED_CONTENT: () = ();
|
||||
/// #
|
||||
/// # #[cfg(not(feature = "auto-install"))]
|
||||
/// # eyre::set_hook(Box::new(eyre::DefaultHandler::default_with)).unwrap();
|
||||
/// #
|
||||
/// # let error: Report = eyre!("...");
|
||||
/// # let root_cause = &error;
|
||||
/// #
|
||||
/// # let ret =
|
||||
/// // If the error was caused by redaction, then return a tombstone instead
|
||||
/// // of the content.
|
||||
/// match root_cause.downcast_ref::<DataStoreError>() {
|
||||
/// Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
|
||||
/// None => Err(error),
|
||||
/// }
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn downcast_ref<E>(&self) -> Option<&E>
|
||||
where
|
||||
E: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
let target = TypeId::of::<E>();
|
||||
unsafe {
|
||||
// Use vtable to find NonNull<()> which points to a value of type E
|
||||
// somewhere inside the data structure.
|
||||
let addr = (self.vtable().object_downcast)(self.inner.as_ref(), target)?;
|
||||
Some(addr.cast::<E>().as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
/// Downcast this error object by mutable reference.
|
||||
pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
|
||||
where
|
||||
E: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
let target = TypeId::of::<E>();
|
||||
unsafe {
|
||||
// Use vtable to find NonNull<()> which points to a value of type E
|
||||
// somewhere inside the data structure.
|
||||
let addr = (self.vtable().object_downcast_mut)(self.inner.as_mut(), target)?;
|
||||
Some(addr.cast::<E>().as_mut())
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the Handler for this Report.
|
||||
pub fn handler(&self) -> &dyn EyreHandler {
|
||||
header(self.inner.as_ref())
|
||||
.handler
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
}
|
||||
|
||||
/// Get a mutable reference to the Handler for this Report.
|
||||
pub fn handler_mut(&mut self) -> &mut dyn EyreHandler {
|
||||
header_mut(self.inner.as_mut())
|
||||
.handler
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
}
|
||||
|
||||
/// Get a reference to the Handler for this Report.
|
||||
#[doc(hidden)]
|
||||
pub fn context(&self) -> &dyn EyreHandler {
|
||||
header(self.inner.as_ref())
|
||||
.handler
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
}
|
||||
|
||||
/// Get a mutable reference to the Handler for this Report.
|
||||
#[doc(hidden)]
|
||||
pub fn context_mut(&mut self) -> &mut dyn EyreHandler {
|
||||
header_mut(self.inner.as_mut())
|
||||
.handler
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> From<E> for Report
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
fn from(error: E) -> Self {
|
||||
Report::from_std(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Report {
|
||||
type Target = dyn StdError + Send + Sync + 'static;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
ErrorImpl::error(self.inner.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Report {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
ErrorImpl::error_mut(self.inner.as_mut())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Report {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
ErrorImpl::display(self.inner.as_ref(), formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Report {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
ErrorImpl::debug(self.inner.as_ref(), formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Report {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// Read Box<ErrorImpl<()>> from self.
|
||||
(self.vtable().object_drop)(self.inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ErrorVTable {
|
||||
object_drop: unsafe fn(OwnedPtr<ErrorImpl<()>>),
|
||||
object_ref: unsafe fn(RefPtr<'_, ErrorImpl<()>>) -> &(dyn StdError + Send + Sync + 'static),
|
||||
object_mut: unsafe fn(MutPtr<'_, ErrorImpl<()>>) -> &mut (dyn StdError + Send + Sync + 'static),
|
||||
#[allow(clippy::type_complexity)]
|
||||
object_boxed: unsafe fn(OwnedPtr<ErrorImpl<()>>) -> Box<dyn StdError + Send + Sync + 'static>,
|
||||
object_downcast: unsafe fn(RefPtr<'_, ErrorImpl<()>>, TypeId) -> Option<NonNull<()>>,
|
||||
object_downcast_mut: unsafe fn(MutPtr<'_, ErrorImpl<()>>, TypeId) -> Option<NonNull<()>>,
|
||||
object_drop_rest: unsafe fn(OwnedPtr<ErrorImpl<()>>, TypeId),
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_drop<E>(e: OwnedPtr<ErrorImpl<()>>) {
|
||||
// Cast to a context type and drop the Box allocation.
|
||||
let unerased = unsafe { e.cast::<ErrorImpl<E>>().into_box() };
|
||||
drop(unerased);
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_drop_front<E>(e: OwnedPtr<ErrorImpl<()>>, target: TypeId) {
|
||||
// Drop the fields of ErrorImpl other than E as well as the Box allocation,
|
||||
// without dropping E itself. This is used by downcast after doing a
|
||||
// ptr::read to take ownership of the E.
|
||||
let _ = target;
|
||||
// Note: This must not use `mem::transmute` because it tries to reborrow the `Unique`
|
||||
// contained in `Box`, which must not be done. In practice this probably won't make any
|
||||
// difference by now, but technically it's unsound.
|
||||
// see: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.m
|
||||
let unerased = unsafe { e.cast::<ErrorImpl<E>>().into_box() };
|
||||
|
||||
mem::forget(unerased._object)
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_ref<E>(e: RefPtr<'_, ErrorImpl<()>>) -> &(dyn StdError + Send + Sync + 'static)
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
// Attach E's native StdError vtable onto a pointer to self._object.
|
||||
&unsafe { e.cast::<ErrorImpl<E>>().as_ref() }._object
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_mut<E>(e: MutPtr<'_, ErrorImpl<()>>) -> &mut (dyn StdError + Send + Sync + 'static)
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
// Attach E's native StdError vtable onto a pointer to self._object.
|
||||
&mut unsafe { e.cast::<ErrorImpl<E>>().into_mut() }._object
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_boxed<E>(e: OwnedPtr<ErrorImpl<()>>) -> Box<dyn StdError + Send + Sync + 'static>
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
// Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
|
||||
unsafe { e.cast::<ErrorImpl<E>>().into_box() }
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_downcast<E>(e: RefPtr<'_, ErrorImpl<()>>, target: TypeId) -> Option<NonNull<()>>
|
||||
where
|
||||
E: 'static,
|
||||
{
|
||||
if TypeId::of::<E>() == target {
|
||||
// Caller is looking for an E pointer and e is ErrorImpl<E>, take a
|
||||
// pointer to its E field.
|
||||
let unerased = unsafe { e.cast::<ErrorImpl<E>>().as_ref() };
|
||||
Some(NonNull::from(&(unerased._object)).cast::<()>())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_downcast_mut<E>(
|
||||
e: MutPtr<'_, ErrorImpl<()>>,
|
||||
target: TypeId,
|
||||
) -> Option<NonNull<()>>
|
||||
where
|
||||
E: 'static,
|
||||
{
|
||||
if TypeId::of::<E>() == target {
|
||||
// Caller is looking for an E pointer and e is ErrorImpl<E>, take a
|
||||
// pointer to its E field.
|
||||
let unerased = unsafe { e.cast::<ErrorImpl<E>>().into_mut() };
|
||||
Some(NonNull::from(&mut (unerased._object)).cast::<()>())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<ContextError<D, E>>.
|
||||
unsafe fn context_downcast<D, E>(
|
||||
e: RefPtr<'_, ErrorImpl<()>>,
|
||||
target: TypeId,
|
||||
) -> Option<NonNull<()>>
|
||||
where
|
||||
D: 'static,
|
||||
E: 'static,
|
||||
{
|
||||
if TypeId::of::<D>() == target {
|
||||
let unerased = unsafe { e.cast::<ErrorImpl<ContextError<D, E>>>().as_ref() };
|
||||
let addr = NonNull::from(&unerased._object.msg).cast::<()>();
|
||||
Some(addr)
|
||||
} else if TypeId::of::<E>() == target {
|
||||
let unerased = unsafe { e.cast::<ErrorImpl<ContextError<D, E>>>().as_ref() };
|
||||
let addr = NonNull::from(&unerased._object.error).cast::<()>();
|
||||
Some(addr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<ContextError<D, E>>.
|
||||
unsafe fn context_downcast_mut<D, E>(
|
||||
e: MutPtr<'_, ErrorImpl<()>>,
|
||||
target: TypeId,
|
||||
) -> Option<NonNull<()>>
|
||||
where
|
||||
D: 'static,
|
||||
E: 'static,
|
||||
{
|
||||
if TypeId::of::<D>() == target {
|
||||
let unerased = unsafe { e.cast::<ErrorImpl<ContextError<D, E>>>().into_mut() };
|
||||
let addr = NonNull::from(&unerased._object.msg).cast::<()>();
|
||||
Some(addr)
|
||||
} else if TypeId::of::<E>() == target {
|
||||
let unerased = unsafe { e.cast::<ErrorImpl<ContextError<D, E>>>().into_mut() };
|
||||
let addr = NonNull::from(&mut unerased._object.error).cast::<()>();
|
||||
Some(addr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<ContextError<D, E>>.
|
||||
unsafe fn context_drop_rest<D, E>(e: OwnedPtr<ErrorImpl<()>>, target: TypeId)
|
||||
where
|
||||
D: 'static,
|
||||
E: 'static,
|
||||
{
|
||||
// Called after downcasting by value to either the D or the E and doing a
|
||||
// ptr::read to take ownership of that value.
|
||||
if TypeId::of::<D>() == target {
|
||||
unsafe {
|
||||
e.cast::<ErrorImpl<ContextError<ManuallyDrop<D>, E>>>()
|
||||
.into_box()
|
||||
};
|
||||
} else {
|
||||
debug_assert_eq!(TypeId::of::<E>(), target);
|
||||
unsafe {
|
||||
e.cast::<ErrorImpl<ContextError<D, ManuallyDrop<E>>>>()
|
||||
.into_box()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<ContextError<D, Report>>.
|
||||
unsafe fn context_chain_downcast<D>(
|
||||
e: RefPtr<'_, ErrorImpl<()>>,
|
||||
target: TypeId,
|
||||
) -> Option<NonNull<()>>
|
||||
where
|
||||
D: 'static,
|
||||
{
|
||||
let unerased = unsafe { e.cast::<ErrorImpl<ContextError<D, Report>>>().as_ref() };
|
||||
if TypeId::of::<D>() == target {
|
||||
let addr = NonNull::from(&unerased._object.msg).cast::<()>();
|
||||
Some(addr)
|
||||
} else {
|
||||
// Recurse down the context chain per the inner error's vtable.
|
||||
let source = &unerased._object.error;
|
||||
unsafe { (source.vtable().object_downcast)(source.inner.as_ref(), target) }
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<ContextError<D, Report>>.
|
||||
unsafe fn context_chain_downcast_mut<D>(
|
||||
e: MutPtr<'_, ErrorImpl<()>>,
|
||||
target: TypeId,
|
||||
) -> Option<NonNull<()>>
|
||||
where
|
||||
D: 'static,
|
||||
{
|
||||
let unerased = unsafe { e.cast::<ErrorImpl<ContextError<D, Report>>>().into_mut() };
|
||||
if TypeId::of::<D>() == target {
|
||||
let addr = NonNull::from(&unerased._object.msg).cast::<()>();
|
||||
Some(addr)
|
||||
} else {
|
||||
// Recurse down the context chain per the inner error's vtable.
|
||||
let source = &mut unerased._object.error;
|
||||
unsafe { (source.vtable().object_downcast_mut)(source.inner.as_mut(), target) }
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Requires layout of *e to match ErrorImpl<ContextError<D, Report>>.
|
||||
unsafe fn context_chain_drop_rest<D>(e: OwnedPtr<ErrorImpl<()>>, target: TypeId)
|
||||
where
|
||||
D: 'static,
|
||||
{
|
||||
// Called after downcasting by value to either the D or one of the causes
|
||||
// and doing a ptr::read to take ownership of that value.
|
||||
if TypeId::of::<D>() == target {
|
||||
let unerased = unsafe {
|
||||
e.cast::<ErrorImpl<ContextError<ManuallyDrop<D>, Report>>>()
|
||||
.into_box()
|
||||
};
|
||||
// Drop the entire rest of the data structure rooted in the next Report.
|
||||
drop(unerased);
|
||||
} else {
|
||||
unsafe {
|
||||
let unerased = e
|
||||
.cast::<ErrorImpl<ContextError<D, ManuallyDrop<Report>>>>()
|
||||
.into_box();
|
||||
// Read out a ManuallyDrop<Box<ErrorImpl<()>>> from the next error.
|
||||
let inner = ptr::read(&unerased.as_ref()._object.error.inner);
|
||||
drop(unerased);
|
||||
// Recursively drop the next error using the same target typeid.
|
||||
(header(inner.as_ref()).vtable.object_drop_rest)(inner, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub(crate) struct ErrorHeader {
|
||||
vtable: &'static ErrorVTable,
|
||||
pub(crate) handler: Option<Box<dyn EyreHandler>>,
|
||||
}
|
||||
|
||||
// repr C to ensure that E remains in the final position.
|
||||
#[repr(C)]
|
||||
pub(crate) struct ErrorImpl<E = ()> {
|
||||
header: ErrorHeader,
|
||||
// NOTE: Don't use directly. Use only through vtable. Erased type may have
|
||||
// different alignment.
|
||||
_object: E,
|
||||
}
|
||||
|
||||
// repr C to ensure that ContextError<D, E> has the same layout as
|
||||
// ContextError<ManuallyDrop<D>, E> and ContextError<D, ManuallyDrop<E>>.
|
||||
#[repr(C)]
|
||||
pub(crate) struct ContextError<D, E> {
|
||||
pub(crate) msg: D,
|
||||
pub(crate) error: E,
|
||||
}
|
||||
|
||||
impl<E> ErrorImpl<E> {
|
||||
/// Returns a type erased Error
|
||||
fn erase(&self) -> RefPtr<'_, ErrorImpl<()>> {
|
||||
// Erase the concrete type of E but preserve the vtable in self.vtable
|
||||
// for manipulating the resulting thin pointer. This is analogous to an
|
||||
// unsize coersion.
|
||||
RefPtr::new(self).cast()
|
||||
}
|
||||
}
|
||||
|
||||
// Reads the header out of `p`. This is the same as `p.as_ref().header`, but
|
||||
// avoids converting `p` into a reference of a shrunk provenance with a type different than the
|
||||
// allocation.
|
||||
fn header(p: RefPtr<'_, ErrorImpl<()>>) -> &'_ ErrorHeader {
|
||||
// Safety: `ErrorHeader` is the first field of repr(C) `ErrorImpl`
|
||||
unsafe { p.cast().as_ref() }
|
||||
}
|
||||
|
||||
fn header_mut(p: MutPtr<'_, ErrorImpl<()>>) -> &mut ErrorHeader {
|
||||
// Safety: `ErrorHeader` is the first field of repr(C) `ErrorImpl`
|
||||
unsafe { p.cast().into_mut() }
|
||||
}
|
||||
|
||||
impl ErrorImpl<()> {
|
||||
pub(crate) fn error(this: RefPtr<'_, Self>) -> &(dyn StdError + Send + Sync + 'static) {
|
||||
// Use vtable to attach E's native StdError vtable for the right
|
||||
// original type E.
|
||||
unsafe { (header(this).vtable.object_ref)(this) }
|
||||
}
|
||||
|
||||
pub(crate) fn error_mut(this: MutPtr<'_, Self>) -> &mut (dyn StdError + Send + Sync + 'static) {
|
||||
// Use vtable to attach E's native StdError vtable for the right
|
||||
// original type E.
|
||||
unsafe { (header_mut(this).vtable.object_mut)(this) }
|
||||
}
|
||||
|
||||
pub(crate) fn chain(this: RefPtr<'_, Self>) -> Chain<'_> {
|
||||
Chain::new(Self::error(this))
|
||||
}
|
||||
|
||||
pub(crate) fn header(this: RefPtr<'_, ErrorImpl>) -> &ErrorHeader {
|
||||
header(this)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> StdError for ErrorImpl<E>
|
||||
where
|
||||
E: StdError,
|
||||
{
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
ErrorImpl::<()>::error(self.erase()).source()
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> Debug for ErrorImpl<E>
|
||||
where
|
||||
E: Debug,
|
||||
{
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
ErrorImpl::debug(self.erase(), formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> Display for ErrorImpl<E>
|
||||
where
|
||||
E: Display,
|
||||
{
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Display::fmt(ErrorImpl::error(self.erase()), formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Report> for Box<dyn StdError + Send + Sync + 'static> {
|
||||
fn from(error: Report) -> Self {
|
||||
let outer = ManuallyDrop::new(error);
|
||||
unsafe {
|
||||
// Read Box<ErrorImpl<()>> from error. Can't move it out because
|
||||
// Report has a Drop impl which we want to not run.
|
||||
// Use vtable to attach ErrorImpl<E>'s native StdError vtable for
|
||||
// the right original type E.
|
||||
(header(outer.inner.as_ref()).vtable.object_boxed)(outer.inner)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Report> for Box<dyn StdError + 'static> {
|
||||
fn from(error: Report) -> Self {
|
||||
Box::<dyn StdError + Send + Sync>::from(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn StdError + Send + Sync> for Report {
|
||||
fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<dyn StdError> for Report {
|
||||
fn as_ref(&self) -> &(dyn StdError + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "pyo3")]
|
||||
mod pyo3_compat;
|
||||
7
third-party/vendor/eyre/src/error/pyo3_compat.rs
vendored
Normal file
7
third-party/vendor/eyre/src/error/pyo3_compat.rs
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
use crate::Report;
|
||||
|
||||
impl From<Report> for pyo3::PyErr {
|
||||
fn from(error: Report) -> Self {
|
||||
pyo3::exceptions::PyRuntimeError::new_err(format!("{:?}", error))
|
||||
}
|
||||
}
|
||||
21
third-party/vendor/eyre/src/fmt.rs
vendored
Normal file
21
third-party/vendor/eyre/src/fmt.rs
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
use crate::{error::ErrorImpl, ptr::RefPtr};
|
||||
use core::fmt;
|
||||
|
||||
impl ErrorImpl<()> {
|
||||
pub(crate) fn display(this: RefPtr<'_, Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
ErrorImpl::header(this)
|
||||
.handler
|
||||
.as_ref()
|
||||
.map(|handler| handler.display(Self::error(this), f))
|
||||
.unwrap_or_else(|| core::fmt::Display::fmt(Self::error(this), f))
|
||||
}
|
||||
|
||||
/// Debug formats the error using the captured handler
|
||||
pub(crate) fn debug(this: RefPtr<'_, Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
ErrorImpl::header(this)
|
||||
.handler
|
||||
.as_ref()
|
||||
.map(|handler| handler.debug(Self::error(this), f))
|
||||
.unwrap_or_else(|| core::fmt::Debug::fmt(Self::error(this), f))
|
||||
}
|
||||
}
|
||||
111
third-party/vendor/eyre/src/kind.rs
vendored
Normal file
111
third-party/vendor/eyre/src/kind.rs
vendored
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#![allow(missing_debug_implementations, missing_docs)]
|
||||
// Tagged dispatch mechanism for resolving the behavior of `eyre!($expr)`.
|
||||
//
|
||||
// When eyre! is given a single expr argument to turn into eyre::Report, we
|
||||
// want the resulting Report to pick up the input's implementation of source()
|
||||
// and backtrace() if it has a std::error::Error impl, otherwise require nothing
|
||||
// more than Display and Debug.
|
||||
//
|
||||
// Expressed in terms of specialization, we want something like:
|
||||
//
|
||||
// trait EyreNew {
|
||||
// fn new(self) -> Report;
|
||||
// }
|
||||
//
|
||||
// impl<T> EyreNew for T
|
||||
// where
|
||||
// T: Display + Debug + Send + Sync + 'static,
|
||||
// {
|
||||
// default fn new(self) -> Report {
|
||||
// /* no std error impl */
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl<T> EyreNew for T
|
||||
// where
|
||||
// T: std::error::Error + Send + Sync + 'static,
|
||||
// {
|
||||
// fn new(self) -> Report {
|
||||
// /* use std error's source() and backtrace() */
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Since specialization is not stable yet, instead we rely on autoref behavior
|
||||
// of method resolution to perform tagged dispatch. Here we have two traits
|
||||
// AdhocKind and TraitKind that both have an eyre_kind() method. AdhocKind is
|
||||
// implemented whether or not the caller's type has a std error impl, while
|
||||
// TraitKind is implemented only when a std error impl does exist. The ambiguity
|
||||
// is resolved by AdhocKind requiring an extra autoref so that it has lower
|
||||
// precedence.
|
||||
//
|
||||
// The eyre! macro will set up the call in this form:
|
||||
//
|
||||
// #[allow(unused_imports)]
|
||||
// use $crate::private::{AdhocKind, TraitKind};
|
||||
// let error = $msg;
|
||||
// (&error).eyre_kind().new(error)
|
||||
|
||||
use crate::Report;
|
||||
use core::fmt::{Debug, Display};
|
||||
|
||||
use crate::StdError;
|
||||
|
||||
pub struct Adhoc;
|
||||
|
||||
pub trait AdhocKind: Sized {
|
||||
#[inline]
|
||||
fn eyre_kind(&self) -> Adhoc {
|
||||
Adhoc
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AdhocKind for &T where T: ?Sized + Display + Debug + Send + Sync + 'static {}
|
||||
|
||||
impl Adhoc {
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub fn new<M>(self, message: M) -> Report
|
||||
where
|
||||
M: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
Report::from_adhoc(message)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Trait;
|
||||
|
||||
pub trait TraitKind: Sized {
|
||||
#[inline]
|
||||
fn eyre_kind(&self) -> Trait {
|
||||
Trait
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> TraitKind for E where E: Into<Report> {}
|
||||
|
||||
impl Trait {
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub fn new<E>(self, error: E) -> Report
|
||||
where
|
||||
E: Into<Report>,
|
||||
{
|
||||
error.into()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Boxed;
|
||||
|
||||
pub trait BoxedKind: Sized {
|
||||
#[inline]
|
||||
fn eyre_kind(&self) -> Boxed {
|
||||
Boxed
|
||||
}
|
||||
}
|
||||
|
||||
impl BoxedKind for Box<dyn StdError + Send + Sync> {}
|
||||
|
||||
impl Boxed {
|
||||
#[cfg_attr(track_caller, track_caller)]
|
||||
pub fn new(self, error: Box<dyn StdError + Send + Sync>) -> Report {
|
||||
Report::from_boxed(error)
|
||||
}
|
||||
}
|
||||
1322
third-party/vendor/eyre/src/lib.rs
vendored
Normal file
1322
third-party/vendor/eyre/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load diff
170
third-party/vendor/eyre/src/macros.rs
vendored
Normal file
170
third-party/vendor/eyre/src/macros.rs
vendored
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/// Return early with an error.
|
||||
///
|
||||
/// This macro is equivalent to `return Err(eyre!(<args>))`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use eyre::{bail, Result};
|
||||
/// #
|
||||
/// # fn has_permission(user: usize, resource: usize) -> bool {
|
||||
/// # true
|
||||
/// # }
|
||||
/// #
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let user = 0;
|
||||
/// # let resource = 0;
|
||||
/// #
|
||||
/// if !has_permission(user, resource) {
|
||||
/// bail!("permission denied for accessing {}", resource);
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// # use eyre::{bail, Result};
|
||||
/// # use thiserror::Error;
|
||||
/// #
|
||||
/// # const MAX_DEPTH: usize = 1;
|
||||
/// #
|
||||
/// #[derive(Error, Debug)]
|
||||
/// enum ScienceError {
|
||||
/// #[error("recursion limit exceeded")]
|
||||
/// RecursionLimitExceeded,
|
||||
/// # #[error("...")]
|
||||
/// # More = (stringify! {
|
||||
/// ...
|
||||
/// # }, 1).1,
|
||||
/// }
|
||||
///
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let depth = 0;
|
||||
/// # let err: &'static dyn std::error::Error = &ScienceError::RecursionLimitExceeded;
|
||||
/// #
|
||||
/// if depth > MAX_DEPTH {
|
||||
/// bail!(ScienceError::RecursionLimitExceeded);
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! bail {
|
||||
($msg:literal $(,)?) => {
|
||||
return $crate::private::Err($crate::eyre!($msg));
|
||||
};
|
||||
($err:expr $(,)?) => {
|
||||
return $crate::private::Err($crate::eyre!($err));
|
||||
};
|
||||
($fmt:expr, $($arg:tt)*) => {
|
||||
return $crate::private::Err($crate::eyre!($fmt, $($arg)*));
|
||||
};
|
||||
}
|
||||
|
||||
/// Return early with an error if a condition is not satisfied.
|
||||
///
|
||||
/// This macro is equivalent to `if !$cond { return Err(eyre!(<other args>)); }`.
|
||||
///
|
||||
/// Analogously to `assert!`, `ensure!` takes a condition and exits the function
|
||||
/// if the condition fails. Unlike `assert!`, `ensure!` returns an `eyre::Result`
|
||||
/// rather than panicking.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use eyre::{ensure, Result};
|
||||
/// #
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let user = 0;
|
||||
/// #
|
||||
/// ensure!(user == 0, "only user 0 is allowed");
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// # use eyre::{ensure, Result};
|
||||
/// # use thiserror::Error;
|
||||
/// #
|
||||
/// # const MAX_DEPTH: usize = 1;
|
||||
/// #
|
||||
/// #[derive(Error, Debug)]
|
||||
/// enum ScienceError {
|
||||
/// #[error("recursion limit exceeded")]
|
||||
/// RecursionLimitExceeded,
|
||||
/// # #[error("...")]
|
||||
/// # More = (stringify! {
|
||||
/// ...
|
||||
/// # }, 1).1,
|
||||
/// }
|
||||
///
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let depth = 0;
|
||||
/// #
|
||||
/// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! ensure {
|
||||
($cond:expr $(,)?) => {
|
||||
if !$cond {
|
||||
$crate::ensure!($cond, concat!("Condition failed: `", stringify!($cond), "`"))
|
||||
}
|
||||
};
|
||||
($cond:expr, $msg:literal $(,)?) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::eyre!($msg));
|
||||
}
|
||||
};
|
||||
($cond:expr, $err:expr $(,)?) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::eyre!($err));
|
||||
}
|
||||
};
|
||||
($cond:expr, $fmt:expr, $($arg:tt)*) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::eyre!($fmt, $($arg)*));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Construct an ad-hoc error from a string.
|
||||
///
|
||||
/// This evaluates to a `Report`. It can take either just a string, or a format
|
||||
/// string with arguments. It also can take any custom type which implements
|
||||
/// `Debug` and `Display`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # type V = ();
|
||||
/// #
|
||||
/// use eyre::{eyre, Result};
|
||||
///
|
||||
/// fn lookup(key: &str) -> Result<V> {
|
||||
/// if key.len() != 16 {
|
||||
/// return Err(eyre!("key length must be 16 characters, got {:?}", key));
|
||||
/// }
|
||||
///
|
||||
/// // ...
|
||||
/// # Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! eyre {
|
||||
($msg:literal $(,)?) => ({
|
||||
let error = $crate::private::format_err($crate::private::format_args!($msg));
|
||||
error
|
||||
});
|
||||
($err:expr $(,)?) => ({
|
||||
use $crate::private::kind::*;
|
||||
let error = match $err {
|
||||
error => (&error).eyre_kind().new(error),
|
||||
};
|
||||
error
|
||||
});
|
||||
($fmt:expr, $($arg:tt)*) => {
|
||||
$crate::private::new_adhoc($crate::private::format!($fmt, $($arg)*))
|
||||
};
|
||||
}
|
||||
15
third-party/vendor/eyre/src/option.rs
vendored
Normal file
15
third-party/vendor/eyre/src/option.rs
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use crate::OptionExt;
|
||||
use core::fmt::{Debug, Display};
|
||||
|
||||
impl<T> OptionExt<T> for Option<T> {
|
||||
#[track_caller]
|
||||
fn ok_or_eyre<M>(self, message: M) -> crate::Result<T>
|
||||
where
|
||||
M: Debug + Display + Send + Sync + 'static,
|
||||
{
|
||||
match self {
|
||||
Some(ok) => Ok(ok),
|
||||
None => Err(crate::Report::msg(message)),
|
||||
}
|
||||
}
|
||||
}
|
||||
149
third-party/vendor/eyre/src/ptr.rs
vendored
Normal file
149
third-party/vendor/eyre/src/ptr.rs
vendored
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
use std::{marker::PhantomData, ptr::NonNull};
|
||||
|
||||
/// An owned pointer
|
||||
///
|
||||
/// **NOTE**: Does not deallocate when dropped
|
||||
pub(crate) struct OwnedPtr<T: ?Sized> {
|
||||
ptr: NonNull<T>,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Copy for OwnedPtr<T> {}
|
||||
|
||||
impl<T: ?Sized> Clone for OwnedPtr<T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for OwnedPtr<T> where T: Send {}
|
||||
unsafe impl<T> Sync for OwnedPtr<T> where T: Send {}
|
||||
|
||||
impl<T> OwnedPtr<T> {
|
||||
pub(crate) fn new(value: T) -> Self {
|
||||
Self::from_boxed(Box::new(value))
|
||||
}
|
||||
|
||||
pub(crate) fn from_boxed(boxed: Box<T>) -> Self {
|
||||
// Safety: `Box::into_raw` is guaranteed to be non-null
|
||||
Self {
|
||||
ptr: unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) },
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the pointer to another type
|
||||
pub(crate) fn cast<U>(self) -> OwnedPtr<U> {
|
||||
OwnedPtr {
|
||||
ptr: self.ptr.cast(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Context the pointer into a Box
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Dropping the Box will deallocate a layout of `T` and run the destructor of `T`.
|
||||
///
|
||||
/// A cast pointer must therefore be cast back to the original type before calling this method.
|
||||
pub(crate) unsafe fn into_box(self) -> Box<T> {
|
||||
unsafe { Box::from_raw(self.ptr.as_ptr()) }
|
||||
}
|
||||
|
||||
pub(crate) const fn as_ref(&self) -> RefPtr<'_, T> {
|
||||
RefPtr {
|
||||
ptr: self.ptr,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn as_mut(&mut self) -> MutPtr<'_, T> {
|
||||
MutPtr {
|
||||
ptr: self.ptr,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience lifetime annotated mutable pointer which facilitates returning an inferred lifetime
|
||||
/// in a `fn` pointer.
|
||||
pub(crate) struct RefPtr<'a, T: ?Sized> {
|
||||
pub(crate) ptr: NonNull<T>,
|
||||
_marker: PhantomData<&'a T>,
|
||||
}
|
||||
|
||||
/// Safety: RefPtr indicates a shared reference to a value and as such exhibits the same Send +
|
||||
/// Sync behavior of &'a T
|
||||
unsafe impl<'a, T: ?Sized> Send for RefPtr<'a, T> where &'a T: Send {}
|
||||
unsafe impl<'a, T: ?Sized> Sync for RefPtr<'a, T> where &'a T: Sync {}
|
||||
|
||||
impl<'a, T: ?Sized> Copy for RefPtr<'a, T> {}
|
||||
impl<'a, T: ?Sized> Clone for RefPtr<'a, T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> RefPtr<'a, T> {
|
||||
pub(crate) fn new(ptr: &'a T) -> Self {
|
||||
Self {
|
||||
ptr: NonNull::from(ptr),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the pointer to another type
|
||||
pub(crate) fn cast<U>(self) -> RefPtr<'a, U> {
|
||||
RefPtr {
|
||||
ptr: self.ptr.cast(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a shared reference to the owned value
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// See: [`NonNull::as_ref`]
|
||||
#[inline]
|
||||
pub(crate) unsafe fn as_ref(&self) -> &'a T {
|
||||
unsafe { self.ptr.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience lifetime annotated mutable pointer which facilitates returning an inferred lifetime
|
||||
/// in a `fn` pointer.
|
||||
pub(crate) struct MutPtr<'a, T: ?Sized> {
|
||||
pub(crate) ptr: NonNull<T>,
|
||||
_marker: PhantomData<&'a mut T>,
|
||||
}
|
||||
|
||||
/// Safety: RefPtr indicates an exclusive reference to a value and as such exhibits the same Send +
|
||||
/// Sync behavior of &'a mut T
|
||||
unsafe impl<'a, T: ?Sized> Send for MutPtr<'a, T> where &'a mut T: Send {}
|
||||
unsafe impl<'a, T: ?Sized> Sync for MutPtr<'a, T> where &'a mut T: Sync {}
|
||||
|
||||
impl<'a, T: ?Sized> Copy for MutPtr<'a, T> {}
|
||||
impl<'a, T: ?Sized> Clone for MutPtr<'a, T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> MutPtr<'a, T> {
|
||||
/// Convert the pointer to another type
|
||||
pub(crate) fn cast<U>(self) -> MutPtr<'a, U> {
|
||||
MutPtr {
|
||||
ptr: self.ptr.cast(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the owned value with the lifetime decoupled from self
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// See: [`NonNull::as_mut`]
|
||||
#[inline]
|
||||
pub(crate) unsafe fn into_mut(mut self) -> &'a mut T {
|
||||
unsafe { self.ptr.as_mut() }
|
||||
}
|
||||
}
|
||||
93
third-party/vendor/eyre/src/wrapper.rs
vendored
Normal file
93
third-party/vendor/eyre/src/wrapper.rs
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
use crate::StdError;
|
||||
use core::fmt::{self, Debug, Display};
|
||||
|
||||
#[repr(transparent)]
|
||||
pub(crate) struct DisplayError<M>(pub(crate) M);
|
||||
|
||||
#[repr(transparent)]
|
||||
/// Wraps a Debug + Display type as an error.
|
||||
///
|
||||
/// Its Debug and Display impls are the same as the wrapped type.
|
||||
pub(crate) struct MessageError<M>(pub(crate) M);
|
||||
|
||||
pub(crate) struct NoneError;
|
||||
|
||||
impl<M> Debug for DisplayError<M>
|
||||
where
|
||||
M: Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> Display for DisplayError<M>
|
||||
where
|
||||
M: Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> StdError for DisplayError<M> where M: Display + 'static {}
|
||||
|
||||
impl<M> Debug for MessageError<M>
|
||||
where
|
||||
M: Display + Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Debug::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> Display for MessageError<M>
|
||||
where
|
||||
M: Display + Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}
|
||||
|
||||
impl Debug for NoneError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Debug::fmt("Option was None", f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for NoneError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Display::fmt("Option was None", f)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for NoneError {}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub(crate) struct BoxedError(pub(crate) Box<dyn StdError + Send + Sync>);
|
||||
|
||||
impl Debug for BoxedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Debug::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for BoxedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for BoxedError {
|
||||
#[cfg(backtrace)]
|
||||
fn backtrace(&self) -> Option<&crate::backtrace::Backtrace> {
|
||||
self.0.backtrace()
|
||||
}
|
||||
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
self.0.source()
|
||||
}
|
||||
}
|
||||
29
third-party/vendor/eyre/tests/common/mod.rs
vendored
Normal file
29
third-party/vendor/eyre/tests/common/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use eyre::{bail, set_hook, DefaultHandler, InstallError, Result};
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::io;
|
||||
|
||||
pub fn bail_literal() -> Result<()> {
|
||||
bail!("oh no!");
|
||||
}
|
||||
|
||||
pub fn bail_fmt() -> Result<()> {
|
||||
bail!("{} {}!", "oh", "no");
|
||||
}
|
||||
|
||||
pub fn bail_error() -> Result<()> {
|
||||
bail!(io::Error::new(io::ErrorKind::Other, "oh no!"));
|
||||
}
|
||||
|
||||
// Tests are multithreaded- use OnceCell to install hook once if auto-install
|
||||
// feature is disabled.
|
||||
pub fn maybe_install_handler() -> Result<(), InstallError> {
|
||||
static INSTALLER: OnceCell<Result<(), InstallError>> = OnceCell::new();
|
||||
|
||||
if cfg!(not(feature = "auto-install")) {
|
||||
*INSTALLER.get_or_init(|| set_hook(Box::new(DefaultHandler::default_with)))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
7
third-party/vendor/eyre/tests/compiletest.rs
vendored
Normal file
7
third-party/vendor/eyre/tests/compiletest.rs
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#[rustversion::attr(not(nightly), ignore)]
|
||||
#[cfg_attr(miri, ignore)]
|
||||
#[test]
|
||||
fn ui() {
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/ui/*.rs");
|
||||
}
|
||||
55
third-party/vendor/eyre/tests/drop/mod.rs
vendored
Normal file
55
third-party/vendor/eyre/tests/drop/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
use std::error::Error as StdError;
|
||||
use std::fmt::{self, Display};
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::atomic::Ordering::SeqCst;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Flag {
|
||||
atomic: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl Flag {
|
||||
pub fn new() -> Self {
|
||||
Flag {
|
||||
atomic: Arc::new(AtomicBool::new(false)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> bool {
|
||||
self.atomic.load(SeqCst)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DetectDrop {
|
||||
has_dropped: Flag,
|
||||
label: &'static str,
|
||||
}
|
||||
|
||||
impl DetectDrop {
|
||||
pub fn new(label: &'static str, has_dropped: &Flag) -> Self {
|
||||
DetectDrop {
|
||||
label,
|
||||
has_dropped: Flag {
|
||||
atomic: Arc::clone(&has_dropped.atomic),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for DetectDrop {}
|
||||
|
||||
impl Display for DetectDrop {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "oh no!")
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DetectDrop {
|
||||
fn drop(&mut self) {
|
||||
eprintln!("Dropping {}", self.label);
|
||||
let already_dropped = self.has_dropped.atomic.swap(true, SeqCst);
|
||||
assert!(!already_dropped);
|
||||
}
|
||||
}
|
||||
13
third-party/vendor/eyre/tests/test_autotrait.rs
vendored
Normal file
13
third-party/vendor/eyre/tests/test_autotrait.rs
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
use eyre::Report;
|
||||
|
||||
#[test]
|
||||
fn test_send() {
|
||||
fn assert_send<T: Send>() {}
|
||||
assert_send::<Report>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sync() {
|
||||
fn assert_sync<T: Sync>() {}
|
||||
assert_sync::<Report>();
|
||||
}
|
||||
66
third-party/vendor/eyre/tests/test_boxed.rs
vendored
Normal file
66
third-party/vendor/eyre/tests/test_boxed.rs
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
mod common;
|
||||
|
||||
use self::common::maybe_install_handler;
|
||||
use eyre::{eyre, Report};
|
||||
use std::error::Error as StdError;
|
||||
use std::io;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[error("outer")]
|
||||
struct MyError {
|
||||
source: io::Error,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxed_str() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let error = Box::<dyn StdError + Send + Sync>::from("oh no!");
|
||||
let error: Report = eyre!(error);
|
||||
assert_eq!("oh no!", error.to_string());
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
error
|
||||
.downcast_ref::<Box<dyn StdError + Send + Sync>>()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxed_thiserror() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let error = MyError {
|
||||
source: io::Error::new(io::ErrorKind::Other, "oh no!"),
|
||||
};
|
||||
let error: Report = eyre!(error);
|
||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxed_eyre() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let error: Report = eyre!("oh no!").wrap_err("it failed");
|
||||
let error = eyre!(error);
|
||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxed_sources() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let error = MyError {
|
||||
source: io::Error::new(io::ErrorKind::Other, "oh no!"),
|
||||
};
|
||||
let error = Box::<dyn StdError + Send + Sync>::from(error);
|
||||
let error: Report = eyre!(error).wrap_err("it failed");
|
||||
assert_eq!("it failed", error.to_string());
|
||||
assert_eq!("outer", error.source().unwrap().to_string());
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
error.source().unwrap().source().unwrap().to_string()
|
||||
);
|
||||
}
|
||||
54
third-party/vendor/eyre/tests/test_chain.rs
vendored
Normal file
54
third-party/vendor/eyre/tests/test_chain.rs
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
mod common;
|
||||
|
||||
use self::common::maybe_install_handler;
|
||||
use eyre::{eyre, Report};
|
||||
|
||||
fn error() -> Report {
|
||||
eyre!({ 0 }).wrap_err(1).wrap_err(2).wrap_err(3)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let e = error();
|
||||
let mut chain = e.chain();
|
||||
assert_eq!("3", chain.next().unwrap().to_string());
|
||||
assert_eq!("2", chain.next().unwrap().to_string());
|
||||
assert_eq!("1", chain.next().unwrap().to_string());
|
||||
assert_eq!("0", chain.next().unwrap().to_string());
|
||||
assert!(chain.next().is_none());
|
||||
assert!(chain.next_back().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let e = error();
|
||||
let mut chain = e.chain().rev();
|
||||
assert_eq!("0", chain.next().unwrap().to_string());
|
||||
assert_eq!("1", chain.next().unwrap().to_string());
|
||||
assert_eq!("2", chain.next().unwrap().to_string());
|
||||
assert_eq!("3", chain.next().unwrap().to_string());
|
||||
assert!(chain.next().is_none());
|
||||
assert!(chain.next_back().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_len() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let e = error();
|
||||
let mut chain = e.chain();
|
||||
assert_eq!(4, chain.len());
|
||||
assert_eq!("3", chain.next().unwrap().to_string());
|
||||
assert_eq!(3, chain.len());
|
||||
assert_eq!("0", chain.next_back().unwrap().to_string());
|
||||
assert_eq!(2, chain.len());
|
||||
assert_eq!("2", chain.next().unwrap().to_string());
|
||||
assert_eq!(1, chain.len());
|
||||
assert_eq!("1", chain.next_back().unwrap().to_string());
|
||||
assert_eq!(0, chain.len());
|
||||
assert!(chain.next().is_none());
|
||||
}
|
||||
173
third-party/vendor/eyre/tests/test_context.rs
vendored
Normal file
173
third-party/vendor/eyre/tests/test_context.rs
vendored
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
mod common;
|
||||
mod drop;
|
||||
|
||||
use crate::common::maybe_install_handler;
|
||||
use crate::drop::{DetectDrop, Flag};
|
||||
use eyre::{Report, Result, WrapErr};
|
||||
use std::fmt::{self, Display};
|
||||
use thiserror::Error;
|
||||
|
||||
// https://github.com/dtolnay/eyre/issues/18
|
||||
#[test]
|
||||
fn test_inference() -> Result<()> {
|
||||
let x = "1";
|
||||
let y: u32 = x.parse().wrap_err("...")?;
|
||||
assert_eq!(y, 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
macro_rules! context_type {
|
||||
($name:ident) => {
|
||||
#[derive(Debug)]
|
||||
#[repr(C)]
|
||||
struct $name {
|
||||
_drop: DetectDrop,
|
||||
message: &'static str,
|
||||
}
|
||||
|
||||
impl Display for $name {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(self.message)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
context_type!(HighLevel);
|
||||
context_type!(MidLevel);
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[error("{message}")]
|
||||
#[repr(C)]
|
||||
struct LowLevel {
|
||||
message: &'static str,
|
||||
drop: DetectDrop,
|
||||
}
|
||||
|
||||
struct Dropped {
|
||||
low: Flag,
|
||||
mid: Flag,
|
||||
high: Flag,
|
||||
}
|
||||
|
||||
impl Dropped {
|
||||
fn none(&self) -> bool {
|
||||
!self.low.get() && !self.mid.get() && !self.high.get()
|
||||
}
|
||||
|
||||
fn all(&self) -> bool {
|
||||
self.low.get() && self.mid.get() && self.high.get()
|
||||
}
|
||||
}
|
||||
|
||||
fn make_chain() -> (Report, Dropped) {
|
||||
let dropped = Dropped {
|
||||
low: Flag::new(),
|
||||
mid: Flag::new(),
|
||||
high: Flag::new(),
|
||||
};
|
||||
|
||||
let low = LowLevel {
|
||||
message: "no such file or directory",
|
||||
drop: DetectDrop::new("LowLevel", &dropped.low),
|
||||
};
|
||||
|
||||
// impl Report for Result<T, E>
|
||||
let mid = Err::<(), LowLevel>(low)
|
||||
.wrap_err(MidLevel {
|
||||
message: "failed to load config",
|
||||
_drop: DetectDrop::new("MidLevel", &dropped.mid),
|
||||
})
|
||||
.unwrap_err();
|
||||
|
||||
// impl Report for Result<T, Error>
|
||||
let high = Err::<(), Report>(mid)
|
||||
.wrap_err(HighLevel {
|
||||
message: "failed to start server",
|
||||
_drop: DetectDrop::new("HighLevel", &dropped.high),
|
||||
})
|
||||
.unwrap_err();
|
||||
|
||||
(high, dropped)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_ref() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let (err, dropped) = make_chain();
|
||||
|
||||
assert!(!err.is::<String>());
|
||||
assert!(err.downcast_ref::<String>().is_none());
|
||||
|
||||
assert!(err.is::<HighLevel>());
|
||||
let high = err.downcast_ref::<HighLevel>().unwrap();
|
||||
assert_eq!(high.to_string(), "failed to start server");
|
||||
|
||||
assert!(err.is::<MidLevel>());
|
||||
let mid = err.downcast_ref::<MidLevel>().unwrap();
|
||||
assert_eq!(mid.to_string(), "failed to load config");
|
||||
|
||||
assert!(err.is::<LowLevel>());
|
||||
let low = err.downcast_ref::<LowLevel>().unwrap();
|
||||
assert_eq!(low.to_string(), "no such file or directory");
|
||||
|
||||
assert!(dropped.none());
|
||||
drop(err);
|
||||
assert!(dropped.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_high() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let (err, dropped) = make_chain();
|
||||
|
||||
let err = err.downcast::<HighLevel>().unwrap();
|
||||
assert!(!dropped.high.get());
|
||||
assert!(dropped.low.get() && dropped.mid.get());
|
||||
|
||||
drop(err);
|
||||
assert!(dropped.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_mid() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let (err, dropped) = make_chain();
|
||||
|
||||
let err = err.downcast::<MidLevel>().unwrap();
|
||||
assert!(!dropped.mid.get());
|
||||
assert!(dropped.low.get() && dropped.high.get());
|
||||
|
||||
drop(err);
|
||||
assert!(dropped.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_low() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let (err, dropped) = make_chain();
|
||||
|
||||
let err = err.downcast::<LowLevel>().unwrap();
|
||||
assert!(!dropped.low.get());
|
||||
assert!(dropped.mid.get() && dropped.high.get());
|
||||
|
||||
drop(err);
|
||||
assert!(dropped.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsuccessful_downcast() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let (err, dropped) = make_chain();
|
||||
|
||||
let err = err.downcast::<String>().unwrap_err();
|
||||
assert!(dropped.none());
|
||||
|
||||
drop(err);
|
||||
assert!(dropped.all());
|
||||
}
|
||||
13
third-party/vendor/eyre/tests/test_context_access.rs
vendored
Normal file
13
third-party/vendor/eyre/tests/test_context_access.rs
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
mod common;
|
||||
|
||||
use crate::common::maybe_install_handler;
|
||||
|
||||
#[test]
|
||||
fn test_context() {
|
||||
use eyre::{eyre, Report};
|
||||
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let error: Report = eyre!("oh no!");
|
||||
let _ = error.context();
|
||||
}
|
||||
28
third-party/vendor/eyre/tests/test_convert.rs
vendored
Normal file
28
third-party/vendor/eyre/tests/test_convert.rs
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
mod common;
|
||||
mod drop;
|
||||
|
||||
use self::common::maybe_install_handler;
|
||||
use self::drop::{DetectDrop, Flag};
|
||||
use eyre::{Report, Result};
|
||||
use std::error::Error as StdError;
|
||||
|
||||
#[test]
|
||||
fn test_convert() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let has_dropped = Flag::new();
|
||||
let error: Report = Report::new(DetectDrop::new("TestConvert", &has_dropped));
|
||||
let box_dyn = Box::<dyn StdError + Send + Sync>::from(error);
|
||||
assert_eq!("oh no!", box_dyn.to_string());
|
||||
drop(box_dyn);
|
||||
assert!(has_dropped.get());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_question_mark() -> Result<(), Box<dyn StdError>> {
|
||||
fn f() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
f()?;
|
||||
Ok(())
|
||||
}
|
||||
148
third-party/vendor/eyre/tests/test_downcast.rs
vendored
Normal file
148
third-party/vendor/eyre/tests/test_downcast.rs
vendored
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
mod common;
|
||||
mod drop;
|
||||
|
||||
use self::common::*;
|
||||
use self::drop::{DetectDrop, Flag};
|
||||
use eyre::Report;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt::{self, Display};
|
||||
use std::io;
|
||||
|
||||
#[test]
|
||||
fn test_downcast() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
#[cfg(not(eyre_no_fmt_arguments_as_str))]
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_literal().unwrap_err().downcast::<&str>().unwrap(),
|
||||
);
|
||||
|
||||
#[cfg(eyre_no_fmt_arguments_as_str)]
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_literal().unwrap_err().downcast::<String>().unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_fmt().unwrap_err().downcast::<String>().unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_error()
|
||||
.unwrap_err()
|
||||
.downcast::<io::Error>()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_ref() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
#[cfg(not(eyre_no_fmt_arguments_as_str))]
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
*bail_literal().unwrap_err().downcast_ref::<&str>().unwrap(),
|
||||
);
|
||||
|
||||
#[cfg(eyre_no_fmt_arguments_as_str)]
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
*bail_literal()
|
||||
.unwrap_err()
|
||||
.downcast_ref::<String>()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_fmt().unwrap_err().downcast_ref::<String>().unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_error()
|
||||
.unwrap_err()
|
||||
.downcast_ref::<io::Error>()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_mut() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
#[cfg(not(eyre_no_fmt_arguments_as_str))]
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
*bail_literal().unwrap_err().downcast_mut::<&str>().unwrap(),
|
||||
);
|
||||
|
||||
#[cfg(eyre_no_fmt_arguments_as_str)]
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
*bail_literal()
|
||||
.unwrap_err()
|
||||
.downcast_mut::<String>()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_fmt().unwrap_err().downcast_mut::<String>().unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_error()
|
||||
.unwrap_err()
|
||||
.downcast_mut::<io::Error>()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let has_dropped = Flag::new();
|
||||
let error: Report = Report::new(DetectDrop::new("DetectDrop", &has_dropped));
|
||||
drop(error.downcast::<DetectDrop>().unwrap());
|
||||
assert!(has_dropped.get());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_large_alignment() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
#[repr(align(64))]
|
||||
#[derive(Debug)]
|
||||
struct LargeAlignedError(&'static str);
|
||||
|
||||
impl Display for LargeAlignedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for LargeAlignedError {}
|
||||
|
||||
let error = Report::new(LargeAlignedError("oh no!"));
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
error.downcast_ref::<LargeAlignedError>().unwrap().0
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsuccessful_downcast() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let mut error = bail_error().unwrap_err();
|
||||
assert!(error.downcast_ref::<&str>().is_none());
|
||||
assert!(error.downcast_mut::<&str>().is_none());
|
||||
assert!(error.downcast::<&str>().is_err());
|
||||
}
|
||||
105
third-party/vendor/eyre/tests/test_fmt.rs
vendored
Normal file
105
third-party/vendor/eyre/tests/test_fmt.rs
vendored
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
mod common;
|
||||
|
||||
use self::common::maybe_install_handler;
|
||||
use eyre::{bail, Result, WrapErr};
|
||||
use std::io;
|
||||
|
||||
fn f() -> Result<()> {
|
||||
bail!(io::Error::new(io::ErrorKind::PermissionDenied, "oh no!"));
|
||||
}
|
||||
|
||||
fn g() -> Result<()> {
|
||||
f().wrap_err("f failed")
|
||||
}
|
||||
|
||||
fn h() -> Result<()> {
|
||||
g().wrap_err("g failed")
|
||||
}
|
||||
|
||||
const EXPECTED_ALTDISPLAY_F: &str = "oh no!";
|
||||
|
||||
const EXPECTED_ALTDISPLAY_G: &str = "f failed: oh no!";
|
||||
|
||||
const EXPECTED_ALTDISPLAY_H: &str = "g failed: f failed: oh no!";
|
||||
|
||||
const EXPECTED_DEBUG_F: &str = "oh no!";
|
||||
|
||||
const EXPECTED_DEBUG_G: &str = "\
|
||||
f failed
|
||||
|
||||
Caused by:
|
||||
oh no!\
|
||||
";
|
||||
|
||||
const EXPECTED_DEBUG_H: &str = "\
|
||||
g failed
|
||||
|
||||
Caused by:
|
||||
0: f failed
|
||||
1: oh no!\
|
||||
";
|
||||
|
||||
const EXPECTED_ALTDEBUG_F: &str = "\
|
||||
Custom {
|
||||
kind: PermissionDenied,
|
||||
error: \"oh no!\",
|
||||
}\
|
||||
";
|
||||
|
||||
const EXPECTED_ALTDEBUG_G: &str = "\
|
||||
Error {
|
||||
msg: \"f failed\",
|
||||
source: Custom {
|
||||
kind: PermissionDenied,
|
||||
error: \"oh no!\",
|
||||
},
|
||||
}\
|
||||
";
|
||||
|
||||
const EXPECTED_ALTDEBUG_H: &str = "\
|
||||
Error {
|
||||
msg: \"g failed\",
|
||||
source: Error {
|
||||
msg: \"f failed\",
|
||||
source: Custom {
|
||||
kind: PermissionDenied,
|
||||
error: \"oh no!\",
|
||||
},
|
||||
},
|
||||
}\
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn test_display() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
assert_eq!("g failed", h().unwrap_err().to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_altdisplay() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
assert_eq!(EXPECTED_ALTDISPLAY_F, format!("{:#}", f().unwrap_err()));
|
||||
assert_eq!(EXPECTED_ALTDISPLAY_G, format!("{:#}", g().unwrap_err()));
|
||||
assert_eq!(EXPECTED_ALTDISPLAY_H, format!("{:#}", h().unwrap_err()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(any(backtrace, track_caller), ignore)]
|
||||
fn test_debug() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
assert_eq!(EXPECTED_DEBUG_F, format!("{:?}", f().unwrap_err()));
|
||||
assert_eq!(EXPECTED_DEBUG_G, format!("{:?}", g().unwrap_err()));
|
||||
assert_eq!(EXPECTED_DEBUG_H, format!("{:?}", h().unwrap_err()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_altdebug() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
assert_eq!(EXPECTED_ALTDEBUG_F, format!("{:#?}", f().unwrap_err()));
|
||||
assert_eq!(EXPECTED_ALTDEBUG_G, format!("{:#?}", g().unwrap_err()));
|
||||
assert_eq!(EXPECTED_ALTDEBUG_H, format!("{:#?}", h().unwrap_err()));
|
||||
}
|
||||
183
third-party/vendor/eyre/tests/test_location.rs
vendored
Normal file
183
third-party/vendor/eyre/tests/test_location.rs
vendored
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
use std::panic::Location;
|
||||
|
||||
use eyre::{OptionExt as _, WrapErr};
|
||||
|
||||
struct LocationHandler {
|
||||
actual: Option<&'static str>,
|
||||
expected: &'static str,
|
||||
}
|
||||
|
||||
impl LocationHandler {
|
||||
fn new(expected: &'static str) -> Self {
|
||||
LocationHandler {
|
||||
actual: None,
|
||||
expected,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl eyre::EyreHandler for LocationHandler {
|
||||
fn debug(
|
||||
&self,
|
||||
_error: &(dyn std::error::Error + 'static),
|
||||
_f: &mut std::fmt::Formatter<'_>,
|
||||
) -> std::fmt::Result {
|
||||
// we assume that if the compiler is new enough to support
|
||||
// `track_caller` that we will always have `actual` be `Some`, so we can
|
||||
// safely skip the assertion if the location is `None` which should only
|
||||
// happen in older rust versions.
|
||||
if let Some(actual) = self.actual {
|
||||
assert_eq!(self.expected, actual);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn track_caller(&mut self, location: &'static Location<'static>) {
|
||||
dbg!(location);
|
||||
self.actual = Some(location.file());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_err() {
|
||||
let _ = eyre::set_hook(Box::new(|_e| {
|
||||
let expected_location = file!();
|
||||
Box::new(LocationHandler::new(expected_location))
|
||||
}));
|
||||
|
||||
let err = read_path("totally_fake_path")
|
||||
.wrap_err("oopsie")
|
||||
.unwrap_err();
|
||||
|
||||
// should panic if the location isn't in our crate
|
||||
println!("{:?}", err);
|
||||
}
|
||||
|
||||
#[cfg(not(miri))]
|
||||
fn read_path(path: &str) -> Result<String, std::io::Error> {
|
||||
std::fs::read_to_string(path)
|
||||
}
|
||||
|
||||
#[cfg(miri)]
|
||||
fn read_path(_path: &str) -> Result<String, std::io::Error> {
|
||||
// Miri doesn't support reading files, so we just return an error
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"Miri doesn't support reading files",
|
||||
))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_err_with() {
|
||||
let _ = eyre::set_hook(Box::new(|_e| {
|
||||
let expected_location = file!();
|
||||
Box::new(LocationHandler::new(expected_location))
|
||||
}));
|
||||
|
||||
let err = read_path("totally_fake_path")
|
||||
.wrap_err_with(|| "oopsie")
|
||||
.unwrap_err();
|
||||
|
||||
// should panic if the location isn't in our crate
|
||||
println!("{:?}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_ok_or_eyre() {
|
||||
let _ = eyre::set_hook(Box::new(|_e| {
|
||||
let expected_location = file!();
|
||||
Box::new(LocationHandler::new(expected_location))
|
||||
}));
|
||||
|
||||
let err = None::<()>.ok_or_eyre("oopsie").unwrap_err();
|
||||
|
||||
// should panic if the location isn't in our crate
|
||||
println!("{:?}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_context() {
|
||||
let _ = eyre::set_hook(Box::new(|_e| {
|
||||
let expected_location = file!();
|
||||
Box::new(LocationHandler::new(expected_location))
|
||||
}));
|
||||
|
||||
let err = read_path("totally_fake_path")
|
||||
.context("oopsie")
|
||||
.unwrap_err();
|
||||
|
||||
// should panic if the location isn't in our crate
|
||||
println!("{:?}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_context() {
|
||||
let _ = eyre::set_hook(Box::new(|_e| {
|
||||
let expected_location = file!();
|
||||
Box::new(LocationHandler::new(expected_location))
|
||||
}));
|
||||
|
||||
let err = read_path("totally_fake_path")
|
||||
.with_context(|| "oopsie")
|
||||
.unwrap_err();
|
||||
|
||||
// should panic if the location isn't in our crate
|
||||
println!("{:?}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_compat_wrap_err() {
|
||||
let _ = eyre::set_hook(Box::new(|_e| {
|
||||
let expected_location = file!();
|
||||
Box::new(LocationHandler::new(expected_location))
|
||||
}));
|
||||
|
||||
use eyre::ContextCompat;
|
||||
let err = None::<()>.wrap_err("oopsie").unwrap_err();
|
||||
|
||||
// should panic if the location isn't in our crate
|
||||
println!("{:?}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_compat_wrap_err_with() {
|
||||
let _ = eyre::set_hook(Box::new(|_e| {
|
||||
let expected_location = file!();
|
||||
Box::new(LocationHandler::new(expected_location))
|
||||
}));
|
||||
|
||||
use eyre::ContextCompat;
|
||||
let err = None::<()>.wrap_err_with(|| "oopsie").unwrap_err();
|
||||
|
||||
// should panic if the location isn't in our crate
|
||||
println!("{:?}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_compat_context() {
|
||||
let _ = eyre::set_hook(Box::new(|_e| {
|
||||
let expected_location = file!();
|
||||
Box::new(LocationHandler::new(expected_location))
|
||||
}));
|
||||
|
||||
use eyre::ContextCompat;
|
||||
let err = None::<()>.context("oopsie").unwrap_err();
|
||||
|
||||
// should panic if the location isn't in our crate
|
||||
println!("{:?}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_compat_with_context() {
|
||||
let _ = eyre::set_hook(Box::new(|_e| {
|
||||
let expected_location = file!();
|
||||
Box::new(LocationHandler::new(expected_location))
|
||||
}));
|
||||
|
||||
use eyre::ContextCompat;
|
||||
let err = None::<()>.with_context(|| "oopsie").unwrap_err();
|
||||
|
||||
// should panic if the location isn't in our crate
|
||||
println!("{:?}", err);
|
||||
}
|
||||
102
third-party/vendor/eyre/tests/test_macros.rs
vendored
Normal file
102
third-party/vendor/eyre/tests/test_macros.rs
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#![allow(clippy::eq_op)]
|
||||
mod common;
|
||||
|
||||
use self::common::*;
|
||||
use eyre::{ensure, eyre, Result};
|
||||
use std::cell::Cell;
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::task::Poll;
|
||||
|
||||
#[test]
|
||||
fn test_messages() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
assert_eq!("oh no!", bail_literal().unwrap_err().to_string());
|
||||
assert_eq!("oh no!", bail_fmt().unwrap_err().to_string());
|
||||
assert_eq!("oh no!", bail_error().unwrap_err().to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ensure() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let f = || -> Result<()> {
|
||||
ensure!(1 + 1 == 2, "This is correct");
|
||||
Ok(())
|
||||
};
|
||||
assert!(f().is_ok());
|
||||
|
||||
let v = 1;
|
||||
let f = || -> Result<()> {
|
||||
ensure!(v + v == 2, "This is correct, v: {}", v);
|
||||
Ok(())
|
||||
};
|
||||
assert!(f().is_ok());
|
||||
|
||||
let f = || -> Result<()> {
|
||||
ensure!(v + v == 1, "This is not correct, v: {}", v);
|
||||
Ok(())
|
||||
};
|
||||
assert!(f().is_err());
|
||||
|
||||
let f = || {
|
||||
ensure!(v + v == 1);
|
||||
Ok(())
|
||||
};
|
||||
assert_eq!(
|
||||
f().unwrap_err().to_string(),
|
||||
"Condition failed: `v + v == 1`",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_temporaries() {
|
||||
struct Ready<T>(Option<T>);
|
||||
|
||||
impl<T> Unpin for Ready<T> {}
|
||||
|
||||
impl<T> Future for Ready<T> {
|
||||
type Output = T;
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, _cx: &mut std::task::Context<'_>) -> Poll<T> {
|
||||
Poll::Ready(self.0.take().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
fn require_send_sync(_: impl Send + Sync) {}
|
||||
|
||||
require_send_sync(async {
|
||||
// If eyre hasn't dropped any temporary format_args it creates by the
|
||||
// time it's done evaluating, those will stick around until the
|
||||
// semicolon, which is on the other side of the await point, making the
|
||||
// enclosing future non-Send.
|
||||
let _ = Ready(Some(eyre!("..."))).await;
|
||||
});
|
||||
|
||||
fn message(cell: Cell<&str>) -> &str {
|
||||
cell.get()
|
||||
}
|
||||
|
||||
require_send_sync(async {
|
||||
let _ = Ready(Some(eyre!(message(Cell::new("..."))))).await;
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(eyre_no_fmt_args_capture))]
|
||||
fn test_capture_format_args() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let var = 42;
|
||||
let err = eyre!("interpolate {var}");
|
||||
assert_eq!("interpolate 42", err.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_brace_escape() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let err = eyre!("unterminated ${{..}} expression");
|
||||
assert_eq!("unterminated ${..} expression", err.to_string());
|
||||
}
|
||||
18
third-party/vendor/eyre/tests/test_no_install.rs
vendored
Normal file
18
third-party/vendor/eyre/tests/test_no_install.rs
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#![cfg(not(feature = "auto-install"))]
|
||||
|
||||
use eyre::{eyre, set_hook, DefaultHandler, Report};
|
||||
|
||||
#[test]
|
||||
fn test_no_hook_panic() {
|
||||
let panic_res = std::panic::catch_unwind(|| eyre!("this will never be displayed"));
|
||||
assert!(panic_res.is_err());
|
||||
|
||||
let downcast_res = panic_res.unwrap_err().downcast::<String>();
|
||||
assert_eq!(
|
||||
*downcast_res.unwrap(),
|
||||
"a handler must always be installed if the `auto-install` feature is disabled"
|
||||
);
|
||||
|
||||
assert!(set_hook(Box::new(DefaultHandler::default_with)).is_ok());
|
||||
let _error: Report = eyre!("this will be displayed if returned");
|
||||
}
|
||||
15
third-party/vendor/eyre/tests/test_option.rs
vendored
Normal file
15
third-party/vendor/eyre/tests/test_option.rs
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
mod common;
|
||||
|
||||
use self::common::maybe_install_handler;
|
||||
use eyre::OptionExt;
|
||||
|
||||
#[test]
|
||||
fn test_option_ok_or_eyre() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let option: Option<()> = None;
|
||||
|
||||
let result = option.ok_or_eyre("static str error");
|
||||
|
||||
assert_eq!(result.unwrap_err().to_string(), "static str error");
|
||||
}
|
||||
33
third-party/vendor/eyre/tests/test_pyo3.rs
vendored
Normal file
33
third-party/vendor/eyre/tests/test_pyo3.rs
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#![cfg(feature = "pyo3")]
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
use eyre::{bail, Result, WrapErr};
|
||||
|
||||
fn f() -> Result<()> {
|
||||
use std::io;
|
||||
bail!(io::Error::new(io::ErrorKind::PermissionDenied, "oh no!"));
|
||||
}
|
||||
|
||||
fn g() -> Result<()> {
|
||||
f().wrap_err("f failed")
|
||||
}
|
||||
|
||||
fn h() -> Result<()> {
|
||||
g().wrap_err("g failed")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pyo3_exception_contents() {
|
||||
use pyo3::types::IntoPyDict;
|
||||
|
||||
let err = h().unwrap_err();
|
||||
let expected_contents = format!("{:?}", err);
|
||||
let pyerr = PyErr::from(err);
|
||||
|
||||
Python::with_gil(|py| {
|
||||
let locals = [("err", pyerr)].into_py_dict(py);
|
||||
let pyerr = py.run("raise err", None, Some(locals)).unwrap_err();
|
||||
assert_eq!(pyerr.value(py).to_string(), expected_contents);
|
||||
})
|
||||
}
|
||||
36
third-party/vendor/eyre/tests/test_repr.rs
vendored
Normal file
36
third-party/vendor/eyre/tests/test_repr.rs
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
mod common;
|
||||
mod drop;
|
||||
|
||||
use self::common::maybe_install_handler;
|
||||
use self::drop::{DetectDrop, Flag};
|
||||
use eyre::Report;
|
||||
use std::marker::Unpin;
|
||||
use std::mem;
|
||||
|
||||
#[test]
|
||||
fn test_error_size() {
|
||||
assert_eq!(mem::size_of::<Report>(), mem::size_of::<usize>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_null_pointer_optimization() {
|
||||
assert_eq!(
|
||||
mem::size_of::<Result<(), Report>>(),
|
||||
mem::size_of::<usize>()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_autotraits() {
|
||||
fn assert<E: Unpin + Send + Sync + 'static>() {}
|
||||
assert::<Report>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let has_dropped = Flag::new();
|
||||
drop(Report::new(DetectDrop::new("TestDrop", &has_dropped)));
|
||||
assert!(has_dropped.get());
|
||||
}
|
||||
75
third-party/vendor/eyre/tests/test_source.rs
vendored
Normal file
75
third-party/vendor/eyre/tests/test_source.rs
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
mod common;
|
||||
|
||||
use self::common::maybe_install_handler;
|
||||
use eyre::{eyre, Report};
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt::{self, Display};
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum TestError {
|
||||
Io(io::Error),
|
||||
}
|
||||
|
||||
impl Display for TestError {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
TestError::Io(e) => Display::fmt(e, formatter),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for TestError {
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
match self {
|
||||
TestError::Io(io) => Some(io),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_literal_source() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let error: Report = eyre!("oh no!");
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_variable_source() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let msg = "oh no!";
|
||||
let error = eyre!(msg);
|
||||
assert!(error.source().is_none());
|
||||
|
||||
let msg = msg.to_owned();
|
||||
let error: Report = eyre!(msg);
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt_source() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let error: Report = eyre!("{} {}!", "oh", "no");
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_io_source() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let io = io::Error::new(io::ErrorKind::Other, "oh no!");
|
||||
let error: Report = eyre!(TestError::Io(io));
|
||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eyre_from_eyre() {
|
||||
maybe_install_handler().unwrap();
|
||||
|
||||
let error: Report = eyre!("oh no!").wrap_err("context");
|
||||
let error = eyre!(error);
|
||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||
}
|
||||
34
third-party/vendor/eyre/tests/test_toolchain.rs
vendored
Normal file
34
third-party/vendor/eyre/tests/test_toolchain.rs
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// These tests check our build script against rustversion.
|
||||
|
||||
#[rustversion::attr(not(nightly), ignore)]
|
||||
#[test]
|
||||
fn nightlytest() {
|
||||
if !cfg!(nightly) {
|
||||
panic!("nightly feature isn't set when the toolchain is nightly.");
|
||||
}
|
||||
if cfg!(any(beta, stable)) {
|
||||
panic!("beta, stable, and nightly are mutually exclusive features.")
|
||||
}
|
||||
}
|
||||
|
||||
#[rustversion::attr(not(beta), ignore)]
|
||||
#[test]
|
||||
fn betatest() {
|
||||
if !cfg!(beta) {
|
||||
panic!("beta feature is not set when the toolchain is beta.");
|
||||
}
|
||||
if cfg!(any(nightly, stable)) {
|
||||
panic!("beta, stable, and nightly are mutually exclusive features.")
|
||||
}
|
||||
}
|
||||
|
||||
#[rustversion::attr(not(stable), ignore)]
|
||||
#[test]
|
||||
fn stabletest() {
|
||||
if !cfg!(stable) {
|
||||
panic!("stable feature is not set when the toolchain is stable.");
|
||||
}
|
||||
if cfg!(any(nightly, beta)) {
|
||||
panic!("beta, stable, and nightly are mutually exclusive features.")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue