summaryrefslogtreecommitdiffstats
path: root/third_party/rust/error-chain
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/error-chain')
-rw-r--r--third_party/rust/error-chain/.cargo-checksum.json1
-rw-r--r--third_party/rust/error-chain/CHANGELOG.md136
-rw-r--r--third_party/rust/error-chain/Cargo.lock67
-rw-r--r--third_party/rust/error-chain/Cargo.toml32
-rw-r--r--third_party/rust/error-chain/LICENSE-APACHE201
-rw-r--r--third_party/rust/error-chain/LICENSE-MIT26
-rw-r--r--third_party/rust/error-chain/README.md36
-rw-r--r--third_party/rust/error-chain/build.rs21
-rw-r--r--third_party/rust/error-chain/examples/all.rs36
-rw-r--r--third_party/rust/error-chain/examples/chain_err.rs67
-rw-r--r--third_party/rust/error-chain/examples/doc.rs28
-rw-r--r--third_party/rust/error-chain/examples/has_backtrace.rs18
-rw-r--r--third_party/rust/error-chain/examples/quickstart.rs78
-rw-r--r--third_party/rust/error-chain/examples/size.rs30
-rw-r--r--third_party/rust/error-chain/src/backtrace.rs111
-rw-r--r--third_party/rust/error-chain/src/error_chain.rs564
-rw-r--r--third_party/rust/error-chain/src/example_generated.rs38
-rw-r--r--third_party/rust/error-chain/src/impl_error_chain_kind.rs383
-rw-r--r--third_party/rust/error-chain/src/lib.rs824
-rw-r--r--third_party/rust/error-chain/src/quick_main.rs81
-rw-r--r--third_party/rust/error-chain/tests/quick_main.rs28
-rw-r--r--third_party/rust/error-chain/tests/tests.rs719
22 files changed, 3525 insertions, 0 deletions
diff --git a/third_party/rust/error-chain/.cargo-checksum.json b/third_party/rust/error-chain/.cargo-checksum.json
new file mode 100644
index 0000000000..25299cf4be
--- /dev/null
+++ b/third_party/rust/error-chain/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"ef6a507058abf31f0e9ca96757e28b02a901ae79e762a3bc7fcf8d1e94fc2d44","Cargo.lock":"f0ff8421e2cf5c319f8201727880716565c3e78ee01c2914f2272cbb6d5f8e32","Cargo.toml":"2a75162596294a04af11f94219ec36c01eee6702027a09918df871fad233e9c7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c43864d39cedab9a1b2aa3d5e480cb58f74cac0b07756670a30c683ce34976a1","README.md":"9fe679f0803f83d65a5b6a26d11305fe042b9ff59494cba31a5904e643240e8e","build.rs":"a1424a03c2df37c5784e8837ce025ad7c2a9efe2e603c80efd3f7ccfbe6b8f07","examples/all.rs":"6f073ea0e3db541a4eefb41436fc03a121a1f932fd6a2798b485a72d64bd1a3c","examples/chain_err.rs":"9a4cfc00808dfde57c97f65969d4ed5a48335b1880c1e2507b71fd9b711bdbae","examples/doc.rs":"426789ff58b2f8792e867d5d85fdb74507cda160285f0130f50d7c4cfff4a51c","examples/has_backtrace.rs":"eedf028ff206938760a53e91d13534b6ad6780b2b6635f405b7896125484a869","examples/quickstart.rs":"80a744c7d309662409b4db255ddcd714e63b2e82a1f0ff00e21525289bbdfe48","examples/size.rs":"d778532f17d9d55e3eb421d920b1cf09b4284d160fffe7c5522258527c8d284c","src/backtrace.rs":"bf70954c483e54fc13f5235efca08f21a02764f34fccdc1a657e66f3632f6f59","src/error_chain.rs":"cb315489643af2b7da7868239b0f1f0e3e6cd3e900030b38617eeddd30e757fc","src/example_generated.rs":"b0742d8df91948a81db01a9b455e0bbe9b211b9c2644a7f10d59f0e099083231","src/impl_error_chain_kind.rs":"ed27688a857e15f4f120769bae892c0280f96e4e082b42ebb2ba1af02f8875ee","src/lib.rs":"cd469e2f18653fc1e6541d82a566a94d8b5769a2e5c6abf3fcdd967eab22246f","src/quick_main.rs":"f77f74104cff1825d9885be1708b5128508312ed5ac92c806fdafa0336f47ead","tests/quick_main.rs":"39a1113cc0d30e5b265e4139cda36f910f8c534a4409e99a9a506a0e88e58f19","tests/tests.rs":"3b80f2c8d45d06dea2ef1375579e63e2fc904ee8c22b1abf285f062b3c1ce271"},"package":"2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"} \ No newline at end of file
diff --git a/third_party/rust/error-chain/CHANGELOG.md b/third_party/rust/error-chain/CHANGELOG.md
new file mode 100644
index 0000000000..bd82afc3d5
--- /dev/null
+++ b/third_party/rust/error-chain/CHANGELOG.md
@@ -0,0 +1,136 @@
+# 0.12.4
+- [executable bits to support build platform linters](https://github.com/rust-lang-nursery/error-chain/pull/289)
+
+# 0.12.2
+- [allow `Error::description` to be used for rust below 1.42](https://github.com/rust-lang-nursery/error-chain/pull/285)
+- [Improvements to has_backtrace_depending_on_env](https://github.com/rust-lang-nursery/error-chain/pull/277)
+- Backtrace support now requires rust 1.32.0
+
+# 0.12.1
+
+- [`std::error::Error::cause` deprecation update](https://github.com/rust-lang-nursery/error-chain/pull/255)
+- [Macro invocations use 2018 style](https://github.com/rust-lang-nursery/error-chain/pull/253)
+
+# 0.12.0
+
+- [Remove `impl Deref<Kind> for Error`](https://github.com/rust-lang-nursery/error-chain/pull/192)
+- [Fix warning](https://github.com/rust-lang-nursery/error-chain/pull/247)
+
+# 0.11.0
+
+- Change last rust version supported to 1.14
+- [Cache whether RUST_BACKTRACE is enabled in a relaxed atomic static.](https://github.com/rust-lang-nursery/error-chain/pull/210)
+- [Mask the `quick_error` macro from the doc](https://github.com/rust-lang-nursery/error-chain/pull/210)
+- [Make generated `ErrorKind` enums non-exhaustive](https://github.com/rust-lang-nursery/error-chain/pull/193)
+- All 0.11.0-rc.2 changes
+
+# 0.11.0-rc.2
+
+- [Make `ErrorChainIter`'s field private](https://github.com/rust-lang-nursery/error-chain/issues/178)
+- [Rename `ErrorChainIter` to `Iter`](https://github.com/rust-lang-nursery/error-chain/issues/168)
+- [Implement `Debug` for `ErrorChainIter`](https://github.com/rust-lang-nursery/error-chain/issues/169)
+- [Rename `ChainedError::display` to `display_chain`](https://github.com/rust-lang-nursery/error-chain/issues/180)
+- [Add a new method for `Error`: `chain_err`.](https://github.com/rust-lang-nursery/error-chain/pull/141)
+- [Allow `chain_err` to be used on `Option<T>`](https://github.com/rust-lang-nursery/error-chain/pull/156)
+- [Add support for creating an error chain on boxed trait errors (`Box<Error>`)](https://github.com/rust-lang-nursery/error-chain/pull/156)
+- [Remove lint for unused doc comment.](https://github.com/rust-lang-nursery/error-chain/pull/199)
+- [Hide error_chain_processed macro from documentation.](https://github.com/rust-lang-nursery/error-chain/pull/212)
+
+# 0.10.0
+
+- [Add a new constructor for `Error`: `with_chain`.](https://github.com/rust-lang-nursery/error-chain/pull/126)
+- [Add the `ensure!` macro.](https://github.com/rust-lang-nursery/error-chain/pull/135)
+
+# 0.9.0
+
+- Revert [Add a `Sync` bound to errors](https://github.com/rust-lang-nursery/error-chain/pull/110)
+
+# 0.8.1
+
+- Add crates.io category.
+
+# 0.8.0
+
+- [Add a `Sync` bound to errors](https://github.com/rust-lang-nursery/error-chain/pull/110)
+- [Add `ChainedError::display` to format error chains](https://github.com/rust-lang-nursery/error-chain/pull/113)
+
+# 0.7.2
+
+- Add `quick_main!` (#88).
+- `allow(unused)` for the `Result` wrapper.
+- Minimum rust version supported is now 1.10 on some conditions (#103).
+
+# 0.7.1
+
+- [Add the `bail!` macro](https://github.com/rust-lang-nursery/error-chain/pull/76)
+
+# 0.7.0
+
+- [Rollback several design changes to fix regressions](https://github.com/rust-lang-nursery/error-chain/pull/75)
+- New `Variant(Error) #[attrs]` for `links` and `foreign_links`.
+- Hide implementation details from the doc.
+- Always generate `Error::backtrace`.
+
+# 0.6.2
+
+- Allow dead code.
+
+# 0.6.1
+
+- Fix wrong trait constraint in ResultExt implementation (#66).
+
+# 0.6.0
+
+- Conditional compilation for error variants.
+- Backtrace generation is now a feature.
+- More standard trait implementations for extra convenience.
+- Remove ChainErr.
+- Remove need to specify `ErrorKind` in `links {}`.
+- Add ResultExt trait.
+- Error.1 is a struct instead of a tuple.
+- Error is now a struct.
+- The declarations order is more flexible.
+- Way better error reporting when there is a syntax error in the macro call.
+- `Result` generation can be disabled.
+- At most one declaration of each type can be present.
+
+# 0.5.0
+
+- [Only generate backtraces with RUST_BACKTRACE set](https://github.com/rust-lang-nursery/error-chain/pull/27)
+- [Fixup matching, disallow repeating "types" section](https://github.com/rust-lang-nursery/error-chain/pull/26)
+- [Fix tests on stable/beta](https://github.com/rust-lang-nursery/error-chain/pull/28)
+- [Only deploy docs when tagged](https://github.com/rust-lang-nursery/error-chain/pull/30)
+
+Contributors: benaryorg, Brian Anderson, Georg Brandl
+
+# 0.4.2
+
+- [Fix the resolution of the ErrorKind description method](https://github.com/rust-lang-nursery/error-chain/pull/24)
+
+Contributors: Brian Anderson
+
+# 0.4.1 (yanked)
+
+- [Fix a problem with resolving methods of the standard Error type](https://github.com/rust-lang-nursery/error-chain/pull/22)
+
+Contributors: Brian Anderson
+
+# 0.4.0 (yanked)
+
+- [Remove the foreign link description and forward to the foreign error](https://github.com/rust-lang-nursery/error-chain/pull/19)
+- [Allow missing sections](https://github.com/rust-lang-nursery/error-chain/pull/17)
+
+Contributors: Brian Anderson, Taylor Cramer
+
+# 0.3.0
+
+- [Forward Display implementation for foreign errors](https://github.com/rust-lang-nursery/error-chain/pull/13)
+
+Contributors: Brian Anderson, Taylor Cramer
+
+# 0.2.2
+
+- [Don't require `types` section in macro invocation](https://github.com/rust-lang-nursery/error-chain/pull/8)
+- [Add "quick start" to README](https://github.com/rust-lang-nursery/error-chain/pull/9)
+
+Contributors: Brian Anderson, Jake Shadle, Nate Mara
diff --git a/third_party/rust/error-chain/Cargo.lock b/third_party/rust/error-chain/Cargo.lock
new file mode 100644
index 0000000000..9453307464
--- /dev/null
+++ b/third_party/rust/error-chain/Cargo.lock
@@ -0,0 +1,67 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "addr2line"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a49806b9dadc843c61e7c97e72490ad7f7220ae249012fbda9ad0609457c0543"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "backtrace"
+version = "0.3.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130"
+dependencies = [
+ "addr2line",
+ "cfg-if",
+ "libc",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
+[[package]]
+name = "error-chain"
+version = "0.12.4"
+dependencies = [
+ "backtrace",
+ "version_check",
+]
+
+[[package]]
+name = "gimli"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c"
+
+[[package]]
+name = "libc"
+version = "0.2.71"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
+
+[[package]]
+name = "object"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2"
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
+
+[[package]]
+name = "version_check"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
diff --git a/third_party/rust/error-chain/Cargo.toml b/third_party/rust/error-chain/Cargo.toml
new file mode 100644
index 0000000000..55ed9ac659
--- /dev/null
+++ b/third_party/rust/error-chain/Cargo.toml
@@ -0,0 +1,32 @@
+# 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 believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "error-chain"
+version = "0.12.4"
+authors = ["Brian Anderson <banderson@mozilla.com>", "Paul Colomiets <paul@colomiets.name>", "Colin Kiegel <kiegel@gmx.de>", "Yamakaky <yamakaky@yamaworld.fr>", "Andrew Gauger <andygauge@gmail.com>"]
+description = "Yet another error boilerplate library."
+documentation = "https://docs.rs/error-chain"
+readme = "README.md"
+keywords = ["error"]
+categories = ["rust-patterns"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/rust-lang-nursery/error-chain"
+[dependencies.backtrace]
+version = "0.3.3"
+optional = true
+[build-dependencies.version_check]
+version = "0.9"
+
+[features]
+default = ["backtrace", "example_generated"]
+example_generated = []
diff --git a/third_party/rust/error-chain/LICENSE-APACHE b/third_party/rust/error-chain/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/error-chain/LICENSE-APACHE
@@ -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.
diff --git a/third_party/rust/error-chain/LICENSE-MIT b/third_party/rust/error-chain/LICENSE-MIT
new file mode 100644
index 0000000000..5f28864c84
--- /dev/null
+++ b/third_party/rust/error-chain/LICENSE-MIT
@@ -0,0 +1,26 @@
+Copyright (c) 2017 The Error-Chain Project Developers
+
+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.
+
diff --git a/third_party/rust/error-chain/README.md b/third_party/rust/error-chain/README.md
new file mode 100644
index 0000000000..b87224d18d
--- /dev/null
+++ b/third_party/rust/error-chain/README.md
@@ -0,0 +1,36 @@
+# error-chain - Consistent error handling for Rust
+
+[![Build Status](https://travis-ci.com/rust-lang-nursery/error-chain.svg?branch=master)](https://travis-ci.com/rust-lang-nursery/error-chain)
+[![Latest Version](https://img.shields.io/crates/v/error-chain.svg)](https://crates.io/crates/error-chain)
+[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-green.svg)](https://github.com/rust-lang-nursery/error-chain)
+
+`error-chain` makes it easy to take full advantage of Rust's error
+handling features without the overhead of maintaining boilerplate
+error types and conversions. It implements an opinionated strategy for
+defining your own error types, as well as conversions from others'
+error types.
+
+[Documentation (crates.io)](https://docs.rs/error-chain).
+
+[Documentation (master)](https://rust-lang-nursery.github.io/error-chain).
+
+## Quick start
+
+If you just want to set up your new project with error-chain,
+follow the [quickstart.rs] template, and read this [intro]
+to error-chain.
+
+[quickstart.rs]: https://github.com/rust-lang-nursery/error-chain/blob/master/examples/quickstart.rs
+[intro]: http://brson.github.io/2016/11/30/starting-with-error-chain
+
+## Supported Rust version
+
+Please view the beginning of the [Travis configuration file](.travis.yml)
+to see the oldest supported Rust version.
+
+Note that `error-chain` supports older versions of Rust when built with
+`default-features = false`.
+
+## License
+
+MIT/Apache-2.0
diff --git a/third_party/rust/error-chain/build.rs b/third_party/rust/error-chain/build.rs
new file mode 100644
index 0000000000..612f2091de
--- /dev/null
+++ b/third_party/rust/error-chain/build.rs
@@ -0,0 +1,21 @@
+extern crate version_check;
+
+use std::env;
+use version_check::is_min_version;
+
+fn main() {
+ // Switch on for versions that have Error::source
+ // As introduced by https://github.com/rust-lang/rust/pull/53533
+ if is_min_version("1.30").unwrap_or(false) {
+ println!("cargo:rustc-cfg=has_error_source");
+ }
+
+ if is_min_version("1.42").unwrap_or(false) {
+ println!("cargo:rustc-cfg=has_error_description_deprecated");
+ }
+
+ // So we can get the build profile for has_backtrace_depending_on_env test
+ if let Ok(profile) = env::var("PROFILE") {
+ println!("cargo:rustc-cfg=build={:?}", profile);
+ }
+}
diff --git a/third_party/rust/error-chain/examples/all.rs b/third_party/rust/error-chain/examples/all.rs
new file mode 100644
index 0000000000..840ca95e27
--- /dev/null
+++ b/third_party/rust/error-chain/examples/all.rs
@@ -0,0 +1,36 @@
+#[macro_use]
+extern crate error_chain;
+
+pub mod inner {
+ error_chain! {}
+}
+
+#[cfg(feature = "a_feature")]
+pub mod feature {
+ error_chain! {}
+}
+
+error_chain! {
+ // Types generated by the macro. If empty or absent, it defaults to
+ // Error, ErrorKind, Result;
+ types {
+ // With custom names:
+ MyError, MyErrorKind, MyResult;
+ // Without the `Result` wrapper:
+ // Error, ErrorKind;
+ }
+
+ // Automatic bindings to other error types generated by `error_chain!`.
+ links {
+ Inner(inner::Error, inner::ErrorKind);
+ // Attributes can be added at the end of the declaration.
+ Feature(feature::Error, feature::ErrorKind) #[cfg(feature = "a_feature")];
+ }
+
+ // Bindings to types implementing std::error::Error.
+ foreign_links {
+ Io(::std::io::Error);
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/error-chain/examples/chain_err.rs b/third_party/rust/error-chain/examples/chain_err.rs
new file mode 100644
index 0000000000..c70a25dd60
--- /dev/null
+++ b/third_party/rust/error-chain/examples/chain_err.rs
@@ -0,0 +1,67 @@
+//! Demonstrates usage of `Error::caused` method. This method enables chaining errors
+//! like `ResultExt::chain_err` but doesn't require the presence of a `Result` wrapper.
+
+#[macro_use]
+extern crate error_chain;
+
+use std::fs::File;
+
+mod errors {
+ use super::LaunchStage;
+ use std::io;
+
+ error_chain! {
+ foreign_links {
+ Io(io::Error) #[doc = "Error during IO"];
+ }
+
+ errors {
+ Launch(phase: LaunchStage) {
+ description("An error occurred during startup")
+ display("Startup aborted: {:?} did not complete successfully", phase)
+ }
+
+ ConfigLoad(path: String) {
+ description("Config file not found")
+ display("Unable to read file `{}`", path)
+ }
+ }
+ }
+
+ impl From<LaunchStage> for ErrorKind {
+ fn from(v: LaunchStage) -> Self {
+ ErrorKind::Launch(v)
+ }
+ }
+}
+
+pub use errors::*;
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum LaunchStage {
+ ConfigLoad,
+ ConfigParse,
+ ConfigResolve,
+}
+
+/// Read the service config from the file specified.
+fn load_config(rel_path: &str) -> Result<()> {
+ File::open(rel_path)
+ .map(|_| ())
+ .chain_err(|| ErrorKind::ConfigLoad(rel_path.to_string()))
+}
+
+/// Launch the service.
+fn launch(rel_path: &str) -> Result<()> {
+ load_config(rel_path).map_err(|e| match e {
+ e @ Error(ErrorKind::ConfigLoad(_), _) => e.chain_err(|| LaunchStage::ConfigLoad),
+ e => e.chain_err(|| "Unknown failure"),
+ })
+}
+
+fn main() {
+ let chain = launch("does_not_exist.json").unwrap_err();
+ for err in chain.iter() {
+ println!("{}", err);
+ }
+}
diff --git a/third_party/rust/error-chain/examples/doc.rs b/third_party/rust/error-chain/examples/doc.rs
new file mode 100644
index 0000000000..68f57d7884
--- /dev/null
+++ b/third_party/rust/error-chain/examples/doc.rs
@@ -0,0 +1,28 @@
+#![deny(missing_docs)]
+
+//! This module is used to check that all generated items are documented.
+
+#[macro_use]
+extern crate error_chain;
+
+/// Inner module.
+pub mod inner {
+ error_chain! {}
+}
+
+error_chain! {
+ links {
+ Inner(inner::Error, inner::ErrorKind) #[doc = "Doc"];
+ }
+ foreign_links {
+ Io(::std::io::Error) #[doc = "Io"];
+ }
+ errors {
+ /// Doc
+ Test2 {
+
+ }
+ }
+}
+
+fn main() {}
diff --git a/third_party/rust/error-chain/examples/has_backtrace.rs b/third_party/rust/error-chain/examples/has_backtrace.rs
new file mode 100644
index 0000000000..c5dac058a8
--- /dev/null
+++ b/third_party/rust/error-chain/examples/has_backtrace.rs
@@ -0,0 +1,18 @@
+//! Exits with exit code 0 if backtraces are disabled and 1 if they are enabled.
+//! Used by tests to make sure backtraces are available when they should be. Should not be used
+//! outside of the tests.
+
+#[macro_use]
+extern crate error_chain;
+
+error_chain! {
+ errors {
+ MyError
+ }
+}
+
+fn main() {
+ let err = Error::from(ErrorKind::MyError);
+ let has_backtrace = err.backtrace().is_some();
+ ::std::process::exit(has_backtrace as i32);
+}
diff --git a/third_party/rust/error-chain/examples/quickstart.rs b/third_party/rust/error-chain/examples/quickstart.rs
new file mode 100644
index 0000000000..e410a62b8a
--- /dev/null
+++ b/third_party/rust/error-chain/examples/quickstart.rs
@@ -0,0 +1,78 @@
+// Simple and robust error handling with error-chain!
+// Use this as a template for new projects.
+
+// `error_chain!` can recurse deeply
+#![recursion_limit = "1024"]
+
+// Import the macro. Don't forget to add `error-chain` in your
+// `Cargo.toml`!
+#[macro_use]
+extern crate error_chain;
+
+// We'll put our errors in an `errors` module, and other modules in
+// this crate will `use errors::*;` to get access to everything
+// `error_chain!` creates.
+mod errors {
+ // Create the Error, ErrorKind, ResultExt, and Result types
+ error_chain! {}
+}
+
+// This only gives access within this module. Make this `pub use errors::*;`
+// instead if the types must be accessible from other modules (e.g., within
+// a `links` section).
+use errors::*;
+
+fn main() {
+ if let Err(ref e) = run() {
+ use std::io::Write;
+ let stderr = &mut ::std::io::stderr();
+ let errmsg = "Error writing to stderr";
+
+ writeln!(stderr, "error: {}", e).expect(errmsg);
+
+ for e in e.iter().skip(1) {
+ writeln!(stderr, "caused by: {}", e).expect(errmsg);
+ }
+
+ // The backtrace is not always generated. Try to run this example
+ // with `RUST_BACKTRACE=1`.
+ if let Some(backtrace) = e.backtrace() {
+ writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg);
+ }
+
+ ::std::process::exit(1);
+ }
+}
+
+// The above main gives you maximum control over how the error is
+// formatted. If you don't care (i.e. you want to display the full
+// error during an assert) you can just call the `display_chain` method
+// on the error object
+#[allow(dead_code)]
+fn alternative_main() {
+ if let Err(ref e) = run() {
+ use error_chain::ChainedError;
+ use std::io::Write; // trait which holds `display_chain`
+ let stderr = &mut ::std::io::stderr();
+ let errmsg = "Error writing to stderr";
+
+ writeln!(stderr, "{}", e.display_chain()).expect(errmsg);
+ ::std::process::exit(1);
+ }
+}
+
+// Use this macro to auto-generate the main above. You may want to
+// set the `RUST_BACKTRACE` env variable to see a backtrace.
+// quick_main!(run);
+
+// Most functions will return the `Result` type, imported from the
+// `errors` module. It is a typedef of the standard `Result` type
+// for which the error type is always our own `Error`.
+fn run() -> Result<()> {
+ use std::fs::File;
+
+ // This operation will fail
+ File::open("tretrete").chain_err(|| "unable to open tretrete file")?;
+
+ Ok(())
+}
diff --git a/third_party/rust/error-chain/examples/size.rs b/third_party/rust/error-chain/examples/size.rs
new file mode 100644
index 0000000000..3e180684e8
--- /dev/null
+++ b/third_party/rust/error-chain/examples/size.rs
@@ -0,0 +1,30 @@
+#[macro_use]
+extern crate error_chain;
+
+use std::mem::{size_of, size_of_val};
+
+error_chain! {
+ errors {
+ AVariant
+ Another
+ }
+}
+
+fn main() {
+ println!("Memory usage in bytes");
+ println!("---------------------");
+ println!("Result<()>: {}", size_of::<Result<()>>());
+ println!(" (): {}", size_of::<()>());
+ println!(" Error: {}", size_of::<Error>());
+ println!(" ErrorKind: {}", size_of::<ErrorKind>());
+ let msg = ErrorKind::Msg("test".into());
+ println!(" ErrorKind::Msg: {}", size_of_val(&msg));
+ println!(" String: {}", size_of::<String>());
+ println!(" State: {}", size_of::<error_chain::State>());
+ let state = error_chain::State {
+ next_error: None,
+ backtrace: error_chain::InternalBacktrace::new(),
+ };
+ println!(" State.next_error: {}", size_of_val(&state.next_error));
+ println!(" State.backtrace: {}", size_of_val(&state.backtrace));
+}
diff --git a/third_party/rust/error-chain/src/backtrace.rs b/third_party/rust/error-chain/src/backtrace.rs
new file mode 100644
index 0000000000..14be75ce1b
--- /dev/null
+++ b/third_party/rust/error-chain/src/backtrace.rs
@@ -0,0 +1,111 @@
+pub use self::imp::{Backtrace, InternalBacktrace};
+
+#[cfg(feature = "backtrace")]
+mod imp {
+ extern crate backtrace;
+
+ use std::cell::UnsafeCell;
+ use std::env;
+ use std::fmt;
+ use std::sync::atomic::{AtomicUsize, Ordering};
+ use std::sync::{Arc, Mutex};
+
+ /// Internal representation of a backtrace
+ #[doc(hidden)]
+ #[derive(Clone)]
+ pub struct InternalBacktrace {
+ backtrace: Option<Arc<MaybeResolved>>,
+ }
+
+ struct MaybeResolved {
+ resolved: Mutex<bool>,
+ backtrace: UnsafeCell<Backtrace>,
+ }
+
+ unsafe impl Send for MaybeResolved {}
+ unsafe impl Sync for MaybeResolved {}
+
+ pub use self::backtrace::Backtrace;
+
+ impl InternalBacktrace {
+ /// Returns a backtrace of the current call stack if `RUST_BACKTRACE`
+ /// is set to anything but ``0``, and `None` otherwise. This is used
+ /// in the generated error implementations.
+ #[doc(hidden)]
+ pub fn new() -> InternalBacktrace {
+ static ENABLED: AtomicUsize = AtomicUsize::new(0);
+
+ match ENABLED.load(Ordering::SeqCst) {
+ 0 => {
+ let enabled = match env::var_os("RUST_BACKTRACE") {
+ Some(ref val) if val != "0" => true,
+ _ => false,
+ };
+ ENABLED.store(enabled as usize + 1, Ordering::SeqCst);
+ if !enabled {
+ return InternalBacktrace { backtrace: None };
+ }
+ }
+ 1 => return InternalBacktrace { backtrace: None },
+ _ => {}
+ }
+
+ InternalBacktrace {
+ backtrace: Some(Arc::new(MaybeResolved {
+ resolved: Mutex::new(false),
+ backtrace: UnsafeCell::new(Backtrace::new_unresolved()),
+ })),
+ }
+ }
+
+ /// Acquire the internal backtrace
+ #[doc(hidden)]
+ pub fn as_backtrace(&self) -> Option<&Backtrace> {
+ let bt = match self.backtrace {
+ Some(ref bt) => bt,
+ None => return None,
+ };
+ let mut resolved = bt.resolved.lock().unwrap();
+ unsafe {
+ if !*resolved {
+ (*bt.backtrace.get()).resolve();
+ *resolved = true;
+ }
+ Some(&*bt.backtrace.get())
+ }
+ }
+ }
+
+ impl fmt::Debug for InternalBacktrace {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("InternalBacktrace")
+ .field("backtrace", &self.as_backtrace())
+ .finish()
+ }
+ }
+}
+
+#[cfg(not(feature = "backtrace"))]
+mod imp {
+ /// Dummy type used when the `backtrace` feature is disabled.
+ pub type Backtrace = ();
+
+ /// Internal representation of a backtrace
+ #[doc(hidden)]
+ #[derive(Clone, Debug)]
+ pub struct InternalBacktrace {}
+
+ impl InternalBacktrace {
+ /// Returns a new backtrace
+ #[doc(hidden)]
+ pub fn new() -> InternalBacktrace {
+ InternalBacktrace {}
+ }
+
+ /// Returns the internal backtrace
+ #[doc(hidden)]
+ pub fn as_backtrace(&self) -> Option<&Backtrace> {
+ None
+ }
+ }
+}
diff --git a/third_party/rust/error-chain/src/error_chain.rs b/third_party/rust/error-chain/src/error_chain.rs
new file mode 100644
index 0000000000..8382709621
--- /dev/null
+++ b/third_party/rust/error-chain/src/error_chain.rs
@@ -0,0 +1,564 @@
+#[doc(hidden)]
+#[macro_export]
+#[cfg(not(has_error_source))]
+macro_rules! impl_error_chain_cause_or_source {
+ (
+ types {
+ $error_kind_name:ident
+ }
+
+ foreign_links {
+ $( $foreign_link_variant:ident ( $foreign_link_error_path:path )
+ $( #[$meta_foreign_links:meta] )*; )*
+ }
+ ) => {
+ #[allow(unknown_lints, renamed_and_removed_lints)]
+ #[allow(unused_doc_comment, unused_doc_comments)]
+ fn cause(&self) -> Option<&::std::error::Error> {
+ match self.1.next_error {
+ Some(ref c) => Some(&**c),
+ None => {
+ match self.0 {
+ $(
+ $(#[$meta_foreign_links])*
+ $error_kind_name::$foreign_link_variant(ref foreign_err) => {
+ foreign_err.cause()
+ }
+ ) *
+ _ => None
+ }
+ }
+ }
+ }
+ };
+}
+
+#[cfg(has_error_source)]
+#[doc(hidden)]
+#[macro_export]
+macro_rules! impl_error_chain_cause_or_source {
+ (
+ types {
+ $error_kind_name:ident
+ }
+
+ foreign_links {
+ $( $foreign_link_variant:ident ( $foreign_link_error_path:path )
+ $( #[$meta_foreign_links:meta] )*; )*
+ }
+ ) => {
+ #[allow(unknown_lints, renamed_and_removed_lints, bare_trait_objects)]
+ #[allow(unused_doc_comment, unused_doc_comments)]
+ fn source(&self) -> Option<&(std::error::Error + 'static)> {
+ match self.1.next_error {
+ Some(ref c) => Some(&**c),
+ None => {
+ match self.0 {
+ $(
+ $(#[$meta_foreign_links])*
+ $error_kind_name::$foreign_link_variant(ref foreign_err) => {
+ foreign_err.source()
+ }
+ ) *
+ _ => None
+ }
+ }
+ }
+ }
+ };
+}
+
+/// Conditional usage of deprecated Error::description
+#[doc(hidden)]
+#[cfg(has_error_description_deprecated)]
+#[macro_export(local_inner_macros)]
+macro_rules! call_to_deprecated_description {
+ ($e:ident) => {
+ ""
+ };
+}
+
+#[doc(hidden)]
+#[cfg(not(has_error_description_deprecated))]
+#[macro_export(local_inner_macros)]
+macro_rules! call_to_deprecated_description {
+ ($e:ident) => {
+ ::std::error::Error::description($e)
+ };
+}
+
+/// Prefer to use `error_chain` instead of this macro.
+#[doc(hidden)]
+#[macro_export(local_inner_macros)]
+macro_rules! impl_error_chain_processed {
+ // Default values for `types`.
+ (
+ types {}
+ $( $rest: tt )*
+ ) => {
+ impl_error_chain_processed! {
+ types {
+ Error, ErrorKind, ResultExt, Result;
+ }
+ $( $rest )*
+ }
+ };
+ // With `Result` wrapper.
+ (
+ types {
+ $error_name:ident, $error_kind_name:ident,
+ $result_ext_name:ident, $result_name:ident;
+ }
+ $( $rest: tt )*
+ ) => {
+ impl_error_chain_processed! {
+ types {
+ $error_name, $error_kind_name,
+ $result_ext_name;
+ }
+ $( $rest )*
+ }
+ /// Convenient wrapper around `std::Result`.
+ #[allow(unused)]
+ pub type $result_name<T> = ::std::result::Result<T, $error_name>;
+ };
+
+ // With `Msg` variant.
+ (
+ types {
+ $error_name:ident, $error_kind_name:ident, $($types:tt)*
+ }
+ links $links:tt
+ foreign_links $foreign_links:tt
+ errors { $($errors:tt)* }
+ ) => {
+ impl_error_chain_processed! {
+ types {
+ $error_name, $error_kind_name, $($types)*
+ }
+ skip_msg_variant
+ links $links
+ foreign_links $foreign_links
+ errors {
+ /// A convenient variant for String.
+ Msg(s: String) {
+ description(&s)
+ display("{}", s)
+ }
+
+ $($errors)*
+ }
+ }
+
+ impl<'a> From<&'a str> for $error_kind_name {
+ fn from(s: &'a str) -> Self {
+ $error_kind_name::Msg(s.into())
+ }
+ }
+
+ impl From<String> for $error_kind_name {
+ fn from(s: String) -> Self {
+ $error_kind_name::Msg(s)
+ }
+ }
+
+ impl<'a> From<&'a str> for $error_name {
+ fn from(s: &'a str) -> Self {
+ Self::from_kind(s.into())
+ }
+ }
+
+ impl From<String> for $error_name {
+ fn from(s: String) -> Self {
+ Self::from_kind(s.into())
+ }
+ }
+ };
+
+ // Without `Result` wrapper or `Msg` variant.
+ (
+ types {
+ $error_name:ident, $error_kind_name:ident,
+ $result_ext_name:ident;
+ }
+
+ skip_msg_variant
+
+ links {
+ $( $link_variant:ident ( $link_error_path:path, $link_kind_path:path )
+ $( #[$meta_links:meta] )*; ) *
+ }
+
+ foreign_links {
+ $( $foreign_link_variant:ident ( $foreign_link_error_path:path )
+ $( #[$meta_foreign_links:meta] )*; )*
+ }
+
+ errors {
+ $( $error_chunks:tt ) *
+ }
+
+ ) => {
+ /// The Error type.
+ ///
+ /// This tuple struct is made of two elements:
+ ///
+ /// - an `ErrorKind` which is used to determine the type of the error.
+ /// - An internal `State`, not meant for direct use outside of `error_chain`
+ /// internals, containing:
+ /// - a backtrace, generated when the error is created.
+ /// - an error chain, used for the implementation of `Error::cause()`.
+ #[derive(Debug)]
+ pub struct $error_name(
+ // The members must be `pub` for `links`.
+ /// The kind of the error.
+ pub $error_kind_name,
+ /// Contains the error chain and the backtrace.
+ #[doc(hidden)]
+ pub $crate::State,
+ );
+
+ impl $crate::ChainedError for $error_name {
+ type ErrorKind = $error_kind_name;
+
+ fn new(kind: $error_kind_name, state: $crate::State) -> $error_name {
+ $error_name(kind, state)
+ }
+
+ fn from_kind(kind: Self::ErrorKind) -> Self {
+ Self::from_kind(kind)
+ }
+
+ fn with_chain<E, K>(error: E, kind: K)
+ -> Self
+ where E: ::std::error::Error + Send + 'static,
+ K: Into<Self::ErrorKind>
+ {
+ Self::with_chain(error, kind)
+ }
+
+ fn kind(&self) -> &Self::ErrorKind {
+ self.kind()
+ }
+
+ fn iter(&self) -> $crate::Iter {
+ $crate::Iter::new(Some(self))
+ }
+
+ fn chain_err<F, EK>(self, error: F) -> Self
+ where F: FnOnce() -> EK,
+ EK: Into<$error_kind_name> {
+ self.chain_err(error)
+ }
+
+ fn backtrace(&self) -> Option<&$crate::Backtrace> {
+ self.backtrace()
+ }
+
+ impl_extract_backtrace!($error_name
+ $error_kind_name
+ $([$link_error_path, $(#[$meta_links])*])*);
+ }
+
+ #[allow(dead_code)]
+ impl $error_name {
+ /// Constructs an error from a kind, and generates a backtrace.
+ pub fn from_kind(kind: $error_kind_name) -> $error_name {
+ $error_name(
+ kind,
+ $crate::State::default(),
+ )
+ }
+
+ /// Constructs a chained error from another error and a kind, and generates a backtrace.
+ pub fn with_chain<E, K>(error: E, kind: K)
+ -> $error_name
+ where E: ::std::error::Error + Send + 'static,
+ K: Into<$error_kind_name>
+ {
+ $error_name::with_boxed_chain(Box::new(error), kind)
+ }
+
+ /// Construct a chained error from another boxed error and a kind, and generates a backtrace
+ #[allow(unknown_lints, bare_trait_objects)]
+ pub fn with_boxed_chain<K>(error: Box<::std::error::Error + Send>, kind: K)
+ -> $error_name
+ where K: Into<$error_kind_name>
+ {
+ $error_name(
+ kind.into(),
+ $crate::State::new::<$error_name>(error, ),
+ )
+ }
+
+ /// Returns the kind of the error.
+ pub fn kind(&self) -> &$error_kind_name {
+ &self.0
+ }
+
+ /// Iterates over the error chain.
+ pub fn iter(&self) -> $crate::Iter {
+ $crate::ChainedError::iter(self)
+ }
+
+ /// Returns the backtrace associated with this error.
+ pub fn backtrace(&self) -> Option<&$crate::Backtrace> {
+ self.1.backtrace()
+ }
+
+ /// Extends the error chain with a new entry.
+ pub fn chain_err<F, EK>(self, error: F) -> $error_name
+ where F: FnOnce() -> EK, EK: Into<$error_kind_name> {
+ $error_name::with_chain(self, Self::from_kind(error().into()))
+ }
+
+ /// A short description of the error.
+ /// This method is identical to [`Error::description()`](https://doc.rust-lang.org/nightly/std/error/trait.Error.html#tymethod.description)
+ pub fn description(&self) -> &str {
+ self.0.description()
+ }
+ }
+
+ impl ::std::error::Error for $error_name {
+ #[cfg(not(has_error_description_deprecated))]
+ fn description(&self) -> &str {
+ self.description()
+ }
+
+ impl_error_chain_cause_or_source!{
+ types {
+ $error_kind_name
+ }
+ foreign_links {
+ $( $foreign_link_variant ( $foreign_link_error_path )
+ $( #[$meta_foreign_links] )*; )*
+ }
+ }
+ }
+
+ impl ::std::fmt::Display for $error_name {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ ::std::fmt::Display::fmt(&self.0, f)
+ }
+ }
+
+ $(
+ $(#[$meta_links])*
+ impl From<$link_error_path> for $error_name {
+ fn from(e: $link_error_path) -> Self {
+ $error_name(
+ $error_kind_name::$link_variant(e.0),
+ e.1,
+ )
+ }
+ }
+ ) *
+
+ $(
+ $(#[$meta_foreign_links])*
+ impl From<$foreign_link_error_path> for $error_name {
+ fn from(e: $foreign_link_error_path) -> Self {
+ $error_name::from_kind(
+ $error_kind_name::$foreign_link_variant(e)
+ )
+ }
+ }
+ ) *
+
+ impl From<$error_kind_name> for $error_name {
+ fn from(e: $error_kind_name) -> Self {
+ $error_name::from_kind(e)
+ }
+ }
+
+ // The ErrorKind type
+ // --------------
+
+ impl_error_chain_kind! {
+ /// The kind of an error.
+ #[derive(Debug)]
+ pub enum $error_kind_name {
+ $(
+ $(#[$meta_links])*
+ $link_variant(e: $link_kind_path) {
+ description(e.description())
+ display("{}", e)
+ }
+ ) *
+
+ $(
+ $(#[$meta_foreign_links])*
+ $foreign_link_variant(err: $foreign_link_error_path) {
+ description(call_to_deprecated_description!(err))
+ display("{}", err)
+ }
+ ) *
+
+ $($error_chunks)*
+ }
+ }
+
+ $(
+ $(#[$meta_links])*
+ impl From<$link_kind_path> for $error_kind_name {
+ fn from(e: $link_kind_path) -> Self {
+ $error_kind_name::$link_variant(e)
+ }
+ }
+ ) *
+
+ impl From<$error_name> for $error_kind_name {
+ fn from(e: $error_name) -> Self {
+ e.0
+ }
+ }
+
+ // The ResultExt trait defines the `chain_err` method.
+
+ /// Additional methods for `Result`, for easy interaction with this crate.
+ pub trait $result_ext_name<T> {
+ /// If the `Result` is an `Err` then `chain_err` evaluates the closure,
+ /// which returns *some type that can be converted to `ErrorKind`*, boxes
+ /// the original error to store as the cause, then returns a new error
+ /// containing the original error.
+ fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
+ where F: FnOnce() -> EK,
+ EK: Into<$error_kind_name>;
+ }
+
+ impl<T, E> $result_ext_name<T> for ::std::result::Result<T, E> where E: ::std::error::Error + Send + 'static {
+ fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
+ where F: FnOnce() -> EK,
+ EK: Into<$error_kind_name> {
+ self.map_err(move |e| {
+ let state = $crate::State::new::<$error_name>(Box::new(e), );
+ $crate::ChainedError::new(callback().into(), state)
+ })
+ }
+ }
+
+ impl<T> $result_ext_name<T> for ::std::option::Option<T> {
+ fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
+ where F: FnOnce() -> EK,
+ EK: Into<$error_kind_name> {
+ self.ok_or_else(move || {
+ $crate::ChainedError::from_kind(callback().into())
+ })
+ }
+ }
+
+
+ };
+}
+
+/// Internal macro used for reordering of the fields.
+#[doc(hidden)]
+#[macro_export(local_inner_macros)]
+macro_rules! error_chain_processing {
+ (
+ ({}, $($rest:tt)*)
+ types $content:tt
+ $( $tail:tt )*
+ ) => {
+ error_chain_processing! {
+ ($content, $($rest)*)
+ $($tail)*
+ }
+ };
+
+ (
+ ($a:tt, {}, $($rest:tt)*)
+ links $content:tt
+ $( $tail:tt )*
+ ) => {
+ error_chain_processing! {
+ ($a, $content, $($rest)*)
+ $($tail)*
+ }
+ };
+
+ (
+ ($a:tt, $b:tt, {}, $($rest:tt)*)
+ foreign_links $content:tt
+ $( $tail:tt )*
+ ) => {
+ error_chain_processing! {
+ ($a, $b, $content, $($rest)*)
+ $($tail)*
+ }
+ };
+
+ (
+ ($a:tt, $b:tt, $c:tt, {}, $($rest:tt)*)
+ errors $content:tt
+ $( $tail:tt )*
+ ) => {
+ error_chain_processing! {
+ ($a, $b, $c, $content, $($rest)*)
+ $($tail)*
+ }
+ };
+
+ (
+ ($a:tt, $b:tt, $c:tt, $d:tt, {}, $($rest:tt)*)
+ skip_msg_variant
+ $( $tail:tt )*
+ ) => {
+ error_chain_processing! {
+ ($a, $b, $c, $d, {skip_msg_variant}, $($rest)*)
+ $($tail)*
+ }
+ };
+
+ ( ($a:tt, $b:tt, $c:tt, $d:tt, {$($e:tt)*},) ) => {
+ impl_error_chain_processed! {
+ types $a
+ $($e)*
+ links $b
+ foreign_links $c
+ errors $d
+ }
+ };
+}
+
+/// Macro for generating error types and traits. See crate level documentation for details.
+#[macro_export(local_inner_macros)]
+macro_rules! error_chain {
+ ( $($args:tt)* ) => {
+ error_chain_processing! {
+ ({}, {}, {}, {}, {},)
+ $($args)*
+ }
+ };
+}
+
+/// Macro used to manage the `backtrace` feature.
+///
+/// See
+/// https://www.reddit.com/r/rust/comments/57virt/hey_rustaceans_got_an_easy_question_ask_here/da5r4ti/?context=3
+/// for more details.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! impl_extract_backtrace {
+ ($error_name: ident
+ $error_kind_name: ident
+ $([$link_error_path: path, $(#[$meta_links: meta])*])*) => {
+ #[allow(unknown_lints, renamed_and_removed_lints, bare_trait_objects)]
+ #[allow(unused_doc_comment, unused_doc_comments)]
+ fn extract_backtrace(e: &(::std::error::Error + Send + 'static))
+ -> Option<$crate::InternalBacktrace> {
+ if let Some(e) = e.downcast_ref::<$error_name>() {
+ return Some(e.1.backtrace.clone());
+ }
+ $(
+ $( #[$meta_links] )*
+ {
+ if let Some(e) = e.downcast_ref::<$link_error_path>() {
+ return Some(e.1.backtrace.clone());
+ }
+ }
+ ) *
+ None
+ }
+ }
+}
diff --git a/third_party/rust/error-chain/src/example_generated.rs b/third_party/rust/error-chain/src/example_generated.rs
new file mode 100644
index 0000000000..c0f4d23014
--- /dev/null
+++ b/third_party/rust/error-chain/src/example_generated.rs
@@ -0,0 +1,38 @@
+//! These modules show an example of code generated by the macro. **IT MUST NOT BE
+//! USED OUTSIDE THIS CRATE**.
+//!
+//! This is the basic error structure. You can see that `ErrorKind`
+//! has been populated in a variety of ways. All `ErrorKind`s get a
+//! `Msg` variant for basic errors. When strings are converted to
+//! `ErrorKind`s they become `ErrorKind::Msg`. The "links" defined in
+//! the macro are expanded to the `Inner` variant, and the
+//! "foreign links" to the `Io` variant.
+//!
+//! Both types come with a variety of `From` conversions as well:
+//! `Error` can be created from `ErrorKind`, `&str` and `String`,
+//! and the `links` and `foreign_links` error types. `ErrorKind`
+//! can be created from the corresponding `ErrorKind`s of the link
+//! types, as well as from `&str` and `String`.
+//!
+//! `into()` and `From::from` are used heavily to massage types into
+//! the right shape. Which one to use in any specific case depends on
+//! the influence of type inference, but there are some patterns that
+//! arise frequently.
+
+/// Another code generated by the macro.
+pub mod inner {
+ error_chain! {}
+}
+
+error_chain! {
+ links {
+ Inner(inner::Error, inner::ErrorKind) #[doc = "Link to another `ErrorChain`."];
+ }
+ foreign_links {
+ Io(::std::io::Error) #[doc = "Link to a `std::io::Error` type."];
+ }
+ errors {
+ #[doc = "A custom error kind."]
+ Custom
+ }
+}
diff --git a/third_party/rust/error-chain/src/impl_error_chain_kind.rs b/third_party/rust/error-chain/src/impl_error_chain_kind.rs
new file mode 100644
index 0000000000..4acf8435b2
--- /dev/null
+++ b/third_party/rust/error-chain/src/impl_error_chain_kind.rs
@@ -0,0 +1,383 @@
+/// From https://github.com/tailhook/quick-error
+/// Changes:
+/// - replace `impl Error` by `impl Item::description`
+/// - $imeta
+
+/// Because of the `#[macro_export(local_inner_macros)]` usage on `impl_error_chain_kind` that macro
+/// will only look inside this crate for macros to invoke. So using `stringify` or `write` from
+/// the standard library will fail. Thus we here create simple wrappers for them that are not
+/// exported as `local_inner_macros`, and thus they can in turn use the standard library macros.
+#[macro_export]
+macro_rules! stringify_internal {
+ ($($t:tt)*) => { stringify!($($t)*) }
+}
+
+/// Macro used interally for output expanding an expression
+#[macro_export]
+macro_rules! write_internal {
+ ($dst:expr, $($arg:tt)*) => (write!($dst, $($arg)*))
+}
+
+#[macro_export(local_inner_macros)]
+#[doc(hidden)]
+macro_rules! impl_error_chain_kind {
+ ( $(#[$meta:meta])*
+ pub enum $name:ident { $($chunks:tt)* }
+ ) => {
+ impl_error_chain_kind!(SORT [pub enum $name $(#[$meta])* ]
+ items [] buf []
+ queue [ $($chunks)* ]);
+ };
+ // Queue is empty, can do the work
+ (SORT [pub enum $name:ident $( #[$meta:meta] )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [ ]
+ queue [ ]
+ ) => {
+ impl_error_chain_kind!(ENUM_DEFINITION [pub enum $name $( #[$meta] )*]
+ body []
+ queue [$($( #[$imeta] )*
+ => $iitem: $imode [$( $ivar: $ityp ),*] )*]
+ );
+ impl_error_chain_kind!(IMPLEMENTATIONS $name {$(
+ $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*}
+ )*});
+ $(
+ impl_error_chain_kind!(ERROR_CHECK $imode $($ifuncs)*);
+ )*
+ };
+ // Add meta to buffer
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*]
+ queue [ #[$qmeta:meta] $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+ buf [$( #[$bmeta] )* #[$qmeta] ]
+ queue [$( $tail )*]);
+ };
+ // Add ident to buffer
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*]
+ queue [ $qitem:ident $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])*
+ => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+ buf [$(#[$bmeta])* => $qitem : UNIT [ ] ]
+ queue [$( $tail )*]);
+ };
+ // Flush buffer on meta after ident
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*
+ => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+ queue [ #[$qmeta:meta] $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ enum [$(#[$bmeta])* => $bitem: $bmode $(( $($btyp),* ))*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+ $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
+ buf [ #[$qmeta] ]
+ queue [$( $tail )*]);
+ };
+ // Add tuple enum-variant
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
+ queue [($( $qvar:ident: $qtyp:ty ),+) $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+ buf [$( #[$bmeta] )* => $bitem: TUPLE [$( $qvar:$qtyp ),+] ]
+ queue [$( $tail )*]
+ );
+ };
+ // Add struct enum-variant - e.g. { descr: &'static str }
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
+ queue [{ $( $qvar:ident: $qtyp:ty ),+} $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+ buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),+] ]
+ queue [$( $tail )*]);
+ };
+ // Add struct enum-variant, with excess comma - e.g. { descr: &'static str, }
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )* => $bitem:ident: UNIT [ ] ]
+ queue [{$( $qvar:ident: $qtyp:ty ),+ ,} $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*]
+ buf [$( #[$bmeta] )* => $bitem: STRUCT [$( $qvar:$qtyp ),+] ]
+ queue [$( $tail )*]);
+ };
+ // Add braces and flush always on braces
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*
+ => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+ queue [ {$( $qfuncs:tt )*} $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+ $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {$( $qfuncs )*} ]
+ buf [ ]
+ queue [$( $tail )*]);
+ };
+ // Flush buffer on double ident
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*
+ => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+ queue [ $qitem:ident $( $tail:tt )*]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+ $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
+ buf [ => $qitem : UNIT [ ] ]
+ queue [$( $tail )*]);
+ };
+ // Flush buffer on end
+ (SORT [$( $def:tt )*]
+ items [$($( #[$imeta:meta] )*
+ => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+ {$( $ifuncs:tt )*} )* ]
+ buf [$( #[$bmeta:meta] )*
+ => $bitem:ident: $bmode:tt [$( $bvar:ident: $btyp:ty ),*] ]
+ queue [ ]
+ ) => {
+ impl_error_chain_kind!(SORT [$( $def )*]
+ items [$( $(#[$imeta])* => $iitem: $imode [$( $ivar:$ityp ),*] {$( $ifuncs )*} )*
+ $(#[$bmeta])* => $bitem: $bmode [$( $bvar:$btyp ),*] {} ]
+ buf [ ]
+ queue [ ]);
+ };
+ // Public enum (Queue Empty)
+ (ENUM_DEFINITION [pub enum $name:ident $( #[$meta:meta] )*]
+ body [$($( #[$imeta:meta] )*
+ => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+ queue [ ]
+ ) => {
+ $(#[$meta])*
+ pub enum $name {
+ $(
+ $(#[$imeta])*
+ $iitem $(($( $ttyp ),+))* $({$( $svar: $styp ),*})*,
+ )*
+
+ #[doc(hidden)]
+ __Nonexhaustive {}
+ }
+ };
+ // Unit variant
+ (ENUM_DEFINITION [$( $def:tt )*]
+ body [$($( #[$imeta:meta] )*
+ => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+ queue [$( #[$qmeta:meta] )*
+ => $qitem:ident: UNIT [ ] $( $queue:tt )*]
+ ) => {
+ impl_error_chain_kind!(ENUM_DEFINITION [ $($def)* ]
+ body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
+ $( #[$qmeta] )* => $qitem () {} ]
+ queue [ $($queue)* ]
+ );
+ };
+ // Tuple variant
+ (ENUM_DEFINITION [$( $def:tt )*]
+ body [$($( #[$imeta:meta] )*
+ => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+ queue [$( #[$qmeta:meta] )*
+ => $qitem:ident: TUPLE [$( $qvar:ident: $qtyp:ty ),+] $( $queue:tt )*]
+ ) => {
+ impl_error_chain_kind!(ENUM_DEFINITION [ $($def)* ]
+ body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
+ $( #[$qmeta] )* => $qitem (($( $qtyp ),+)) {} ]
+ queue [ $($queue)* ]
+ );
+ };
+ // Struct variant
+ (ENUM_DEFINITION [$( $def:tt )*]
+ body [$($( #[$imeta:meta] )*
+ => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+ queue [$( #[$qmeta:meta] )*
+ => $qitem:ident: STRUCT [$( $qvar:ident: $qtyp:ty ),*] $( $queue:tt )*]
+ ) => {
+ impl_error_chain_kind!(ENUM_DEFINITION [ $($def)* ]
+ body [$($( #[$imeta] )* => $iitem ($(($( $ttyp ),+))*) {$({$( $svar: $styp ),*})*} )*
+ $( #[$qmeta] )* => $qitem () {{$( $qvar: $qtyp ),*}} ]
+ queue [ $($queue)* ]
+ );
+ };
+ (IMPLEMENTATIONS
+ $name:ident {$(
+ $item:ident: $imode:tt [$(#[$imeta:meta])*] [$( $var:ident: $typ:ty ),*] {$( $funcs:tt )*}
+ )*}
+ ) => {
+ #[allow(unknown_lints, unused, renamed_and_removed_lints)]
+ #[allow(unused_doc_comment, unused_doc_comments)]
+ impl ::std::fmt::Display for $name {
+ fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
+ -> ::std::fmt::Result
+ {
+ match *self {
+ $(
+ $(#[$imeta])*
+ impl_error_chain_kind!(ITEM_PATTERN
+ $name $item: $imode [$( ref $var ),*]
+ ) => {
+ let display_fn = impl_error_chain_kind!(FIND_DISPLAY_IMPL
+ $name $item: $imode
+ {$( $funcs )*});
+
+ display_fn(self, fmt)
+ }
+ )*
+
+ _ => Ok(())
+ }
+ }
+ }
+ #[allow(unknown_lints, unused, renamed_and_removed_lints)]
+ #[allow(unused_doc_comment, unused_doc_comments)]
+ impl $name {
+ /// A string describing the error kind.
+ pub fn description(&self) -> &str {
+ match *self {
+ $(
+ $(#[$imeta])*
+ impl_error_chain_kind!(ITEM_PATTERN
+ $name $item: $imode [$( ref $var ),*]
+ ) => {
+ impl_error_chain_kind!(FIND_DESCRIPTION_IMPL
+ $item: $imode self fmt [$( $var ),*]
+ {$( $funcs )*})
+ }
+ )*
+
+ _ => "",
+ }
+ }
+ }
+ };
+ (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+ { display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*}
+ ) => {
+ |impl_error_chain_kind!(IDENT $self_): &$name, f: &mut ::std::fmt::Formatter| {
+ write_internal!(f, $( $exprs )*)
+ }
+ };
+ (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+ { display($pattern:expr) $( $tail:tt )*}
+ ) => {
+ |_, f: &mut ::std::fmt::Formatter| { write_internal!(f, $pattern) }
+ };
+ (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+ { display($pattern:expr, $( $exprs:tt )*) $( $tail:tt )*}
+ ) => {
+ |_, f: &mut ::std::fmt::Formatter| { write_internal!(f, $pattern, $( $exprs )*) }
+ };
+ (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+ { $t:tt $( $tail:tt )*}
+ ) => {
+ impl_error_chain_kind!(FIND_DISPLAY_IMPL
+ $name $item: $imode
+ {$( $tail )*})
+ };
+ (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+ { }
+ ) => {
+ |self_: &$name, f: &mut ::std::fmt::Formatter| {
+ write_internal!(f, "{}", self_.description())
+ }
+ };
+ (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+ [$( $var:ident ),*]
+ { description($expr:expr) $( $tail:tt )*}
+ ) => {
+ $expr
+ };
+ (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+ [$( $var:ident ),*]
+ { $t:tt $( $tail:tt )*}
+ ) => {
+ impl_error_chain_kind!(FIND_DESCRIPTION_IMPL
+ $item: $imode $me $fmt [$( $var ),*]
+ {$( $tail )*})
+ };
+ (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+ [$( $var:ident ),*]
+ { }
+ ) => {
+ stringify_internal!($item)
+ };
+ (ITEM_BODY $(#[$imeta:meta])* $item:ident: UNIT
+ ) => { };
+ (ITEM_BODY $(#[$imeta:meta])* $item:ident: TUPLE
+ [$( $typ:ty ),*]
+ ) => {
+ ($( $typ ),*)
+ };
+ (ITEM_BODY $(#[$imeta:meta])* $item:ident: STRUCT
+ [$( $var:ident: $typ:ty ),*]
+ ) => {
+ {$( $var:$typ ),*}
+ };
+ (ITEM_PATTERN $name:ident $item:ident: UNIT []
+ ) => {
+ $name::$item
+ };
+ (ITEM_PATTERN $name:ident $item:ident: TUPLE
+ [$( ref $var:ident ),*]
+ ) => {
+ $name::$item ($( ref $var ),*)
+ };
+ (ITEM_PATTERN $name:ident $item:ident: STRUCT
+ [$( ref $var:ident ),*]
+ ) => {
+ $name::$item {$( ref $var ),*}
+ };
+ // This one should match all allowed sequences in "funcs" but not match
+ // anything else.
+ // This is to contrast FIND_* clauses which just find stuff they need and
+ // skip everything else completely
+ (ERROR_CHECK $imode:tt display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
+ (ERROR_CHECK $imode:tt display($pattern: expr) $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
+ (ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
+ (ERROR_CHECK $imode:tt description($expr:expr) $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK_COMMA $imode $($tail)*); };
+ (ERROR_CHECK $imode:tt ) => {};
+ (ERROR_CHECK_COMMA $imode:tt , $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK $imode $($tail)*); };
+ (ERROR_CHECK_COMMA $imode:tt $( $tail:tt )*)
+ => { impl_error_chain_kind!(ERROR_CHECK $imode $($tail)*); };
+ // Utility functions
+ (IDENT $ident:ident) => { $ident }
+}
diff --git a/third_party/rust/error-chain/src/lib.rs b/third_party/rust/error-chain/src/lib.rs
new file mode 100644
index 0000000000..43d2d5f479
--- /dev/null
+++ b/third_party/rust/error-chain/src/lib.rs
@@ -0,0 +1,824 @@
+#![deny(missing_docs)]
+#![doc(html_root_url = "https://docs.rs/error-chain/0.12.4")]
+
+//! A library for consistent and reliable error handling
+//!
+//! error-chain makes it easy to take full advantage of Rust's
+//! powerful error handling features without the overhead of
+//! maintaining boilerplate error types and conversions. It implements
+//! an opinionated strategy for defining your own error types, as well
+//! as conversions from others' error types.
+//!
+//! ## Quick start
+//!
+//! If you just want to set up your new project with error-chain,
+//! follow the [quickstart.rs] template, and read this [intro]
+//! to error-chain.
+//!
+//! [quickstart.rs]: https://github.com/rust-lang-nursery/error-chain/blob/master/examples/quickstart.rs
+//! [intro]: http://brson.github.io/2016/11/30/starting-with-error-chain
+//!
+//! ## Why error chain?
+//!
+//! * error-chain is easy to configure. Handle errors robustly with minimal
+//! effort.
+//! * Basic error handling requires no maintenance of custom error types
+//! nor the [`From`] conversions that make `?` work.
+//! * error-chain scales from simple error handling strategies to more
+//! rigorous. Return formatted strings for simple errors, only
+//! introducing error variants and their strong typing as needed for
+//! advanced error recovery.
+//! * error-chain makes it trivial to correctly manage the [cause] of
+//! the errors generated by your own code. This is the "chaining"
+//! in "error-chain".
+//!
+//! [cause]: https://doc.rust-lang.org/std/error/trait.Error.html#method.cause
+//!
+//! ## Principles of error-chain
+//!
+//! error-chain is based on the following principles:
+//!
+//! * No error should ever be discarded. This library primarily
+//! makes it easy to "chain" errors with the [`chain_err`] method.
+//! * Introducing new errors is trivial. Simple errors can be introduced
+//! at the error site with just a string.
+//! * Handling errors is possible with pattern matching.
+//! * Conversions between error types are done in an automatic and
+//! consistent way - [`From`] conversion behavior is never specified
+//! explicitly.
+//! * Errors implement [`Send`].
+//! * Errors can carry backtraces.
+//!
+//! Similar to other libraries like [error-type] and [quick-error],
+//! this library introduces the error chaining mechanism originally
+//! employed by Cargo. The [`error_chain!`] macro declares the types
+//! and implementation boilerplate necessary for fulfilling a
+//! particular error-handling strategy. Most importantly it defines a
+//! custom error type (called [`Error`] by convention) and the [`From`]
+//! conversions that let the `?` operator work.
+//!
+//! This library differs in a few ways from previous error libs:
+//!
+//! * Instead of defining the custom [`Error`] type as an enum, it is a
+//! struct containing an [`ErrorKind`][] (which defines the
+//! [`description`] and [`display_chain`] methods for the error), an opaque,
+//! optional, boxed [`std::error::Error`]` + `[`Send`]` + 'static` object
+//! (which defines the [`cause`], and establishes the links in the
+//! error chain), and a [`Backtrace`].
+//! * The macro also defines a [`ResultExt`] trait that defines a
+//! [`chain_err`] method. This method on all [`std::error::Error`]` + `[`Send`]` + 'static`
+//! types extends the error chain by boxing the current
+//! error into an opaque object and putting it inside a new concrete
+//! error.
+//! * It provides automatic [`From`] conversions between other error types
+//! defined by the [`error_chain!`] that preserve type information,
+//! and facilitate seamless error composition and matching of composed
+//! errors.
+//! * It provides automatic [`From`] conversions between any other error
+//! type that hides the type of the other error in the [`cause`] box.
+//! * If `RUST_BACKTRACE` is enabled, it collects a single backtrace at
+//! the earliest opportunity and propagates it down the stack through
+//! [`From`] and [`ResultExt`] conversions.
+//!
+//! To accomplish its goals it makes some tradeoffs:
+//!
+//! * The split between the [`Error`] and [`ErrorKind`] types can make it
+//! slightly more cumbersome to instantiate new (unchained) errors,
+//! requiring an [`Into`] or [`From`] conversion; as well as slightly
+//! more cumbersome to match on errors with another layer of types
+//! to match.
+//! * Because the error type contains [`std::error::Error`]` + `[`Send`]` + 'static` objects,
+//! it can't implement [`PartialEq`] for easy comparisons.
+//!
+//! ## Declaring error types
+//!
+//! Generally, you define one family of error types per crate, though
+//! it's also perfectly fine to define error types on a finer-grained
+//! basis, such as per module.
+//!
+//! Assuming you are using crate-level error types, typically you will
+//! define an `errors` module and inside it call [`error_chain!`]:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! mod other_error {
+//! error_chain! {}
+//! }
+//!
+//! error_chain! {
+//! // The type defined for this error. These are the conventional
+//! // and recommended names, but they can be arbitrarily chosen.
+//! //
+//! // It is also possible to leave this section out entirely, or
+//! // leave it empty, and these names will be used automatically.
+//! types {
+//! Error, ErrorKind, ResultExt, Result;
+//! }
+//!
+//! // Without the `Result` wrapper:
+//! //
+//! // types {
+//! // Error, ErrorKind, ResultExt;
+//! // }
+//!
+//! // Automatic conversions between this error chain and other
+//! // error chains. In this case, it will e.g. generate an
+//! // `ErrorKind` variant called `Another` which in turn contains
+//! // the `other_error::ErrorKind`, with conversions from
+//! // `other_error::Error`.
+//! //
+//! // Optionally, some attributes can be added to a variant.
+//! //
+//! // This section can be empty.
+//! links {
+//! Another(other_error::Error, other_error::ErrorKind) #[cfg(unix)];
+//! }
+//!
+//! // Automatic conversions between this error chain and other
+//! // error types not defined by the `error_chain!`. These will be
+//! // wrapped in a new error with, in the first case, the
+//! // `ErrorKind::Fmt` variant. The description and cause will
+//! // forward to the description and cause of the original error.
+//! //
+//! // Optionally, some attributes can be added to a variant.
+//! //
+//! // This section can be empty.
+//! foreign_links {
+//! Fmt(::std::fmt::Error);
+//! Io(::std::io::Error) #[cfg(unix)];
+//! }
+//!
+//! // Define additional `ErrorKind` variants. Define custom responses with the
+//! // `description` and `display` calls.
+//! errors {
+//! InvalidToolchainName(t: String) {
+//! description("invalid toolchain name")
+//! display("invalid toolchain name: '{}'", t)
+//! }
+//!
+//! // You can also add commas after description/display.
+//! // This may work better with some editor auto-indentation modes:
+//! UnknownToolchainVersion(v: String) {
+//! description("unknown toolchain version"), // note the ,
+//! display("unknown toolchain version: '{}'", v), // trailing comma is allowed
+//! }
+//! }
+//!
+//! // If this annotation is left off, a variant `Msg(s: String)` will be added, and `From`
+//! // impls will be provided for `String` and `&str`
+//! skip_msg_variant
+//! }
+//!
+//! # fn main() {}
+//! ```
+//!
+//! Each section, `types`, `links`, `foreign_links`, and `errors` may
+//! be omitted if it is empty.
+//!
+//! This populates the module with a number of definitions,
+//! the most important of which are the [`Error`] type
+//! and the [`ErrorKind`] type. An example of generated code can be found in the
+//! [example_generated](example_generated/index.html) module.
+//!
+//! ## Returning new errors
+//!
+//! Introducing new error chains, with a string message:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! fn foo() -> Result<()> {
+//! Err("foo error!".into())
+//! }
+//! ```
+//!
+//! Introducing new error chains, with an [`ErrorKind`]:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! error_chain! {
+//! errors { FooError }
+//! }
+//!
+//! fn foo() -> Result<()> {
+//! Err(ErrorKind::FooError.into())
+//! }
+//! ```
+//!
+//! Note that the return type is the typedef [`Result`], which is
+//! defined by the macro as `pub type Result<T> =
+//! ::std::result::Result<T, Error>`. Note that in both cases
+//! [`.into()`] is called to convert a type into the [`Error`] type; both
+//! strings and [`ErrorKind`] have [`From`] conversions to turn them into
+//! [`Error`].
+//!
+//! When the error is emitted behind the `?` operator, the explicit conversion
+//! isn't needed; `Err(ErrorKind)` will automatically be converted to `Err(Error)`.
+//! So the below is equivalent to the previous:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! { errors { FooError } }
+//! fn foo() -> Result<()> {
+//! Ok(Err(ErrorKind::FooError)?)
+//! }
+//!
+//! fn bar() -> Result<()> {
+//! Ok(Err("bogus!")?)
+//! }
+//! ```
+//!
+//! ## The `bail!` macro
+//!
+//! The above method of introducing new errors works but is a little
+//! verbose. Instead, we can use the [`bail!`] macro, which performs an early return
+//! with conversions done automatically.
+//!
+//! With [`bail!`] the previous examples look like:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! { errors { FooError } }
+//! fn foo() -> Result<()> {
+//! if true {
+//! bail!(ErrorKind::FooError);
+//! } else {
+//! Ok(())
+//! }
+//! }
+//!
+//! fn bar() -> Result<()> {
+//! if true {
+//! bail!("bogus!");
+//! } else {
+//! Ok(())
+//! }
+//! }
+//! ```
+//!
+//! ## Chaining errors
+//! error-chain supports extending an error chain by appending new errors.
+//! This can be done on a Result or on an existing Error.
+//!
+//! To extend the error chain:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! # fn do_something() -> Result<()> { unimplemented!() }
+//! # fn test() -> Result<()> {
+//! let res: Result<()> = do_something().chain_err(|| "something went wrong");
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! [`chain_err`] can be called on any [`Result`] type where the contained
+//! error type implements [`std::error::Error`]` + `[`Send`]` + 'static`, as long as
+//! the [`Result`] type's corresponding [`ResultExt`] trait is in scope. If
+//! the [`Result`] is an `Err` then [`chain_err`] evaluates the closure,
+//! which returns *some type that can be converted to [`ErrorKind`]*,
+//! boxes the original error to store as the cause, then returns a new
+//! error containing the original error.
+//!
+//! Calling [`chain_err`][Error_chain_err] on an existing [`Error`] instance has
+//! the same signature and produces the same outcome as being called on a
+//! [`Result`] matching the properties described above. This is most useful when
+//! partially handling errors using the [`map_err`] function.
+//!
+//! To chain an error directly, use [`with_chain`]:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # error_chain! {}
+//! # fn do_something() -> Result<()> { unimplemented!() }
+//! # fn test() -> Result<()> {
+//! let res: Result<()> =
+//! do_something().map_err(|e| Error::with_chain(e, "something went wrong"));
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! ## Linking errors
+//!
+//! To convert an error from another error chain to this error chain:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {}
+//! # mod other { error_chain! {} }
+//! error_chain! {
+//! links {
+//! OtherError(other::Error, other::ErrorKind);
+//! }
+//! }
+//!
+//! fn do_other_thing() -> other::Result<()> { unimplemented!() }
+//!
+//! # fn test() -> Result<()> {
+//! let res: Result<()> = do_other_thing().map_err(|e| e.into());
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! The [`Error`] and [`ErrorKind`] types implements [`From`] for the corresponding
+//! types of all linked error chains. Linked errors do not introduce a new
+//! cause to the error chain.
+//!
+//! ## Matching errors
+//!
+//! error-chain error variants are matched with simple patterns.
+//! [`Error`] is a tuple struct and its first field is the [`ErrorKind`],
+//! making dispatching on error kinds relatively compact:
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! # fn main() {
+//! error_chain! {
+//! errors {
+//! InvalidToolchainName(t: String) {
+//! description("invalid toolchain name")
+//! display("invalid toolchain name: '{}'", t)
+//! }
+//! }
+//! }
+//!
+//! match Error::from("error!") {
+//! Error(ErrorKind::InvalidToolchainName(_), _) => { }
+//! Error(ErrorKind::Msg(_), _) => { }
+//! _ => { }
+//! }
+//! # }
+//! ```
+//!
+//! Chained errors are also matched with (relatively) compact syntax
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! mod utils {
+//! error_chain! {
+//! errors {
+//! BadStuff {
+//! description("bad stuff")
+//! }
+//! }
+//! }
+//! }
+//!
+//! mod app {
+//! error_chain! {
+//! links {
+//! Utils(::utils::Error, ::utils::ErrorKind);
+//! }
+//! }
+//! }
+//!
+//!
+//! # fn main() {
+//! match app::Error::from("error!") {
+//! app::Error(app::ErrorKind::Utils(utils::ErrorKind::BadStuff), _) => { }
+//! _ => { }
+//! }
+//! # }
+//! ```
+//!
+//! ## Inspecting errors
+//!
+//! An error-chain error contains information about the error itself, a backtrace, and the chain
+//! of causing errors. For reporting purposes, this information can be accessed as follows.
+//!
+//! ```
+//! # #[macro_use] extern crate error_chain;
+//! use error_chain::ChainedError; // for e.display_chain()
+//!
+//! error_chain! {
+//! errors {
+//! InvalidToolchainName(t: String) {
+//! description("invalid toolchain name")
+//! display("invalid toolchain name: '{}'", t)
+//! }
+//! }
+//! }
+//!
+//! # fn main() {
+//! // Generate an example error to inspect:
+//! let e = "xyzzy".parse::<i32>()
+//! .chain_err(|| ErrorKind::InvalidToolchainName("xyzzy".to_string()))
+//! .unwrap_err();
+//!
+//! // Get the brief description of the error:
+//! assert_eq!(e.description(), "invalid toolchain name");
+//!
+//! // Get the display version of the error:
+//! assert_eq!(e.to_string(), "invalid toolchain name: 'xyzzy'");
+//!
+//! // Get the full cause and backtrace:
+//! println!("{}", e.display_chain().to_string());
+//! // Error: invalid toolchain name: 'xyzzy'
+//! // Caused by: invalid digit found in string
+//! // stack backtrace:
+//! // 0: 0x7fa9f684fc94 - backtrace::backtrace::libunwind::trace
+//! // at src/backtrace/libunwind.rs:53
+//! // - backtrace::backtrace::trace<closure>
+//! // at src/backtrace/mod.rs:42
+//! // 1: 0x7fa9f6850b0e - backtrace::capture::{{impl}}::new
+//! // at out/capture.rs:79
+//! // [..]
+//! # }
+//! ```
+//!
+//! The [`Error`] and [`ErrorKind`] types also allow programmatic access to these elements.
+//!
+//! ## Foreign links
+//!
+//! Errors that do not conform to the same conventions as this library
+//! can still be included in the error chain. They are considered "foreign
+//! errors", and are declared using the `foreign_links` block of the
+//! [`error_chain!`] macro. [`Error`]s are automatically created from
+//! foreign errors by the `?` operator.
+//!
+//! Foreign links and regular links have one crucial difference:
+//! [`From`] conversions for regular links *do not introduce a new error
+//! into the error chain*, while conversions for foreign links *always
+//! introduce a new error into the error chain*. So for the example
+//! above all errors deriving from the [`std::fmt::Error`] type will be
+//! presented to the user as a new [`ErrorKind`] variant, and the
+//! cause will be the original [`std::fmt::Error`] error. In contrast, when
+//! `other_error::Error` is converted to `Error` the two `ErrorKind`s
+//! are converted between each other to create a new `Error` but the
+//! old error is discarded; there is no "cause" created from the
+//! original error.
+//!
+//! ## Backtraces
+//!
+//! If the `RUST_BACKTRACE` environment variable is set to anything
+//! but ``0``, the earliest non-foreign error to be generated creates
+//! a single backtrace, which is passed through all [`From`] conversions
+//! and [`chain_err`] invocations of compatible types. To read the
+//! backtrace just call the [`backtrace`] method.
+//!
+//! Backtrace generation can be disabled by turning off the `backtrace` feature.
+//!
+//! The Backtrace contains a Vec of [`BacktraceFrame`]s that can be operated
+//! on directly. For example, to only see the files and line numbers of code
+//! within your own project.
+//!
+//! ```
+//! # #[macro_use]
+//! # extern crate error_chain;
+//! # mod errors {
+//! # error_chain! {
+//! # foreign_links {
+//! # Io(::std::io::Error);
+//! # }
+//! # }
+//! # }
+//! # use errors::*;
+//! # #[cfg(feature="backtrace")]
+//! # fn main() {
+//! if let Err(ref e) = open_file() {
+//! if let Some(backtrace) = e.backtrace() {
+//! let frames = backtrace.frames();
+//! for frame in frames.iter() {
+//! for symbol in frame.symbols().iter() {
+//! if let (Some(file), Some(lineno)) = (symbol.filename(), symbol.lineno()) {
+//! if file.display().to_string()[0..3] == "src".to_string(){
+//! println!("{}:{}", file.display().to_string(), lineno);
+//! }
+//! }
+//! }
+//! }
+//! }
+//! };
+//! # }
+//! # #[cfg(not(feature="backtrace"))]
+//! # fn main() { }
+//!
+//! fn open_file() -> Result<()> {
+//! std::fs::File::open("does_not_exist")?;
+//! Ok(())
+//! }
+//! ```
+//!
+//! ## Iteration
+//!
+//! The [`iter`] method returns an iterator over the chain of error boxes.
+//!
+//! [error-type]: https://github.com/DanielKeep/rust-error-type
+//! [quick-error]: https://github.com/tailhook/quick-error
+
+//! [`display_chain`]: trait.ChainedError.html#method.display_chain
+//! [`error_chain!`]: macro.error_chain.html
+//! [`bail!`]: macro.bail.html
+//! [`Backtrace`]: struct.Backtrace.html
+
+//! [`Error`]: example_generated/struct.Error.html
+//! [`with_chain`]: example_generated/struct.Error.html#method.with_chain
+//! [Error_chain_err]: example_generated/struct.Error.html#method.chain_err
+//! [`cause`]: example_generated/struct.Error.html#method.cause
+//! [`backtrace`]: example_generated/struct.Error.html#method.backtrace
+//! [`iter`]: example_generated/struct.Error.html#method.iter
+//! [`ErrorKind`]: example_generated/enum.ErrorKind.html
+//! [`description`]: example_generated/enum.ErrorKind.html#method.description
+//! [`Result`]: example_generated/type.Result.html
+//! [`ResultExt`]: example_generated/trait.ResultExt.html
+//! [`chain_err`]: example_generated/trait.ResultExt.html#tymethod.chain_err
+
+//! [`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
+//! [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
+//! [`Into`]: https://doc.rust-lang.org/std/convert/trait.Into.html
+//! [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
+//! [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html
+//! [`std::fmt::Error`]: https://doc.rust-lang.org/std/fmt/struct.Error.html
+//! [`.into()`]: https://doc.rust-lang.org/std/convert/trait.Into.html#tymethod.into
+//! [`map_err`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.map_err
+//! [`BacktraceFrame`]: https://docs.rs/backtrace/0.3.2/backtrace/struct.BacktraceFrame.html
+
+use std::error;
+use std::fmt;
+use std::iter::Iterator;
+
+#[macro_use]
+mod impl_error_chain_kind;
+#[macro_use]
+mod error_chain;
+#[macro_use]
+mod quick_main;
+pub use quick_main::ExitCode;
+mod backtrace;
+#[cfg(feature = "example_generated")]
+pub mod example_generated;
+pub use backtrace::Backtrace;
+#[doc(hidden)]
+pub use backtrace::InternalBacktrace;
+
+#[derive(Debug)]
+#[allow(unknown_lints, bare_trait_objects)]
+/// Iterator over the error chain using the `Error::cause()` method.
+pub struct Iter<'a>(Option<&'a error::Error>);
+
+impl<'a> Iter<'a> {
+ /// Returns a new iterator over the error chain using `Error::cause()`.
+ #[allow(unknown_lints, bare_trait_objects)]
+ pub fn new(err: Option<&'a error::Error>) -> Iter<'a> {
+ Iter(err)
+ }
+}
+
+#[allow(unknown_lints, bare_trait_objects)]
+impl<'a> Iterator for Iter<'a> {
+ type Item = &'a error::Error;
+
+ fn next<'b>(&'b mut self) -> Option<&'a error::Error> {
+ match self.0.take() {
+ Some(e) => {
+ self.0 = match () {
+ #[cfg(not(has_error_source))]
+ () => e.cause(),
+ #[cfg(has_error_source)]
+ () => e.source(),
+ };
+ Some(e)
+ }
+ None => None,
+ }
+ }
+}
+
+/// This trait is implemented on all the errors generated by the `error_chain`
+/// macro.
+pub trait ChainedError: error::Error + Send + 'static {
+ /// Associated kind type.
+ type ErrorKind;
+
+ /// Constructs an error from a kind, and generates a backtrace.
+ fn from_kind(kind: Self::ErrorKind) -> Self
+ where
+ Self: Sized;
+
+ /// Constructs a chained error from another error and a kind, and generates a backtrace.
+ fn with_chain<E, K>(error: E, kind: K) -> Self
+ where
+ Self: Sized,
+ E: ::std::error::Error + Send + 'static,
+ K: Into<Self::ErrorKind>;
+
+ /// Returns the kind of the error.
+ fn kind(&self) -> &Self::ErrorKind;
+
+ /// Iterates over the error chain.
+ fn iter(&self) -> Iter;
+
+ /// Returns the backtrace associated with this error.
+ fn backtrace(&self) -> Option<&Backtrace>;
+
+ /// Returns an object which implements `Display` for printing the full
+ /// context of this error.
+ ///
+ /// The full cause chain and backtrace, if present, will be printed.
+ fn display_chain<'a>(&'a self) -> DisplayChain<'a, Self> {
+ DisplayChain(self)
+ }
+
+ /// Extends the error chain with a new entry.
+ fn chain_err<F, EK>(self, error: F) -> Self
+ where
+ F: FnOnce() -> EK,
+ EK: Into<Self::ErrorKind>;
+
+ /// Creates an error from its parts.
+ #[doc(hidden)]
+ fn new(kind: Self::ErrorKind, state: State) -> Self
+ where
+ Self: Sized;
+
+ /// Returns the first known backtrace, either from its State or from one
+ /// of the errors from `foreign_links`.
+ #[doc(hidden)]
+ #[allow(unknown_lints, bare_trait_objects)]
+ fn extract_backtrace(e: &(error::Error + Send + 'static)) -> Option<InternalBacktrace>
+ where
+ Self: Sized;
+}
+
+/// A struct which formats an error for output.
+#[derive(Debug)]
+pub struct DisplayChain<'a, T: 'a + ?Sized>(&'a T);
+
+impl<'a, T> fmt::Display for DisplayChain<'a, T>
+where
+ T: ChainedError,
+{
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ writeln!(fmt, "Error: {}", self.0)?;
+
+ for e in self.0.iter().skip(1) {
+ writeln!(fmt, "Caused by: {}", e)?;
+ }
+
+ if let Some(backtrace) = ChainedError::backtrace(self.0) {
+ writeln!(fmt, "{:?}", backtrace)?;
+ }
+
+ Ok(())
+ }
+}
+
+/// Common state between errors.
+#[derive(Debug)]
+#[doc(hidden)]
+#[allow(unknown_lints, bare_trait_objects)]
+pub struct State {
+ /// Next error in the error chain.
+ pub next_error: Option<Box<error::Error + Send>>,
+ /// Backtrace for the current error.
+ pub backtrace: InternalBacktrace,
+}
+
+impl Default for State {
+ fn default() -> State {
+ State {
+ next_error: None,
+ backtrace: InternalBacktrace::new(),
+ }
+ }
+}
+
+impl State {
+ /// Creates a new State type
+ #[allow(unknown_lints, bare_trait_objects)]
+ pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
+ let backtrace = CE::extract_backtrace(&*e).unwrap_or_else(InternalBacktrace::new);
+ State {
+ next_error: Some(e),
+ backtrace: backtrace,
+ }
+ }
+
+ /// Returns the inner backtrace if present.
+ pub fn backtrace(&self) -> Option<&Backtrace> {
+ self.backtrace.as_backtrace()
+ }
+}
+
+/// Exits a function early with an error
+///
+/// The `bail!` macro provides an easy way to exit a function.
+/// `bail!(expr)` is equivalent to writing.
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let expr = "";
+/// return Err(expr.into());
+/// # }
+/// ```
+///
+/// And as shorthand it takes a formatting string a la `println!`:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let n = 0;
+/// bail!("bad number: {}", n);
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// Bailing on a custom error:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # fn main() {}
+/// error_chain! {
+/// errors { FooError }
+/// }
+///
+/// fn foo() -> Result<()> {
+/// if bad_condition() {
+/// bail!(ErrorKind::FooError);
+/// }
+///
+/// Ok(())
+/// }
+///
+/// # fn bad_condition() -> bool { true }
+/// ```
+///
+/// Bailing on a formatted string:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # fn main() {}
+/// error_chain! { }
+///
+/// fn foo() -> Result<()> {
+/// if let Some(bad_num) = bad_condition() {
+/// bail!("so bad: {}", bad_num);
+/// }
+///
+/// Ok(())
+/// }
+///
+/// # fn bad_condition() -> Option<i8> { None }
+/// ```
+#[macro_export]
+macro_rules! bail {
+ ($e:expr) => {
+ return Err($e.into());
+ };
+ ($fmt:expr, $($arg:tt)+) => {
+ return Err(format!($fmt, $($arg)+).into());
+ };
+}
+
+/// Exits a function early with an error if the condition is not satisfied
+///
+/// The `ensure!` macro is a convenience helper that provides a way to exit
+/// a function with an error if the given condition fails.
+///
+/// As an example, `ensure!(condition, "error code: {}", errcode)` is equivalent to
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! { }
+/// # fn main() { }
+/// # fn foo() -> Result<()> {
+/// # let errcode = 0u8;
+/// # let condition = true;
+/// if !condition {
+/// bail!("error code: {}", errcode);
+/// }
+/// # Ok(())
+/// # }
+/// ```
+///
+/// See documentation for `bail!` macro for further details.
+#[macro_export(local_inner_macros)]
+macro_rules! ensure {
+ ($cond:expr, $e:expr) => {
+ if !($cond) {
+ bail!($e);
+ }
+ };
+ ($cond:expr, $fmt:expr, $($arg:tt)+) => {
+ if !($cond) {
+ bail!($fmt, $($arg)+);
+ }
+ };
+}
+
+#[doc(hidden)]
+pub mod mock {
+ error_chain! {}
+}
diff --git a/third_party/rust/error-chain/src/quick_main.rs b/third_party/rust/error-chain/src/quick_main.rs
new file mode 100644
index 0000000000..a6f093d2b3
--- /dev/null
+++ b/third_party/rust/error-chain/src/quick_main.rs
@@ -0,0 +1,81 @@
+/// Convenient wrapper to be able to use `?` and such in the main. You can
+/// use it with a separated function:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! {}
+/// # fn main() {
+/// quick_main!(run);
+/// # }
+///
+/// fn run() -> Result<()> {
+/// Err("error".into())
+/// }
+/// ```
+///
+/// or with a closure:
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! {}
+/// # fn main() {
+/// quick_main!(|| -> Result<()> {
+/// Err("error".into())
+/// });
+/// # }
+/// ```
+///
+/// You can also set the exit value of the process by returning a type that implements [`ExitCode`](trait.ExitCode.html):
+///
+/// ```
+/// # #[macro_use] extern crate error_chain;
+/// # error_chain! {}
+/// # fn main() {
+/// quick_main!(run);
+/// # }
+///
+/// fn run() -> Result<i32> {
+/// Err("error".into())
+/// }
+/// ```
+#[macro_export]
+macro_rules! quick_main {
+ ($main:expr) => {
+ fn main() {
+ use std::io::Write;
+
+ ::std::process::exit(match $main() {
+ Ok(ret) => $crate::ExitCode::code(ret),
+ Err(ref e) => {
+ write!(
+ &mut ::std::io::stderr(),
+ "{}",
+ $crate::ChainedError::display_chain(e)
+ )
+ .expect("Error writing to stderr");
+
+ 1
+ }
+ });
+ }
+ };
+}
+
+/// Represents a value that can be used as the exit status of the process.
+/// See [`quick_main!`](macro.quick_main.html).
+pub trait ExitCode {
+ /// Returns the value to use as the exit status.
+ fn code(self) -> i32;
+}
+
+impl ExitCode for i32 {
+ fn code(self) -> i32 {
+ self
+ }
+}
+
+impl ExitCode for () {
+ fn code(self) -> i32 {
+ 0
+ }
+}
diff --git a/third_party/rust/error-chain/tests/quick_main.rs b/third_party/rust/error-chain/tests/quick_main.rs
new file mode 100644
index 0000000000..4ada3b4e03
--- /dev/null
+++ b/third_party/rust/error-chain/tests/quick_main.rs
@@ -0,0 +1,28 @@
+#![allow(dead_code)]
+#[macro_use]
+extern crate error_chain;
+
+error_chain!();
+
+mod unit {
+ use super::*;
+ quick_main!(run);
+
+ fn run() -> Result<()> {
+ Ok(())
+ }
+}
+
+mod i32 {
+ use super::*;
+ quick_main!(run);
+
+ fn run() -> Result<i32> {
+ Ok(1)
+ }
+}
+
+mod closure {
+ use super::*;
+ quick_main!(|| -> Result<()> { Ok(()) });
+}
diff --git a/third_party/rust/error-chain/tests/tests.rs b/third_party/rust/error-chain/tests/tests.rs
new file mode 100644
index 0000000000..e9d183c577
--- /dev/null
+++ b/third_party/rust/error-chain/tests/tests.rs
@@ -0,0 +1,719 @@
+#![allow(dead_code)]
+
+#[macro_use]
+extern crate error_chain;
+
+#[test]
+fn smoke_test_1() {
+ error_chain! {
+ types {
+ Error, ErrorKind, ResultExt, Result;
+ }
+
+ links { }
+
+ foreign_links { }
+
+ errors { }
+ };
+}
+
+#[test]
+fn smoke_test_2() {
+ error_chain! {
+ types { }
+
+ links { }
+
+ foreign_links { }
+
+ errors { }
+ };
+}
+
+#[test]
+fn smoke_test_3() {
+ error_chain! {
+ links { }
+
+ foreign_links { }
+
+ errors { }
+ };
+}
+
+#[test]
+fn smoke_test_4() {
+ error_chain! {
+ links { }
+
+ foreign_links { }
+
+ errors {
+ HttpStatus(e: u32) {
+ description("http request returned an unsuccessful status code")
+ display("http request returned an unsuccessful status code: {}", e)
+ }
+ }
+ };
+}
+
+#[test]
+fn smoke_test_5() {
+ error_chain! {
+ types { }
+
+ links { }
+
+ foreign_links { }
+
+ errors {
+ HttpStatus(e: u32) {
+ description("http request returned an unsuccessful status code")
+ display("http request returned an unsuccessful status code: {}", e)
+ }
+ }
+ };
+}
+
+#[test]
+fn smoke_test_6() {
+ error_chain! {
+ errors {
+ HttpStatus(e: u32) {
+ description("http request returned an unsuccessful status code")
+ display("http request returned an unsuccessful status code: {}", e)
+ }
+ }
+ };
+}
+
+#[test]
+fn smoke_test_7() {
+ error_chain! {
+ types { }
+
+ foreign_links { }
+
+ errors {
+ HttpStatus(e: u32) {
+ description("http request returned an unsuccessful status code")
+ display("http request returned an unsuccessful status code: {}", e)
+ }
+ }
+ };
+}
+
+#[test]
+fn smoke_test_8() {
+ error_chain! {
+ types { }
+
+ links { }
+ links { }
+
+ foreign_links { }
+ foreign_links { }
+
+ errors {
+ FileNotFound
+ AccessDenied
+ }
+ };
+}
+
+#[test]
+fn order_test_1() {
+ error_chain! { types { } links { } foreign_links { } errors { } };
+}
+
+#[test]
+fn order_test_2() {
+ error_chain! { links { } types { } foreign_links { } errors { } };
+}
+
+#[test]
+fn order_test_3() {
+ error_chain! { foreign_links { } links { } errors { } types { } };
+}
+
+#[test]
+fn order_test_4() {
+ error_chain! { errors { } types { } foreign_links { } };
+}
+
+#[test]
+fn order_test_5() {
+ error_chain! { foreign_links { } types { } };
+}
+
+#[test]
+fn order_test_6() {
+ error_chain! {
+ links { }
+
+ errors {
+ HttpStatus(e: u32) {
+ description("http request returned an unsuccessful status code")
+ display("http request returned an unsuccessful status code: {}", e)
+ }
+ }
+
+
+ foreign_links { }
+ };
+}
+
+#[test]
+fn order_test_7() {
+ error_chain! {
+ links { }
+
+ foreign_links { }
+
+ types {
+ Error, ErrorKind, ResultExt, Result;
+ }
+ };
+}
+
+#[test]
+fn order_test_8() {
+ error_chain! {
+ links { }
+
+ foreign_links { }
+ foreign_links { }
+
+ types {
+ Error, ErrorKind, ResultExt, Result;
+ }
+ };
+}
+
+#[test]
+fn empty() {
+ error_chain! {};
+}
+
+#[test]
+#[cfg(feature = "backtrace")]
+fn has_backtrace_depending_on_env() {
+ use std::path::PathBuf;
+ use std::process::Command;
+
+ let cmd_folder = if cfg!(build = "debug") {
+ "debug"
+ } else if cfg!(build = "release") {
+ "release"
+ } else {
+ panic!("Unknown build config");
+ };
+
+ let cmd_path = if cfg!(windows) {
+ PathBuf::from(format!(
+ "./target/{}/examples/has_backtrace.exe",
+ cmd_folder
+ ))
+ } else {
+ PathBuf::from(format!("./target/{}/examples/has_backtrace", cmd_folder))
+ };
+ let mut cmd = Command::new(cmd_path);
+
+ // missing RUST_BACKTRACE and RUST_BACKTRACE=0
+ cmd.env_remove("RUST_BACKTRACE");
+ assert_eq!(cmd.status().unwrap().code().unwrap(), 0);
+
+ cmd.env("RUST_BACKTRACE", "0");
+ assert_eq!(cmd.status().unwrap().code().unwrap(), 0);
+
+ // RUST_BACKTRACE set to anything but 0
+ cmd.env("RUST_BACKTRACE", "yes");
+ assert_eq!(cmd.status().unwrap().code().unwrap(), 1);
+
+ cmd.env("RUST_BACKTRACE", "1");
+ assert_eq!(cmd.status().unwrap().code().unwrap(), 1);
+}
+
+#[test]
+fn chain_err() {
+ use std::fmt;
+
+ error_chain! {
+ foreign_links {
+ Fmt(fmt::Error);
+ }
+ errors {
+ Test
+ }
+ }
+
+ let _: Result<()> = Err(fmt::Error).chain_err(|| "");
+ let _: Result<()> = Err(Error::from_kind(ErrorKind::Test)).chain_err(|| "");
+}
+
+/// Verify that an error chain is extended one by `Error::chain_err`, with
+/// the new error added to the end.
+#[test]
+fn error_chain_err() {
+ error_chain! {
+ errors {
+ Test
+ }
+ }
+
+ let base = Error::from(ErrorKind::Test);
+ let ext = base.chain_err(|| "Test passes");
+
+ if let Error(ErrorKind::Msg(_), _) = ext {
+ // pass
+ } else {
+ panic!("The error should be wrapped. {:?}", ext);
+ }
+}
+
+#[test]
+fn links() {
+ mod test {
+ error_chain! {}
+ }
+
+ error_chain! {
+ links {
+ Test(test::Error, test::ErrorKind);
+ }
+ }
+}
+
+#[cfg(test)]
+mod foreign_link_test {
+
+ use std::fmt;
+
+ // Note: foreign errors must be `pub` because they appear in the
+ // signature of the public foreign_link_error_path
+ #[derive(Debug)]
+ pub struct ForeignError {
+ cause: ForeignErrorCause,
+ }
+
+ impl ::std::error::Error for ForeignError {
+ fn description(&self) -> &'static str {
+ "Foreign error description"
+ }
+
+ #[cfg(not(has_error_source))]
+ fn cause(&self) -> Option<&::std::error::Error> {
+ Some(&self.cause)
+ }
+
+ #[cfg(has_error_source)]
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ Some(&self.cause)
+ }
+ }
+
+ impl fmt::Display for ForeignError {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "Foreign error display")
+ }
+ }
+
+ #[derive(Debug)]
+ pub struct ForeignErrorCause {}
+
+ impl ::std::error::Error for ForeignErrorCause {
+ fn description(&self) -> &'static str {
+ "Foreign error cause description"
+ }
+
+ #[cfg(not(has_error_source))]
+ fn cause(&self) -> Option<&::std::error::Error> {
+ None
+ }
+
+ #[cfg(has_error_source)]
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ None
+ }
+ }
+
+ impl fmt::Display for ForeignErrorCause {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "Foreign error cause display")
+ }
+ }
+
+ error_chain! {
+ types{
+ Error, ErrorKind, ResultExt, Result;
+ }
+ links {}
+ foreign_links {
+ Foreign(ForeignError);
+ Io(::std::io::Error);
+ }
+ errors {}
+ }
+
+ #[test]
+ fn display_underlying_error() {
+ let chained_error = try_foreign_error().err().unwrap();
+ assert_eq!(
+ format!(
+ "{}",
+ ForeignError {
+ cause: ForeignErrorCause {}
+ }
+ ),
+ format!("{}", chained_error)
+ );
+ }
+
+ #[test]
+ #[cfg(not(has_error_source))]
+ fn finds_cause() {
+ let chained_error = try_foreign_error().err().unwrap();
+ assert_eq!(
+ format!("{}", ForeignErrorCause {}),
+ format!("{}", ::std::error::Error::cause(&chained_error).unwrap())
+ );
+ }
+
+ #[test]
+ #[cfg(has_error_source)]
+ fn finds_source() {
+ let chained_error = try_foreign_error().err().unwrap();
+ assert_eq!(
+ format!("{}", ForeignErrorCause {}),
+ format!("{}", ::std::error::Error::source(&chained_error).unwrap())
+ );
+ }
+
+ #[test]
+ #[allow(unknown_lints, bare_trait_objects)]
+ fn iterates() {
+ let chained_error = try_foreign_error().err().unwrap();
+ let mut error_iter = chained_error.iter();
+ assert!(!format!("{:?}", error_iter).is_empty());
+ assert_eq!(
+ format!(
+ "{}",
+ ForeignError {
+ cause: ForeignErrorCause {}
+ }
+ ),
+ format!("{}", error_iter.next().unwrap())
+ );
+ assert_eq!(
+ format!("{}", ForeignErrorCause {}),
+ format!("{}", error_iter.next().unwrap())
+ );
+ assert_eq!(
+ format!("{:?}", None as Option<&::std::error::Error>),
+ format!("{:?}", error_iter.next())
+ );
+ }
+
+ fn try_foreign_error() -> Result<()> {
+ Err(ForeignError {
+ cause: ForeignErrorCause {},
+ })?;
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod attributes_test {
+ #[allow(unused_imports)]
+ use std::io;
+
+ #[cfg(not(test))]
+ mod inner {
+ error_chain! {}
+ }
+
+ error_chain! {
+ types {
+ Error, ErrorKind, ResultExt, Result;
+ }
+
+ links {
+ Inner(inner::Error, inner::ErrorKind) #[cfg(not(test))];
+ }
+
+ foreign_links {
+ Io(io::Error) #[cfg(not(test))];
+ }
+
+ errors {
+ #[cfg(not(test))]
+ AnError {
+
+ }
+ }
+ }
+}
+
+#[test]
+fn with_result() {
+ error_chain! {
+ types {
+ Error, ErrorKind, ResultExt, Result;
+ }
+ }
+ let _: Result<()> = Ok(());
+}
+
+#[test]
+fn without_result() {
+ error_chain! {
+ types {
+ Error, ErrorKind, ResultExt;
+ }
+ }
+ let _: Result<(), ()> = Ok(());
+}
+
+#[test]
+fn documentation() {
+ mod inner {
+ error_chain! {}
+ }
+
+ error_chain! {
+ links {
+ Inner(inner::Error, inner::ErrorKind) #[doc = "Doc"];
+ }
+ foreign_links {
+ Io(::std::io::Error) #[doc = "Doc"];
+ }
+ errors {
+ /// Doc
+ Variant
+ }
+ }
+}
+
+#[cfg(test)]
+mod multiple_error_same_mod {
+ error_chain! {
+ types {
+ MyError, MyErrorKind, MyResultExt, MyResult;
+ }
+ }
+ error_chain! {}
+}
+
+#[doc(test)]
+#[deny(dead_code)]
+mod allow_dead_code {
+ error_chain! {}
+}
+
+// Make sure links actually work!
+#[test]
+fn rustup_regression() {
+ error_chain! {
+ links {
+ Download(error_chain::mock::Error, error_chain::mock::ErrorKind);
+ }
+
+ foreign_links { }
+
+ errors {
+ LocatingWorkingDir {
+ description("could not locate working directory")
+ }
+ }
+ }
+}
+
+#[test]
+fn error_patterns() {
+ error_chain! {
+ links { }
+
+ foreign_links { }
+
+ errors { }
+ }
+
+ // Tuples look nice when matching errors
+ match Error::from("Test") {
+ Error(ErrorKind::Msg(_), _) => {}
+ _ => {}
+ }
+}
+
+#[test]
+fn result_match() {
+ error_chain! {}
+
+ fn ok() -> Result<()> {
+ Ok(())
+ }
+
+ match ok() {
+ Ok(()) => {}
+ Err(Error(ErrorKind::Msg(_), _)) => {}
+ Err(..) => {}
+ }
+}
+
+#[test]
+fn error_first() {
+ error_chain! {
+ errors {
+ LocatingWorkingDir {
+ description("could not locate working directory")
+ }
+ }
+
+ links {
+ Download(error_chain::mock::Error, error_chain::mock::ErrorKind);
+ }
+
+ foreign_links { }
+ }
+}
+
+#[test]
+fn bail() {
+ error_chain! {
+ errors { Foo }
+ }
+
+ fn foo() -> Result<()> {
+ bail!(ErrorKind::Foo)
+ }
+
+ fn bar() -> Result<()> {
+ bail!("bar")
+ }
+
+ fn baz() -> Result<()> {
+ bail!("{}", "baz")
+ }
+}
+
+#[test]
+fn ensure() {
+ error_chain! {
+ errors { Bar }
+ }
+
+ fn foo(x: u8) -> Result<()> {
+ ensure!(x == 42, ErrorKind::Bar);
+ Ok(())
+ }
+
+ assert!(foo(42).is_ok());
+ assert!(foo(0).is_err());
+}
+
+/// Since the `types` declaration is a list of symbols, check if we
+/// don't change their meaning or order.
+#[test]
+fn types_declarations() {
+ error_chain! {
+ types {
+ MyError, MyErrorKind, MyResultExt, MyResult;
+ }
+ }
+
+ MyError::from_kind(MyErrorKind::Msg("".into()));
+
+ let err: Result<(), ::std::io::Error> = Ok(());
+ MyResultExt::chain_err(err, || "").unwrap();
+
+ let _: MyResult<()> = Ok(());
+}
+
+#[test]
+/// Calling chain_err over a `Result` containing an error to get a chained error
+/// and constructing a MyError directly, passing it an error should be equivalent.
+fn rewrapping() {
+ use std::env::VarError::{self, NotPresent, NotUnicode};
+
+ error_chain! {
+ foreign_links {
+ VarErr(VarError);
+ }
+
+ types {
+ MyError, MyErrorKind, MyResultExt, MyResult;
+ }
+ }
+
+ let result_a_from_func: Result<String, _> = Err(VarError::NotPresent);
+ let result_b_from_func: Result<String, _> = Err(VarError::NotPresent);
+
+ let our_error_a = result_a_from_func.map_err(|e| match e {
+ NotPresent => MyError::with_chain(e, "env var wasn't provided"),
+ NotUnicode(_) => MyError::with_chain(e, "env var was bork文字化ã"),
+ });
+
+ let our_error_b = result_b_from_func.or_else(|e| match e {
+ NotPresent => Err(e).chain_err(|| "env var wasn't provided"),
+ NotUnicode(_) => Err(e).chain_err(|| "env var was bork文字化ã"),
+ });
+
+ assert_eq!(
+ format!("{}", our_error_a.unwrap_err()),
+ format!("{}", our_error_b.unwrap_err())
+ );
+}
+
+#[test]
+fn comma_in_errors_impl() {
+ error_chain! {
+ links { }
+
+ foreign_links { }
+
+ errors {
+ HttpStatus(e: u32) {
+ description("http request returned an unsuccessful status code"),
+ display("http request returned an unsuccessful status code: {}", e)
+ }
+ }
+ };
+}
+
+#[test]
+fn trailing_comma_in_errors_impl() {
+ error_chain! {
+ links { }
+
+ foreign_links { }
+
+ errors {
+ HttpStatus(e: u32) {
+ description("http request returned an unsuccessful status code"),
+ display("http request returned an unsuccessful status code: {}", e),
+ }
+ }
+ };
+}
+
+#[test]
+fn skipping_msg_variant() {
+ error_chain! {
+ skip_msg_variant
+
+ errors {
+ MyMsg(s: String) {
+ description(&s)
+ display("{}", s)
+ }
+ }
+ }
+
+ let x = Error::from_kind(ErrorKind::MyMsg("some string".into()));
+ // This would fail to compile if we generate a `Msg` variant
+ match *x.kind() {
+ ErrorKind::MyMsg(_) => {}
+ ErrorKind::__Nonexhaustive {} => {}
+ }
+}