diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 4cd31f5..0000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/.vagga -/target -/Cargo.lock diff --git a/.lock b/.lock new file mode 100755 index 0000000..e69de29 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0c96a5e..0000000 --- a/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -sudo: false -dist: trusty -language: rust - -cache: -- cargo - -before_cache: -- rm -r $TRAVIS_BUILD_DIR/target/debug - -jobs: - include: - - os: linux - rust: stable - - os: linux - rust: beta - - os: linux - rust: nightly - - # deploy - - stage: publish - os: linux - rust: stable - install: true - script: true - - deploy: - - provider: script - script: 'cargo publish --verbose --token=$CARGO_TOKEN' - on: - tags: true diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt new file mode 100644 index 0000000..c69861a --- /dev/null +++ b/COPYRIGHT.txt @@ -0,0 +1,59 @@ +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff, FiraSans-Medium.woff): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* Heuristica (Heuristica-Italic.woff): + + Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved. + Utopia is either a registered trademark or trademark of Adobe Systems + Incorporated in the United States and/or other countries. Used under + license. + + Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net + + Copyright (c) 2008-2012, Andrey V. Panov (panov@canopus.iacp.dvo.ru), + with Reserved Font Name Heuristica. + + Licensed under the SIL Open Font License, Version 1.1. + See Heuristica-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.woff, SourceCodePro-Semibold.woff): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif Pro (SourceSerifPro-Regular.woff, SourceSerifPro-Bold.woff): + + Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with + Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of + Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerifPro-LICENSE.txt. + +This copyright file is intended to be distributed with rustdoc output. diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 022b543..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "quick-error" -description = """ - A macro which makes error types pleasant to write. -""" -license = "MIT/Apache-2.0" -version = "2.0.1" -edition = "2018" -keywords = ["macro", "error", "type", "enum"] -authors = ["Paul Colomiets ", "Colin Kiegel "] -homepage = "http://github.com/tailhook/quick-error" -repository = "http://github.com/tailhook/quick-error" -documentation = "http://docs.rs/quick-error" -categories = ["rust-patterns"] diff --git a/FiraSans-LICENSE.txt b/FiraSans-LICENSE.txt new file mode 100644 index 0000000..b4a3967 --- /dev/null +++ b/FiraSans-LICENSE.txt @@ -0,0 +1,99 @@ +Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ +with Reserved Font Name Fira Sans. + +Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ +with Reserved Font Name Fira Mono. + +Copyright (c) 2014, Telefonica S.A. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/FiraSans-Medium.woff b/FiraSans-Medium.woff new file mode 100644 index 0000000..5627227 Binary files /dev/null and b/FiraSans-Medium.woff differ diff --git a/FiraSans-Regular.woff b/FiraSans-Regular.woff new file mode 100644 index 0000000..9ff4044 Binary files /dev/null and b/FiraSans-Regular.woff differ diff --git a/Heuristica-Italic.woff b/Heuristica-Italic.woff new file mode 100644 index 0000000..b0cebf0 Binary files /dev/null and b/Heuristica-Italic.woff differ diff --git a/Heuristica-LICENSE.txt b/Heuristica-LICENSE.txt new file mode 100644 index 0000000..dd85e40 --- /dev/null +++ b/Heuristica-LICENSE.txt @@ -0,0 +1,101 @@ +Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved. +Utopia is either a registered trademark or trademark of Adobe Systems +Incorporated in the United States and/or other countries. Used under +license. + +Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net + +Copyright (c) 2008-2012, Andrey V. Panov (panov@canopus.iacp.dvo.ru), +with Reserved Font Name Heuristica. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/LICENSE-APACHE b/LICENSE-APACHE deleted file mode 100644 index 8f71f43..0000000 --- a/LICENSE-APACHE +++ /dev/null @@ -1,202 +0,0 @@ - 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/LICENSE-APACHE.txt b/LICENSE-APACHE.txt new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/LICENSE-APACHE.txt @@ -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/LICENSE-MIT b/LICENSE-MIT deleted file mode 100644 index 14f715b..0000000 --- a/LICENSE-MIT +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015 The quick-error 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/LICENSE-MIT.txt b/LICENSE-MIT.txt new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/LICENSE-MIT.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.rst b/README.rst deleted file mode 100644 index 67773e8..0000000 --- a/README.rst +++ /dev/null @@ -1,66 +0,0 @@ -=========== -Quick Error -=========== - -:Status: production-ready -:Documentation: https://docs.rs/quick-error/ - -A macro which makes error types pleasant to write. - -Features: - -* Define enum type with arbitrary parameters -* Concise notation of ``Display`` and ``Error`` traits -* Full control of ``Display`` and ``Error`` trait implementation -* Any number of ``From`` traits -* Support for all enum-variants ``Unit``, ``Tuple`` and ``Struct`` - -Here is the comprehensive example: - -.. code-block:: rust - - quick_error! { - #[derive(Debug)] - pub enum IoWrapper { - Io(err: io::Error) { - from() - display("I/O error: {}", err) - source(err) - } - Other(descr: &'static str) { - display("Error {}", descr) - } - IoAt { place: &'static str, err: io::Error } { - source(err) - display(me) -> ("io error at {}: {}", place, err) - from(s: String) -> { - place: "some string", - err: io::Error::new(io::ErrorKind::Other, s) - } - } - Discard { - from(&'static str) - } - } - } - -======= -License -======= - -Licensed under either of - - * Apache License, Version 2.0, (./LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) - * MIT license (./LICENSE-MIT or http://opensource.org/licenses/MIT) - -at your option. - ------------- -Contribution ------------- - -Unless you explicitly state otherwise, any contribution intentionally -submitted for inclusion in the work by you, as defined in the Apache-2.0 -license, shall be dual licensed as above, without any additional terms or -conditions. - diff --git a/SourceCodePro-LICENSE.txt b/SourceCodePro-LICENSE.txt new file mode 100644 index 0000000..0754257 --- /dev/null +++ b/SourceCodePro-LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/SourceCodePro-Regular.woff b/SourceCodePro-Regular.woff new file mode 100644 index 0000000..5576670 Binary files /dev/null and b/SourceCodePro-Regular.woff differ diff --git a/SourceCodePro-Semibold.woff b/SourceCodePro-Semibold.woff new file mode 100644 index 0000000..ca972a1 Binary files /dev/null and b/SourceCodePro-Semibold.woff differ diff --git a/SourceSerifPro-Bold.woff b/SourceSerifPro-Bold.woff new file mode 100644 index 0000000..ac1b1b3 Binary files /dev/null and b/SourceSerifPro-Bold.woff differ diff --git a/SourceSerifPro-LICENSE.txt b/SourceSerifPro-LICENSE.txt new file mode 100644 index 0000000..b77d653 --- /dev/null +++ b/SourceSerifPro-LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/SourceSerifPro-Regular.woff b/SourceSerifPro-Regular.woff new file mode 100644 index 0000000..e8c43b8 Binary files /dev/null and b/SourceSerifPro-Regular.woff differ diff --git a/bulk.yaml b/bulk.yaml deleted file mode 100644 index cdb9763..0000000 --- a/bulk.yaml +++ /dev/null @@ -1,8 +0,0 @@ -minimum-bulk: v0.4.5 - -versions: - -- file: Cargo.toml - block-start: ^\[package\] - block-end: ^\[.*\] - regex: ^version\s*=\s*"(\S+)" diff --git a/examples/context.rs b/examples/context.rs deleted file mode 100644 index 1d40661..0000000 --- a/examples/context.rs +++ /dev/null @@ -1,43 +0,0 @@ -use quick_error::{quick_error, ResultExt}; -use std::env; -use std::fs::File; -use std::io::{self, stderr, Read, Write}; -use std::num::ParseIntError; -use std::path::{Path, PathBuf}; - -quick_error! { - #[derive(Debug)] - pub enum Error { - NoFileName {} - Io(err: io::Error, path: PathBuf) { - display("could not read file {:?}: {}", path, err) - context(path: &'a Path, err: io::Error) - -> (err, path.to_path_buf()) - } - Parse(err: ParseIntError, path: PathBuf) { - display("could not parse file {:?}: {}", path, err) - context(path: &'a Path, err: ParseIntError) - -> (err, path.to_path_buf()) - } - } -} - -fn parse_file() -> Result { - let fname = env::args().skip(1).next().ok_or(Error::NoFileName)?; - let fname = Path::new(&fname); - let mut file = File::open(fname).context(fname)?; - let mut buf = String::new(); - file.read_to_string(&mut buf).context(fname)?; - Ok(buf.parse().context(fname)?) -} - -fn main() { - match parse_file() { - Ok(val) => { - println!("Read: {}", val); - } - Err(e) => { - writeln!(&mut stderr(), "Error: {}", e).ok(); - } - } -} diff --git a/implementors/core/fmt/trait.Debug.js b/implementors/core/fmt/trait.Debug.js new file mode 100644 index 0000000..ef0d867 --- /dev/null +++ b/implementors/core/fmt/trait.Debug.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["quick_error"] = ["impl<X: Debug, E: Debug> Debug for Context<X, E>",]; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/implementors/quick_error/trait.ResultExt.js b/implementors/quick_error/trait.ResultExt.js new file mode 100644 index 0000000..cdd16d6 --- /dev/null +++ b/implementors/quick_error/trait.ResultExt.js @@ -0,0 +1,10 @@ +(function() {var implementors = {}; +implementors["quick_error"] = []; + + if (window.register_implementors) { + window.register_implementors(implementors); + } else { + window.pending_implementors = implementors; + } + +})() diff --git a/index.html b/index.html new file mode 100644 index 0000000..78dc13d --- /dev/null +++ b/index.html @@ -0,0 +1 @@ + diff --git a/main.css b/main.css new file mode 100644 index 0000000..c031019 --- /dev/null +++ b/main.css @@ -0,0 +1,186 @@ +/** + * Copyright 2015 The Rust Project Developers. See the COPYRIGHT + * file at the top-level directory of this distribution and at + * http://rust-lang.org/COPYRIGHT. + * + * Licensed under the Apache License, Version 2.0 or the MIT license + * , at your + * option. This file may not be copied, modified, or distributed + * except according to those terms. + */ + +/* General structure and fonts */ + +body { + background-color: white; + color: black; +} + +h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { + color: black; +} +h1.fqn { + border-bottom-color: #D5D5D5; +} +h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod) { + border-bottom-color: #DDDDDD; +} +.in-band { + background-color: white; +} + +.docblock code, .docblock-short code { + background-color: #F5F5F5; +} +pre { + background-color: #F5F5F5; +} + +.sidebar { + background-color: #F1F1F1; +} + +.sidebar .current { + background-color: #fff; +} + +.source .sidebar { + background-color: #fff; +} + +.sidebar .location { + border-color: #000; + background-color: #fff; + color: #333; +} + +.block a:hover { + background: #F5F5F5; +} + +.line-numbers span { color: #c67e2d; } +.line-numbers .line-highlighted { + background-color: #f6fdb0 !important; +} + +:target { background: #FDFFD3; } +.content .highlighted { + color: #000 !important; + background-color: #ccc; +} +.content .highlighted a, .content .highlighted span { color: #000 !important; } +.content .highlighted.trait { background-color: #fece7e; } +.content .highlighted.mod { background-color: #afc6e4; } +.content .highlighted.enum { background-color: #b4d1b9; } +.content .highlighted.struct { background-color: #e7b1a0; } +.content .highlighted.fn { background-color: #c6afb3; } +.content .highlighted.method { background-color: #c6afb3; } +.content .highlighted.tymethod { background-color: #c6afb3; } +.content .highlighted.type { background-color: #c6afb3; } + +.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { + border-bottom-color: #DDD; +} + +.docblock table { + border-color: #ddd; +} + +.docblock table td { + border-top-color: #ddd; + border-bottom-color: #ddd; +} + +.docblock table th { + border-top-color: #ddd; + border-bottom-color: #ddd; +} + +.content span.primitive, .content a.primitive, .block a.current.primitive { color: #39a7bf; } +.content span.externcrate, +.content span.mod, .content a.mod, .block a.current.mod { color: #4d76ae; } +.content span.fn, .content a.fn, .block a.current.fn, +.content span.method, .content a.method, .block a.current.method, +.content span.tymethod, .content a.tymethod, .block a.current.tymethod, +.content .fnname { color: #8c6067; } + +pre.rust .comment { color: #8E908C; } +pre.rust .doccomment { color: #4D4D4C; } + +nav { + border-bottom-color: #e0e0e0; +} +nav.main .current { + border-top-color: #000; + border-bottom-color: #000; +} +nav.main .separator { + border: 1px solid #000; +} +a { + color: #000; +} + +.docblock a, .docblock-short a, .stability a { + color: #3873AD; +} + +a.test-arrow { + color: #f5f5f5; +} + +.content span.trait, .content a.trait, .block a.current.trait { color: #7c5af3; } + +.search-input { + color: #555; + box-shadow: 0 0 0 1px #e0e0e0, 0 0 0 2px transparent; + background-color: white; +} + +.stab.unstable { background: #FFF5D6; border-color: #FFC600; } +.stab.deprecated { background: #F3DFFF; border-color: #7F0087; } + +#help > div { + background: #e9e9e9; + border-color: #bfbfbf;; +} + +#help dt { + border-color: #bfbfbf; + background: #fff; +} + +.since { + color: grey; +} + +.line-numbers :target { background-color: transparent; } + +/* Code highlighting */ +pre.rust .kw { color: #8959A8; } +pre.rust .kw-2, pre.rust .prelude-ty { color: #4271AE; } +pre.rust .number, pre.rust .string { color: #718C00; } +pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, +pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; } +pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; } +pre.rust .lifetime { color: #B76514; } +pre.rust .question-mark { + color: #ff9011; +} + +a.test-arrow { + background-color: rgba(78, 139, 202, 0.2); +} + +a.test-arrow:hover{ + background-color: #4e8bca; +} + +.toggle-label { + color: #999; +} + +:target > code { + background: #FDFFD3; +} \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 0000000..788cd80 --- /dev/null +++ b/main.js @@ -0,0 +1,1303 @@ +/*! + * Copyright 2014 The Rust Project Developers. See the COPYRIGHT + * file at the top-level directory of this distribution and at + * http://rust-lang.org/COPYRIGHT. + * + * Licensed under the Apache License, Version 2.0 or the MIT license + * , at your + * option. This file may not be copied, modified, or distributed + * except according to those terms. + */ + +/*jslint browser: true, es5: true */ +/*globals $: true, rootPath: true */ + +(function() { + "use strict"; + + // This mapping table should match the discriminants of + // `rustdoc::html::item_type::ItemType` type in Rust. + var itemTypes = ["mod", + "externcrate", + "import", + "struct", + "enum", + "fn", + "type", + "static", + "trait", + "impl", + "tymethod", + "method", + "structfield", + "variant", + "macro", + "primitive", + "associatedtype", + "constant", + "associatedconstant", + "union"]; + + function hasClass(elem, className) { + if (elem && className && elem.className) { + var elemClass = elem.className; + var start = elemClass.indexOf(className); + if (start == -1) { + return false; + } else if (elemClass.length == className.length) { + return true; + } else { + if (start > 0 && elemClass[start - 1] != ' ') { + return false; + } + var end = start + className.length; + if (end < elemClass.length && elemClass[end] != ' ') { + return false; + } + return true; + } + } + return false; + } + + function addClass(elem, className) { + if (elem && className && !hasClass(elem, className)) { + if (elem.className && elem.className.length > 0) { + elem.className += ' ' + className; + } else { + elem.className = className; + } + } + } + + function removeClass(elem, className) { + if (elem && className && elem.className) { + elem.className = (" " + elem.className + " ").replace(" " + className + " ", " ") + .trim(); + } + } + + function onEach(arr, func) { + if (arr && arr.length > 0 && func) { + for (var i = 0; i < arr.length; i++) { + func(arr[i]); + } + } + } + + function isHidden(elem) { + return (elem.offsetParent === null) + } + + // used for special search precedence + var TY_PRIMITIVE = itemTypes.indexOf("primitive"); + + onEach(document.getElementsByClassName('js-only'), function(e) { + removeClass(e, 'js-only'); + }); + + function getQueryStringParams() { + var params = {}; + window.location.search.substring(1).split("&"). + map(function(s) { + var pair = s.split("="); + params[decodeURIComponent(pair[0])] = + typeof pair[1] === "undefined" ? + null : decodeURIComponent(pair[1]); + }); + return params; + } + + function browserSupportsHistoryApi() { + return document.location.protocol != "file:" && + window.history && typeof window.history.pushState === "function"; + } + + function highlightSourceLines(ev) { + var i, from, to, match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/); + if (match) { + from = parseInt(match[1], 10); + to = Math.min(50000, parseInt(match[2] || match[1], 10)); + from = Math.min(from, to); + var elem = document.getElementById(from); + if (!elem) { + return; + } + if (ev === null) { + var x = document.getElementById(from); + if (x) { + x.scrollIntoView(); + } + }; + onEach(document.getElementsByClassName('line-numbers'), function(e) { + onEach(e.getElementsByTagName('span'), function(i_e) { + removeClass(i_e, 'line-highlighted'); + }); + }) + for (i = from; i <= to; ++i) { + addClass(document.getElementById(i), 'line-highlighted'); + } + } + } + highlightSourceLines(null); + window.onhashchange = highlightSourceLines; + + // Gets the human-readable string for the virtual-key code of the + // given KeyboardEvent, ev. + // + // This function is meant as a polyfill for KeyboardEvent#key, + // since it is not supported in Trident. We also test for + // KeyboardEvent#keyCode because the handleShortcut handler is + // also registered for the keydown event, because Blink doesn't fire + // keypress on hitting the Escape key. + // + // So I guess you could say things are getting pretty interoperable. + function getVirtualKey(ev) { + if ("key" in ev && typeof ev.key != "undefined") + return ev.key; + + var c = ev.charCode || ev.keyCode; + if (c == 27) + return "Escape"; + return String.fromCharCode(c); + } + + function handleShortcut(ev) { + if (document.activeElement.tagName === "INPUT") + return; + + // Don't interfere with browser shortcuts + if (ev.ctrlKey || ev.altKey || ev.metaKey) + return; + + var help = document.getElementById("help"); + switch (getVirtualKey(ev)) { + case "Escape": + var search = document.getElementById("search"); + if (!hasClass(help, "hidden")) { + ev.preventDefault(); + addClass(help, "hidden"); + removeClass(document.body, "blur"); + } else if (!hasClass(search, "hidden")) { + ev.preventDefault(); + addClass(search, "hidden"); + removeClass(document.getElementById("main"), "hidden"); + } + break; + + case "s": + case "S": + ev.preventDefault(); + focusSearchBar(); + break; + + case "+": + ev.preventDefault(); + toggleAllDocs(); + break; + + case "?": + if (ev.shiftKey && hasClass(help, "hidden")) { + ev.preventDefault(); + removeClass(help, "hidden"); + addClass(document.body, "blur"); + } + break; + } + } + + document.onkeypress = handleShortcut; + document.onkeydown = handleShortcut; + document.onclick = function(ev) { + if (hasClass(ev.target, 'collapse-toggle')) { + collapseDocs(ev.target); + } else if (hasClass(ev.target.parentNode, 'collapse-toggle')) { + collapseDocs(ev.target.parentNode); + } else if (ev.target.tagName === 'SPAN' && hasClass(ev.target.parentNode, 'line-numbers')) { + var prev_id = 0; + + var set_fragment = function (name) { + if (browserSupportsHistoryApi()) { + history.replaceState(null, null, '#' + name); + window.hashchange(); + } else { + location.replace('#' + name); + } + }; + + var cur_id = parseInt(ev.target.id, 10); + + if (ev.shiftKey && prev_id) { + if (prev_id > cur_id) { + var tmp = prev_id; + prev_id = cur_id; + cur_id = tmp; + } + + set_fragment(prev_id + '-' + cur_id); + } else { + prev_id = cur_id; + + set_fragment(cur_id); + } + } else if (!hasClass(document.getElementById("help"), "hidden")) { + addClass(document.getElementById("help"), "hidden"); + removeClass(document.body, "blur"); + } + }; + + var x = document.getElementsByClassName('version-selector'); + if (x.length > 0) { + x[0].onchange = function() { + var i, match, + url = document.location.href, + stripped = '', + len = rootPath.match(/\.\.\//g).length + 1; + + for (i = 0; i < len; ++i) { + match = url.match(/\/[^\/]*$/); + if (i < len - 1) { + stripped = match[0] + stripped; + } + url = url.substring(0, url.length - match[0].length); + } + + url += '/' + document.getElementsByClassName('version-selector')[0].value + stripped; + + document.location.href = url; + }; + } + + /** + * A function to compute the Levenshtein distance between two strings + * Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported + * Full License can be found at http://creativecommons.org/licenses/by-sa/3.0/legalcode + * This code is an unmodified version of the code written by Marco de Wit + * and was found at http://stackoverflow.com/a/18514751/745719 + */ + var levenshtein = (function() { + var row2 = []; + return function(s1, s2) { + if (s1 === s2) { + return 0; + } + var s1_len = s1.length, s2_len = s2.length; + if (s1_len && s2_len) { + var i1 = 0, i2 = 0, a, b, c, c2, row = row2; + while (i1 < s1_len) { + row[i1] = ++i1; + } + while (i2 < s2_len) { + c2 = s2.charCodeAt(i2); + a = i2; + ++i2; + b = i2; + for (i1 = 0; i1 < s1_len; ++i1) { + c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0); + a = row[i1]; + b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c); + row[i1] = b; + } + } + return b; + } + return s1_len + s2_len; + }; + })(); + + function initSearch(rawSearchIndex) { + var currentResults, index, searchIndex; + var MAX_LEV_DISTANCE = 3; + var params = getQueryStringParams(); + + // Populate search bar with query string search term when provided, + // but only if the input bar is empty. This avoid the obnoxious issue + // where you start trying to do a search, and the index loads, and + // suddenly your search is gone! + if (document.getElementsByClassName("search-input")[0].value === "") { + document.getElementsByClassName("search-input")[0].value = params.search || ''; + } + + /** + * Executes the query and builds an index of results + * @param {[Object]} query [The user query] + * @param {[type]} max [The maximum results returned] + * @param {[type]} searchWords [The list of search words to query + * against] + * @return {[type]} [A search index of results] + */ + function execQuery(query, max, searchWords) { + var valLower = query.query.toLowerCase(), + val = valLower, + typeFilter = itemTypeFromName(query.type), + results = [], + split = valLower.split("::"); + + // remove empty keywords + for (var j = 0; j < split.length; ++j) { + split[j].toLowerCase(); + if (split[j] === "") { + split.splice(j, 1); + } + } + + function typePassesFilter(filter, type) { + // No filter + if (filter < 0) return true; + + // Exact match + if (filter === type) return true; + + // Match related items + var name = itemTypes[type]; + switch (itemTypes[filter]) { + case "constant": + return (name == "associatedconstant"); + case "fn": + return (name == "method" || name == "tymethod"); + case "type": + return (name == "primitive"); + } + + // No match + return false; + } + + // quoted values mean literal search + var nSearchWords = searchWords.length; + if ((val.charAt(0) === "\"" || val.charAt(0) === "'") && + val.charAt(val.length - 1) === val.charAt(0)) + { + val = val.substr(1, val.length - 2); + for (var i = 0; i < nSearchWords; ++i) { + if (searchWords[i] === val) { + // filter type: ... queries + if (typePassesFilter(typeFilter, searchIndex[i].ty)) { + results.push({id: i, index: -1}); + } + } + if (results.length === max) { + break; + } + } + // searching by type + } else if (val.search("->") > -1) { + var trimmer = function (s) { return s.trim(); }; + var parts = val.split("->").map(trimmer); + var input = parts[0]; + // sort inputs so that order does not matter + var inputs = input.split(",").map(trimmer).sort().toString(); + var output = parts[1]; + + for (var i = 0; i < nSearchWords; ++i) { + var type = searchIndex[i].type; + if (!type) { + continue; + } + + // sort index inputs so that order does not matter + var typeInputs = type.inputs.map(function (input) { + return input.name; + }).sort(); + + // allow searching for void (no output) functions as well + var typeOutput = type.output ? type.output.name : ""; + if ((inputs === "*" || inputs === typeInputs.toString()) && + (output === "*" || output == typeOutput)) { + results.push({id: i, index: -1, dontValidate: true}); + } + } + } else { + // gather matching search results up to a certain maximum + val = val.replace(/\_/g, ""); + for (var i = 0; i < split.length; ++i) { + for (var j = 0; j < nSearchWords; ++j) { + var lev_distance; + if (searchWords[j].indexOf(split[i]) > -1 || + searchWords[j].indexOf(val) > -1 || + searchWords[j].replace(/_/g, "").indexOf(val) > -1) + { + // filter type: ... queries + if (typePassesFilter(typeFilter, searchIndex[j].ty)) { + results.push({ + id: j, + index: searchWords[j].replace(/_/g, "").indexOf(val), + lev: 0, + }); + } + } else if ( + (lev_distance = levenshtein(searchWords[j], val)) <= + MAX_LEV_DISTANCE) { + if (typePassesFilter(typeFilter, searchIndex[j].ty)) { + results.push({ + id: j, + index: 0, + // we want lev results to go lower than others + lev: lev_distance, + }); + } + } + if (results.length === max) { + break; + } + } + } + } + + var nresults = results.length; + for (var i = 0; i < nresults; ++i) { + results[i].word = searchWords[results[i].id]; + results[i].item = searchIndex[results[i].id] || {}; + } + // if there are no results then return to default and fail + if (results.length === 0) { + return []; + } + + results.sort(function sortResults(aaa, bbb) { + var a, b; + + // Sort by non levenshtein results and then levenshtein results by the distance + // (less changes required to match means higher rankings) + a = (aaa.lev); + b = (bbb.lev); + if (a !== b) { return a - b; } + + // sort by crate (non-current crate goes later) + a = (aaa.item.crate !== window.currentCrate); + b = (bbb.item.crate !== window.currentCrate); + if (a !== b) { return a - b; } + + // sort by exact match (mismatch goes later) + a = (aaa.word !== valLower); + b = (bbb.word !== valLower); + if (a !== b) { return a - b; } + + // sort by item name length (longer goes later) + a = aaa.word.length; + b = bbb.word.length; + if (a !== b) { return a - b; } + + // sort by item name (lexicographically larger goes later) + a = aaa.word; + b = bbb.word; + if (a !== b) { return (a > b ? +1 : -1); } + + // sort by index of keyword in item name (no literal occurrence goes later) + a = (aaa.index < 0); + b = (bbb.index < 0); + if (a !== b) { return a - b; } + // (later literal occurrence, if any, goes later) + a = aaa.index; + b = bbb.index; + if (a !== b) { return a - b; } + + // special precedence for primitive pages + if ((aaa.item.ty === TY_PRIMITIVE) && (bbb.item.ty !== TY_PRIMITIVE)) { + return -1; + } + if ((bbb.item.ty === TY_PRIMITIVE) && (aaa.item.ty !== TY_PRIMITIVE)) { + return 1; + } + + // sort by description (no description goes later) + a = (aaa.item.desc === ''); + b = (bbb.item.desc === ''); + if (a !== b) { return a - b; } + + // sort by type (later occurrence in `itemTypes` goes later) + a = aaa.item.ty; + b = bbb.item.ty; + if (a !== b) { return a - b; } + + // sort by path (lexicographically larger goes later) + a = aaa.item.path; + b = bbb.item.path; + if (a !== b) { return (a > b ? +1 : -1); } + + // que sera, sera + return 0; + }); + + // remove duplicates, according to the data provided + for (var i = results.length - 1; i > 0; i -= 1) { + if (results[i].word === results[i - 1].word && + results[i].item.ty === results[i - 1].item.ty && + results[i].item.path === results[i - 1].item.path && + (results[i].item.parent || {}).name === (results[i - 1].item.parent || {}).name) + { + results[i].id = -1; + } + } + for (var i = 0; i < results.length; ++i) { + var result = results[i], + name = result.item.name.toLowerCase(), + path = result.item.path.toLowerCase(), + parent = result.item.parent; + + // this validation does not make sense when searching by types + if (result.dontValidate) { + continue; + } + + var valid = validateResult(name, path, split, parent); + if (!valid) { + result.id = -1; + } + } + return results; + } + + /** + * Validate performs the following boolean logic. For example: + * "File::open" will give IF A PARENT EXISTS => ("file" && "open") + * exists in (name || path || parent) OR => ("file" && "open") exists in + * (name || path ) + * + * This could be written functionally, but I wanted to minimise + * functions on stack. + * + * @param {[string]} name [The name of the result] + * @param {[string]} path [The path of the result] + * @param {[string]} keys [The keys to be used (["file", "open"])] + * @param {[object]} parent [The parent of the result] + * @return {[boolean]} [Whether the result is valid or not] + */ + function validateResult(name, path, keys, parent) { + for (var i = 0; i < keys.length; ++i) { + // each check is for validation so we negate the conditions and invalidate + if (!( + // check for an exact name match + name.toLowerCase().indexOf(keys[i]) > -1 || + // then an exact path match + path.toLowerCase().indexOf(keys[i]) > -1 || + // next if there is a parent, check for exact parent match + (parent !== undefined && + parent.name.toLowerCase().indexOf(keys[i]) > -1) || + // lastly check to see if the name was a levenshtein match + levenshtein(name.toLowerCase(), keys[i]) <= + MAX_LEV_DISTANCE)) { + return false; + } + } + return true; + } + + function getQuery() { + var matches, type, query, raw = + document.getElementsByClassName('search-input')[0].value; + query = raw; + + matches = query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i); + if (matches) { + type = matches[1].replace(/^const$/, 'constant'); + query = query.substring(matches[0].length); + } + + return { + raw: raw, + query: query, + type: type, + id: query + type + }; + } + + function initSearchNav() { + var hoverTimeout; + + var click_func = function(e) { + var el = e.target; + // to retrieve the real "owner" of the event. + while (el.tagName !== 'TR') { + el = el.parentNode; + } + var dst = e.target.getElementsByTagName('a'); + if (dst.length < 1) { + return; + } + dst = dst[0]; + if (window.location.pathname === dst.pathname) { + addClass(document.getElementById('search'), 'hidden'); + removeClass(document.getElementById('main'), 'hidden'); + document.location.href = dst.href; + } + }; + var mouseover_func = function(e) { + var el = e.target; + // to retrieve the real "owner" of the event. + while (el.tagName !== 'TR') { + el = el.parentNode; + } + clearTimeout(hoverTimeout); + hoverTimeout = setTimeout(function() { + onEach(document.getElementsByClassName('search-results'), function(e) { + onEach(e.getElementsByClassName('result'), function(i_e) { + removeClass(i_e, 'highlighted'); + }); + }); + addClass(el, 'highlighted'); + }, 20); + }; + onEach(document.getElementsByClassName('search-results'), function(e) { + onEach(e.getElementsByClassName('result'), function(i_e) { + i_e.onclick = click_func; + i_e.onmouseover = mouseover_func; + }); + }); + + var search_input = document.getElementsByClassName('search-input')[0]; + search_input.onkeydown = null; + search_input.onkeydown = function(e) { + var actives = []; + onEach(document.getElementsByClassName('search-results'), function(e) { + onEach(document.getElementsByClassName('highlighted'), function(e) { + actives.push(e); + }); + }); + + if (e.which === 38) { // up + if (!actives.length || !actives[0].previousElementSibling) { + return; + } + + addClass(actives[0].previousElementSibling, 'highlighted'); + removeClass(actives[0], 'highlighted'); + } else if (e.which === 40) { // down + if (!actives.length) { + var results = document.getElementsByClassName('search-results'); + if (results.length > 0) { + var res = results[0].getElementsByClassName('result'); + if (res.length > 0) { + addClass(res[0], 'highlighted'); + } + } + } else if (actives[0].nextElementSibling) { + addClass(actives[0].nextElementSibling, 'highlighted'); + removeClass(actives[0], 'highlighted'); + } + } else if (e.which === 13) { // return + if (actives.length) { + document.location.href = actives[0].getElementsByTagName('a')[0].href; + } + } else if (actives.length > 0) { + removeClass(actives[0], 'highlighted'); + } + }; + } + + function escape(content) { + var h1 = document.createElement('h1'); + h1.textContent = content; + return h1.innerHTML; + } + + function showResults(results) { + var output, shown, query = getQuery(); + + currentResults = query.id; + output = '

Results for ' + escape(query.query) + + (query.type ? ' (type: ' + escape(query.type) + ')' : '') + '

'; + output += ''; + + if (results.length > 0) { + shown = []; + + results.forEach(function(item) { + var name, type, href, displayPath; + + if (shown.indexOf(item) !== -1) { + return; + } + + shown.push(item); + name = item.name; + type = itemTypes[item.ty]; + + if (type === 'mod') { + displayPath = item.path + '::'; + href = rootPath + item.path.replace(/::/g, '/') + '/' + + name + '/index.html'; + } else if (type === "primitive") { + displayPath = ""; + href = rootPath + item.path.replace(/::/g, '/') + + '/' + type + '.' + name + '.html'; + } else if (type === "externcrate") { + displayPath = ""; + href = rootPath + name + '/index.html'; + } else if (item.parent !== undefined) { + var myparent = item.parent; + var anchor = '#' + type + '.' + name; + var parentType = itemTypes[myparent.ty]; + if (parentType === "primitive") { + displayPath = myparent.name + '::'; + } else { + displayPath = item.path + '::' + myparent.name + '::'; + } + href = rootPath + item.path.replace(/::/g, '/') + + '/' + parentType + + '.' + myparent.name + + '.html' + anchor; + } else { + displayPath = item.path + '::'; + href = rootPath + item.path.replace(/::/g, '/') + + '/' + type + '.' + name + '.html'; + } + + output += ''; + }); + } else { + output += 'No results :( Try on DuckDuckGo?'; + } + + output += "

"; + addClass(document.getElementById('main'), 'hidden'); + var search = document.getElementById('search'); + removeClass(search, 'hidden'); + search.innerHTML = output; + var tds = search.getElementsByTagName('td'); + var td_width = 0; + if (tds.length > 0) { + td_width = tds[0].offsetWidth; + } + var width = search.offsetWidth - 40 - td_width; + onEach(search.getElementsByClassName('desc'), function(e) { + e.style.width = width + 'px'; + }); + initSearchNav(); + } + + function search(e) { + var query, + filterdata = [], + obj, i, len, + results = [], + maxResults = 200, + resultIndex; + var params = getQueryStringParams(); + + query = getQuery(); + if (e) { + e.preventDefault(); + } + + if (!query.query || query.id === currentResults) { + return; + } + + // Update document title to maintain a meaningful browser history + document.title = "Results for " + query.query + " - Rust"; + + // Because searching is incremental by character, only the most + // recent search query is added to the browser history. + if (browserSupportsHistoryApi()) { + if (!history.state && !params.search) { + history.pushState(query, "", "?search=" + encodeURIComponent(query.raw)); + } else { + history.replaceState(query, "", "?search=" + encodeURIComponent(query.raw)); + } + } + + resultIndex = execQuery(query, 20000, index); + len = resultIndex.length; + for (i = 0; i < len; ++i) { + if (resultIndex[i].id > -1) { + obj = searchIndex[resultIndex[i].id]; + filterdata.push([obj.name, obj.ty, obj.path, obj.desc]); + results.push(obj); + } + if (results.length >= maxResults) { + break; + } + } + + showResults(results); + } + + function itemTypeFromName(typename) { + for (var i = 0; i < itemTypes.length; ++i) { + if (itemTypes[i] === typename) { return i; } + } + return -1; + } + + function buildIndex(rawSearchIndex) { + searchIndex = []; + var searchWords = []; + for (var crate in rawSearchIndex) { + if (!rawSearchIndex.hasOwnProperty(crate)) { continue; } + + searchWords.push(crate); + searchIndex.push({ + crate: crate, + ty: 1, // == ExternCrate + name: crate, + path: "", + desc: rawSearchIndex[crate].doc, + type: null, + }); + + // an array of [(Number) item type, + // (String) name, + // (String) full path or empty string for previous path, + // (String) description, + // (Number | null) the parent path index to `paths`] + // (Object | null) the type of the function (if any) + var items = rawSearchIndex[crate].items; + // an array of [(Number) item type, + // (String) name] + var paths = rawSearchIndex[crate].paths; + + // convert `paths` into an object form + var len = paths.length; + for (var i = 0; i < len; ++i) { + paths[i] = {ty: paths[i][0], name: paths[i][1]}; + } + + // convert `items` into an object form, and construct word indices. + // + // before any analysis is performed lets gather the search terms to + // search against apart from the rest of the data. This is a quick + // operation that is cached for the life of the page state so that + // all other search operations have access to this cached data for + // faster analysis operations + var len = items.length; + var lastPath = ""; + for (var i = 0; i < len; ++i) { + var rawRow = items[i]; + var row = {crate: crate, ty: rawRow[0], name: rawRow[1], + path: rawRow[2] || lastPath, desc: rawRow[3], + parent: paths[rawRow[4]], type: rawRow[5]}; + searchIndex.push(row); + if (typeof row.name === "string") { + var word = row.name.toLowerCase(); + searchWords.push(word); + } else { + searchWords.push(""); + } + lastPath = row.path; + } + } + return searchWords; + } + + function startSearch() { + var searchTimeout; + var callback = function() { + var search_input = document.getElementsByClassName('search-input'); + if (search_input.length < 1) { return; } + search_input = search_input[0]; + clearTimeout(searchTimeout); + if (search_input.value.length === 0) { + if (browserSupportsHistoryApi()) { + history.replaceState("", "std - Rust", "?search="); + } + var main = document.getElementById('main'); + if (hasClass(main, 'content')) { + removeClass(main, 'hidden'); + } + var search_c = document.getElementById('search'); + if (hasClass(search_c, 'content')) { + addClass(search_c, 'hidden'); + } + } else { + searchTimeout = setTimeout(search, 500); + } + }; + var search_input = document.getElementsByClassName("search-input")[0]; + search_input.onkeyup = callback; + search_input.oninput = callback; + document.getElementsByClassName("search-form")[0].onsubmit = function(e){ + e.preventDefault(); + clearTimeout(searchTimeout); + search(); + }; + search_input.onchange = function(e) { + // Do NOT e.preventDefault() here. It will prevent pasting. + clearTimeout(searchTimeout); + // zero-timeout necessary here because at the time of event handler execution the + // pasted content is not in the input field yet. Shouldn’t make any difference for + // change, though. + setTimeout(search, 0); + }; + search_input.onpaste = search_input.onchange; + + // Push and pop states are used to add search results to the browser + // history. + if (browserSupportsHistoryApi()) { + // Store the previous so we can revert back to it later. + var previousTitle = document.title; + + window.onpopstate = function(e) { + var params = getQueryStringParams(); + // When browsing back from search results the main page + // visibility must be reset. + if (!params.search) { + var main = document.getElementById('main'); + if (hasClass(main, 'content')) { + removeClass(main, 'hidden'); + } + var search_c = document.getElementById('search'); + if (hasClass(search_c, 'content')) { + addClass(search_c, 'hidden'); + } + } + // Revert to the previous title manually since the History + // API ignores the title parameter. + document.title = previousTitle; + // When browsing forward to search results the previous + // search will be repeated, so the currentResults are + // cleared to ensure the search is successful. + currentResults = null; + // Synchronize search bar with query string state and + // perform the search. This will empty the bar if there's + // nothing there, which lets you really go back to a + // previous state with nothing in the bar. + if (params.search) { + document.getElementsByClassName('search-input')[0].value = params.search; + } else { + document.getElementsByClassName('search-input')[0].value = ''; + } + // Some browsers fire 'onpopstate' for every page load + // (Chrome), while others fire the event only when actually + // popping a state (Firefox), which is why search() is + // called both here and at the end of the startSearch() + // function. + search(); + }; + } + search(); + } + + index = buildIndex(rawSearchIndex); + startSearch(); + + // Draw a convenient sidebar of known crates if we have a listing + if (rootPath === '../') { + var sidebar = document.getElementsByClassName('sidebar')[0]; + var div = document.createElement('div'); + div.className = 'block crate'; + div.innerHTML = '<h3>Crates</h3>'; + var ul = document.createElement('ul'); + div.appendChild(ul); + + var crates = []; + for (var crate in rawSearchIndex) { + if (!rawSearchIndex.hasOwnProperty(crate)) { continue; } + crates.push(crate); + } + crates.sort(); + for (var i = 0; i < crates.length; ++i) { + var klass = 'crate'; + if (crates[i] === window.currentCrate) { + klass += ' current'; + } + var link = document.createElement('a'); + link.href = '../' + crates[i] + '/index.html'; + link.title = rawSearchIndex[crates[i]].doc; + link.className = klass; + link.textContent = crates[i]; + + var li = document.createElement('li'); + li.appendChild(link); + ul.appendChild(li); + } + sidebar.appendChild(div); + } + } + + window.initSearch = initSearch; + + // delayed sidebar rendering. + function initSidebarItems(items) { + var sidebar = document.getElementsByClassName('sidebar')[0]; + var current = window.sidebarCurrent; + + function block(shortty, longty) { + var filtered = items[shortty]; + if (!filtered) { return; } + + var div = document.createElement('div'); + div.className = 'block ' + shortty; + var h3 = document.createElement('h3'); + h3.textContent = longty; + div.appendChild(h3); + var ul = document.createElement('ul'); + + for (var i = 0; i < filtered.length; ++i) { + var item = filtered[i]; + var name = item[0]; + var desc = item[1]; // can be null + + var klass = shortty; + if (name === current.name && shortty === current.ty) { + klass += ' current'; + } + var path; + if (shortty === 'mod') { + path = name + '/index.html'; + } else { + path = shortty + '.' + name + '.html'; + } + var link = document.createElement('a'); + link.href = current.relpath + path; + link.title = desc; + link.className = klass; + link.textContent = name; + var li = document.createElement('li'); + li.appendChild(link); + ul.appendChild(li); + } + div.appendChild(ul); + sidebar.appendChild(div); + } + + block("primitive", "Primitive Types"); + block("mod", "Modules"); + block("macro", "Macros"); + block("struct", "Structs"); + block("enum", "Enums"); + block("constant", "Constants"); + block("static", "Statics"); + block("trait", "Traits"); + block("fn", "Functions"); + block("type", "Type Definitions"); + } + + window.initSidebarItems = initSidebarItems; + + window.register_implementors = function(imp) { + var list = document.getElementById('implementors-list'); + var libs = Object.getOwnPropertyNames(imp); + for (var i = 0; i < libs.length; ++i) { + if (libs[i] === currentCrate) { continue; } + var structs = imp[libs[i]]; + for (var j = 0; j < structs.length; ++j) { + var code = document.createElement('code'); + code.innerHTML = structs[j]; + + var x = code.getElementsByTagName('a'); + for (var k = 0; k < x.length; k++) { + var href = x[k].getAttribute('href'); + if (href && href.indexOf('http') !== 0) { + x[k].setAttribute('href', rootPath + href); + } + } + var li = document.createElement('li'); + li.appendChild(code); + list.appendChild(li); + } + } + }; + if (window.pending_implementors) { + window.register_implementors(window.pending_implementors); + } + + function labelForToggleButton(sectionIsCollapsed) { + if (sectionIsCollapsed) { + // button will expand the section + return "+"; + } + // button will collapse the section + // note that this text is also set in the HTML template in render.rs + return "\u2212"; // "\u2212" is '−' minus sign + } + + function onEveryMatchingChild(elem, className, func) { + if (elem && className && func) { + for (var i = 0; i < elem.childNodes.length; i++) { + if (hasClass(elem.childNodes[i], className)) { + func(elem.childNodes[i]); + } else { + onEveryMatchingChild(elem.childNodes[i], className, func); + } + } + } + } + + function toggleAllDocs() { + var toggle = document.getElementById("toggle-all-docs"); + if (hasClass(toggle, "will-expand")) { + removeClass(toggle, "will-expand"); + onEveryMatchingChild(toggle, "inner", function(e) { + e.innerHTML = labelForToggleButton(false); + }); + toggle.title = "collapse all docs"; + onEach(document.getElementsByClassName("docblock"), function(e) { + e.style.display = 'block'; + }); + onEach(document.getElementsByClassName("toggle-label"), function(e) { + e.style.display = 'none'; + }); + onEach(document.getElementsByClassName("toggle-wrapper"), function(e) { + removeClass(e, "collapsed"); + }); + onEach(document.getElementsByClassName("collapse-toggle"), function(e) { + onEveryMatchingChild(e, "inner", function(i_e) { + i_e.innerHTML = labelForToggleButton(false); + }); + }); + } else { + addClass(toggle, "will-expand"); + onEveryMatchingChild(toggle, "inner", function(e) { + e.innerHTML = labelForToggleButton(true); + }); + toggle.title = "expand all docs"; + onEach(document.getElementsByClassName("docblock"), function(e) { + e.style.display = 'none'; + }); + onEach(document.getElementsByClassName("toggle-label"), function(e) { + e.style.display = 'inline-block'; + }); + onEach(document.getElementsByClassName("toggle-wrapper"), function(e) { + addClass(e, "collapsed"); + }); + onEach(document.getElementsByClassName("collapse-toggle"), function(e) { + onEveryMatchingChild(e, "inner", function(i_e) { + i_e.innerHTML = labelForToggleButton(true); + }); + }); + } + } + + function collapseDocs(toggle) { + if (!toggle || !toggle.parentNode) { + return; + } + var relatedDoc = toggle.parentNode.nextElementSibling; + if (hasClass(relatedDoc, "stability")) { + relatedDoc = relatedDoc.nextElementSibling; + } + if (hasClass(relatedDoc, "docblock")) { + if (!isHidden(relatedDoc)) { + relatedDoc.style.display = 'none'; + onEach(toggle.childNodes, function(e) { + if (hasClass(e, 'toggle-label')) { + e.style.display = 'inline-block'; + } + if (hasClass(e, 'inner')) { + e.innerHTML = labelForToggleButton(true); + } + }); + addClass(toggle.parentNode, 'collapsed'); + } else { + relatedDoc.style.display = 'block'; + removeClass(toggle.parentNode, 'collapsed'); + onEach(toggle.childNodes, function(e) { + if (hasClass(e, 'toggle-label')) { + e.style.display = 'none'; + } + if (hasClass(e, 'inner')) { + e.innerHTML = labelForToggleButton(false); + } + }); + } + } + } + + var x = document.getElementById('toggle-all-docs'); + if (x) { + x.onclick = toggleAllDocs; + } + + function insertAfter(newNode, referenceNode) { + referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); + } + + var toggle = document.createElement('a'); + toggle.href = 'javascript:void(0)'; + toggle.className = 'collapse-toggle'; + toggle.innerHTML = "[<span class='inner'>"+labelForToggleButton(false)+"</span>]"; + + var func = function(e) { + var next = e.nextElementSibling; + if (!next) { + return; + } + if (hasClass(next, 'docblock') || + (hasClass(next, 'stability') && + hasClass(next.nextElementSibling, 'docblock'))) { + insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]); + } + } + onEach(document.getElementsByClassName('method'), func); + onEach(document.getElementsByClassName('impl-items'), function(e) { + onEach(e.getElementsByClassName('associatedconstant'), func); + }); + + function createToggle() { + var span = document.createElement('span'); + span.className = 'toggle-label'; + span.style.display = 'none'; + span.innerHTML = ' Expand description'; + + var mainToggle = toggle.cloneNode(true); + mainToggle.appendChild(span); + + var wrapper = document.createElement('div'); + wrapper.className = 'toggle-wrapper'; + wrapper.appendChild(mainToggle); + return wrapper; + } + + onEach(document.getElementById('main').getElementsByClassName('docblock'), function(e) { + if (e.parentNode.id === "main") { + e.parentNode.insertBefore(createToggle(), e); + } + }); + + onEach(document.getElementsByClassName('docblock'), function(e) { + if (hasClass(e, 'autohide')) { + var wrap = e.previousElementSibling; + if (wrap && hasClass(wrap, 'toggle-wrapper')) { + var toggle = wrap.childNodes[0]; + if (e.childNodes[0].tagName === 'H3') { + onEach(toggle.getElementsByClassName('toggle-label'), function(i_e) { + i_e.innerHTML = " Show " + e.childNodes[0].innerHTML; + }); + } + e.style.display = 'none'; + addClass(wrap, 'collapsed'); + onEach(toggle.getElementsByClassName('inner'), function(e) { + e.innerHTML = labelForToggleButton(true); + }); + onEach(toggle.getElementsByClassName('toggle-label'), function(e) { + e.style.display = 'block'; + }); + } + } + }) + + function createToggleWrapper() { + var span = document.createElement('span'); + span.className = 'toggle-label'; + span.style.display = 'none'; + span.innerHTML = ' Expand attributes'; + toggle.appendChild(span); + + var wrapper = document.createElement('div'); + wrapper.className = 'toggle-wrapper toggle-attributes'; + wrapper.appendChild(toggle); + return wrapper; + } + + onEach(document.getElementById('main').getElementsByTagName('pre'), function(e) { + onEach(e.getElementsByClassName('attributes'), function(i_e) { + i_e.parentNode.insertBefore(createToggleWrapper(), i_e); + collapseDocs(i_e.previousSibling.childNodes[0]); + }); + }); +}()); + +// Sets the focus on the search bar at the top of the page +function focusSearchBar() { + document.getElementsByClassName('search-input')[0].focus(); +} diff --git a/normalize.css b/normalize.css new file mode 100644 index 0000000..2804c26 --- /dev/null +++ b/normalize.css @@ -0,0 +1 @@ +/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} diff --git a/quick_error/Context.t.html b/quick_error/Context.t.html new file mode 100644 index 0000000..78c8c05 --- /dev/null +++ b/quick_error/Context.t.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta http-equiv="refresh" content="0;URL=struct.Context.html"> +</head> +<body> + <p>Redirecting to <a href="struct.Context.html">struct.Context.html</a>...</p> + <script>location.replace("struct.Context.html" + location.search + location.hash);</script> +</body> +</html> \ No newline at end of file diff --git a/quick_error/ResultExt.t.html b/quick_error/ResultExt.t.html new file mode 100644 index 0000000..f4c1577 --- /dev/null +++ b/quick_error/ResultExt.t.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta http-equiv="refresh" content="0;URL=trait.ResultExt.html"> +</head> +<body> + <p>Redirecting to <a href="trait.ResultExt.html">trait.ResultExt.html</a>...</p> + <script>location.replace("trait.ResultExt.html" + location.search + location.hash);</script> +</body> +</html> \ No newline at end of file diff --git a/quick_error/index.html b/quick_error/index.html new file mode 100644 index 0000000..886ea1a --- /dev/null +++ b/quick_error/index.html @@ -0,0 +1,389 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="generator" content="rustdoc"> + <meta name="description" content="API documentation for the Rust `quick_error` crate."> + <meta name="keywords" content="rust, rustlang, rust-lang, quick_error"> + + <title>quick_error - Rust + + + + + + + + + + + + + + + + + + +
+

Crate quick_error + + [] + + [src]

+

A macro which makes errors easy to write

+ +

Minimum type is like this:

+ +
+#[macro_use] extern crate quick_error;
+
+quick_error! {
+    #[derive(Debug)]
+    pub enum SomeError {
+        Variant1 {}
+    }
+}
+ +

Both pub and non-public types may be declared, and all meta attributes +(such as #[derive(Debug)]) are forwarded as is. The Debug must be +implemented (but you may do that yourself if you like). The documentation +comments /// something (as well as other meta attrbiutes) on variants +are allowed.

+ +

Allowed Syntax

+

You may add arbitrary parameters to any struct variant:

+ +
+quick_error! {
+    #[derive(Debug)]
+    pub enum SomeError {
+        /// IO Error
+        Io(err: std::io::Error) {}
+        /// Utf8 Error
+        Utf8(err: std::str::Utf8Error) {}
+    }
+}
+ +

Note unlike in normal Enum declarations you declare names of fields (which +are omitted from type). How they can be used is outlined below.

+ +

Now you might have noticed trailing braces {}. They are used to define +implementations. By default:

+ +
    +
  • Error::description() returns variant name as static string
  • +
  • Error::cause() returns None (even if type wraps some value)
  • +
  • Display outputs description()
  • +
  • No From implementations are defined
  • +
+ +

To define description simply add description(value) inside braces:

+ +
+quick_error! {
+    #[derive(Debug)]
+    pub enum SomeError {
+        Io(err: std::io::Error) {
+            description(err.description())
+        }
+        Utf8(err: std::str::Utf8Error) {
+            description("utf8 error")
+        }
+    }
+}
+ +

Normal rules for borrowing apply. So most of the time description either +returns constant string or forwards description from enclosed type.

+ +

To change cause method to return some error, add cause(value), for +example:

+ +
+quick_error! {
+    #[derive(Debug)]
+    pub enum SomeError {
+        Io(err: std::io::Error) {
+            cause(err)
+            description(err.description())
+        }
+        Utf8(err: std::str::Utf8Error) {
+            description("utf8 error")
+        }
+        Other(err: Box<std::error::Error>) {
+            cause(&**err)
+            description(err.description())
+        }
+    }
+}
+ +

Note you don't need to wrap value in Some, its implicit. In case you want +None returned just omit the cause. You can't return None +conditionally.

+ +

To change how each clause is Displayed add display(pattern,..args), +for example:

+ +
+quick_error! {
+    #[derive(Debug)]
+    pub enum SomeError {
+        Io(err: std::io::Error) {
+            display("I/O error: {}", err)
+        }
+        Utf8(err: std::str::Utf8Error) {
+            display("Utf8 error, valid up to {}", err.valid_up_to())
+        }
+    }
+}
+ +

If you need a reference to the error when Displaying, you can instead use +display(x) -> (pattern, ..args), where x sets the name of the reference.

+ +
+use std::error::Error; // put methods like `description()` of this trait into scope
+
+quick_error! {
+    #[derive(Debug)]
+    pub enum SomeError {
+        Io(err: std::io::Error) {
+            display(x) -> ("{}: {}", x.description(), err)
+        }
+        Utf8(err: std::str::Utf8Error) {
+            display(self_) -> ("{}, valid up to {}", self_.description(), err.valid_up_to())
+        }
+    }
+}
+ +

To convert to the type from any other, use one of the three forms of +from clause.

+ +

For example, to convert simple wrapper use bare from():

+ +
+quick_error! {
+    #[derive(Debug)]
+    pub enum SomeError {
+        Io(err: std::io::Error) {
+            from()
+        }
+    }
+}
+ +

This implements From<io::Error>.

+ +

To convert to singleton enumeration type (discarding the value), use +the from(type) form:

+ +
+quick_error! {
+    #[derive(Debug)]
+    pub enum SomeError {
+        FormatError {
+            from(std::fmt::Error)
+        }
+    }
+}
+ +

And the most powerful form is from(var: type) -> (arguments...). It +might be used to convert to type with multiple arguments or for arbitrary +value conversions:

+ +
+quick_error! {
+    #[derive(Debug)]
+    pub enum SomeError {
+        FailedOperation(s: &'static str, errno: i32) {
+            from(errno: i32) -> ("os error", errno)
+            from(e: std::io::Error) -> ("io error", e.raw_os_error().unwrap())
+        }
+        /// Converts from both kinds of utf8 errors
+        Utf8(err: std::str::Utf8Error) {
+            from()
+            from(err: std::string::FromUtf8Error) -> (err.utf8_error())
+        }
+    }
+}
+ +

Context

+

Since quick-error 1.1 we also have a context declaration, which is +similar to (the longest form of) from, but allows adding some context to +the error. We need a longer example to demonstrate this:

+ +
+use quick_error::ResultExt;
+
+quick_error! {
+    #[derive(Debug)]
+    pub enum Error {
+        File(filename: PathBuf, err: io::Error) {
+            context(path: &'a Path, err: io::Error)
+                -> (path.to_path_buf(), err)
+        }
+    }
+}
+
+fn openfile(path: &Path) -> Result<(), Error> {
+    try!(File::open(path).context(path));
+
+    // If we didn't have context, the line above would be written as;
+    //
+    // try!(File::open(path)
+    //     .map_err(|err| Error::File(path.to_path_buf(), err)));
+
+    Ok(())
+}
+
+ +

Each context(a: A, b: B) clause implements +From<Context<A, B>> for Error. Which means multiple context clauses +are a subject to the normal coherence rules. Unfortunately, we can't +provide full support of generics for the context, but you may either use a +lifetime 'a for references or AsRef<Type> (the latter means A: AsRef<Type>, and Type must be concrete). It's also occasionally useful +to use a tuple as a type of the first argument.

+ +

You also need to use quick_error::ResultExt extension trait to get +working .context() method.

+ +

More info on context in this article.

+ +

All forms of from, display, description, cause, and context +clauses can be combined and put in arbitrary order. Only from and +context can be used multiple times in single variant of enumeration. +Docstrings are also okay. Empty braces can be omitted as of quick_error +0.1.3.

+ +

Private Enums

+

Since quick-error 1.2.0 we have a way to make a private enum that is +wrapped by public structure:

+ +
+#[macro_use] extern crate quick_error;
+
+quick_error! {
+    #[derive(Debug)]
+    pub enum PubError wraps ErrorEnum {
+        Variant1 {}
+    }
+}
+ +

This generates data structures like this

+ +
+pub struct PubError(ErrorEnum);
+
+enum ErrorEnum {
+    Variant1,
+}
+
+ +

Which in turn allows you to export just PubError in your crate and keep +actual enumeration private to the crate. This is useful to keep backwards +compatibility for error types. Currently there is no shorcuts to define +error constructors for the inner type, but we consider adding some in +future versions.

+ +

It's possible to declare internal enum as public too.

+

Macros

+
' + + '' + + displayPath + '' + + name + '' + + '' + + '' + escape(item.desc) + + ' 
+ + + +
quick_error +

Main macro that does all the work

+

Structs

+ + + + +
Context +

Generic context type

+

Traits

+ + + + +
ResultExt +

Result extension trait adding a context method

+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/quick_error/macro.quick_error!.html b/quick_error/macro.quick_error!.html new file mode 100644 index 0000000..3a6ca2f --- /dev/null +++ b/quick_error/macro.quick_error!.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.quick_error.html...

+ + + \ No newline at end of file diff --git a/quick_error/macro.quick_error.html b/quick_error/macro.quick_error.html new file mode 100644 index 0000000..fdcf24d --- /dev/null +++ b/quick_error/macro.quick_error.html @@ -0,0 +1,374 @@ + + + + + + + + + + quick_error::quick_error - Rust + + + + + + + + + + + + + + + + + + +
+

Macro quick_error::quick_error + + [] + + [src]

+
+macro_rules! quick_error {
+    (   $(#[$meta:meta])*
+        pub enum $name:ident { $($chunks:tt)* }
+    ) => { ... };
+    (   $(#[$meta:meta])*
+        enum $name:ident { $($chunks:tt)* }
+    ) => { ... };
+    (   $(#[$meta:meta])*
+        pub enum $name:ident wraps $enum_name:ident { $($chunks:tt)* }
+    ) => { ... };
+    (   $(#[$meta:meta])*
+        pub enum $name:ident wraps pub $enum_name:ident { $($chunks:tt)* }
+    ) => { ... };
+    (   $(#[$meta:meta])*
+        enum $name:ident wraps $enum_name:ident { $($chunks:tt)* }
+    ) => { ... };
+    (   $(#[$meta:meta])*
+        enum $name:ident wraps pub $enum_name:ident { $($chunks:tt)* }
+    ) => { ... };
+    (
+        WRAPPER $internal:ident [ $($strdef:tt)* ] $strname:ident
+        $(#[$meta:meta])*
+    ) => { ... };
+    (SORT [enum $name:ident $( #[$meta:meta] )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [ ]
+        queue [ ]
+    ) => { ... };
+    (SORT [pub enum $name:ident $( #[$meta:meta] )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [ ]
+        queue [ ]
+    ) => { ... };
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )*]
+        queue [ #[$qmeta:meta] $( $tail:tt )*]
+    ) => { ... };
+    (SORT [$( $def:tt )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [$( #[$bmeta:meta] )*]
+        queue [ $qitem:ident $( $tail:tt )*]
+    ) => { ... };
+    (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 )*]
+    ) => { ... };
+    (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 )*]
+    ) => { ... };
+    (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 )*]
+    ) => { ... };
+    (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 )*]
+    ) => { ... };
+    (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 )*]
+    ) => { ... };
+    (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 )*]
+    ) => { ... };
+    (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 [ ]
+    ) => { ... };
+    (ENUM_DEFINITION [pub enum $name:ident $( #[$meta:meta] )*]
+        body [$($( #[$imeta:meta] )*
+            => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+        queue [ ]
+    ) => { ... };
+    (ENUM_DEFINITION [enum $name:ident $( #[$meta:meta] )*]
+        body [$($( #[$imeta:meta] )*
+            => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+        queue [ ]
+    ) => { ... };
+    (ENUM_DEFINITION [$( $def:tt )*]
+        body [$($( #[$imeta:meta] )*
+            => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+        queue [$( #[$qmeta:meta] )*
+            => $qitem:ident: UNIT [ ] $( $queue:tt )*]
+    ) => { ... };
+    (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 )*]
+    ) => { ... };
+    (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 )*]
+    ) => { ... };
+    (IMPLEMENTATIONS
+        $name:ident {$(
+            $item:ident: $imode:tt [$(#[$imeta:meta])*] [$( $var:ident: $typ:ty ),*] {$( $funcs:tt )*}
+        )*}
+    ) => { ... };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*}
+    ) => { ... };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { display($pattern:expr) $( $tail:tt )*}
+    ) => { ... };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { display($pattern:expr, $( $exprs:tt )*) $( $tail:tt )*}
+    ) => { ... };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { $t:tt $( $tail:tt )*}
+    ) => { ... };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { }
+    ) => { ... };
+    (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+        [$( $var:ident ),*]
+        { description($expr:expr) $( $tail:tt )*}
+    ) => { ... };
+    (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+        [$( $var:ident ),*]
+        { $t:tt $( $tail:tt )*}
+    ) => { ... };
+    (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+        [$( $var:ident ),*]
+        { }
+    ) => { ... };
+    (FIND_CAUSE_IMPL $item:ident: $imode:tt
+        [$( $var:ident ),*]
+        { cause($expr:expr) $( $tail:tt )*}
+    ) => { ... };
+    (FIND_CAUSE_IMPL $item:ident: $imode:tt
+        [$( $var:ident ),*]
+        { $t:tt $( $tail:tt )*}
+    ) => { ... };
+    (FIND_CAUSE_IMPL $item:ident: $imode:tt
+        [$( $var:ident ),*]
+        { }
+    ) => { ... };
+    (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { from() $( $tail:tt )*}
+    ) => { ... };
+    (FIND_FROM_IMPL $name:ident $item:ident: UNIT
+        [ ]
+        { from($ftyp:ty) $( $tail:tt )*}
+    ) => { ... };
+    (FIND_FROM_IMPL $name:ident $item:ident: TUPLE
+        [$( $var:ident: $typ:ty ),*]
+        { from($fvar:ident: $ftyp:ty) -> ($( $texpr:expr ),*) $( $tail:tt )*}
+    ) => { ... };
+    (FIND_FROM_IMPL $name:ident $item:ident: STRUCT
+        [$( $var:ident: $typ:ty ),*]
+        { from($fvar:ident: $ftyp:ty) -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )*}
+    ) => { ... };
+    (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { $t:tt $( $tail:tt )*}
+    ) => { ... };
+    (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { }
+    ) => { ... };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: TUPLE
+        [$( $var:ident: $typ:ty ),*]
+        { context($cvar:ident: AsRef<$ctyp:ty>, $fvar:ident: $ftyp:ty)
+            -> ($( $texpr:expr ),*) $( $tail:tt )* }
+    ) => { ... };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: TUPLE
+        [$( $var:ident: $typ:ty ),*]
+        { context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
+            -> ($( $texpr:expr ),*) $( $tail:tt )* }
+    ) => { ... };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: STRUCT
+        [$( $var:ident: $typ:ty ),*]
+        { context($cvar:ident: AsRef<$ctyp:ty>, $fvar:ident: $ftyp:ty)
+            -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )* }
+    ) => { ... };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: STRUCT
+        [$( $var:ident: $typ:ty ),*]
+        { context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
+            -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )* }
+    ) => { ... };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { $t:tt $( $tail:tt )*}
+    ) => { ... };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { }
+    ) => { ... };
+    (ITEM_BODY $(#[$imeta:meta])* $item:ident: UNIT
+    ) => { ... };
+    (ITEM_BODY $(#[$imeta:meta])* $item:ident: TUPLE
+        [$( $typ:ty ),*]
+    ) => { ... };
+    (ITEM_BODY $(#[$imeta:meta])* $item:ident: STRUCT
+        [$( $var:ident: $typ:ty ),*]
+    ) => { ... };
+    (ITEM_PATTERN $name:ident $item:ident: UNIT []
+    ) => { ... };
+    (ITEM_PATTERN $name:ident $item:ident: TUPLE
+        [$( ref $var:ident ),*]
+    ) => { ... };
+    (ITEM_PATTERN $name:ident $item:ident: STRUCT
+        [$( ref $var:ident ),*]
+    ) => { ... };
+    (ERROR_CHECK $imode:tt display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*) => { ... };
+    (ERROR_CHECK $imode:tt display($pattern: expr) $( $tail:tt )*) => { ... };
+    (ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*) => { ... };
+    (ERROR_CHECK $imode:tt description($expr:expr) $( $tail:tt )*) => { ... };
+    (ERROR_CHECK $imode:tt cause($expr:expr) $($tail:tt)*) => { ... };
+    (ERROR_CHECK $imode:tt from() $($tail:tt)*) => { ... };
+    (ERROR_CHECK $imode:tt from($ftyp:ty) $($tail:tt)*) => { ... };
+    (ERROR_CHECK TUPLE from($fvar:ident: $ftyp:ty) -> ($( $e:expr ),*) $( $tail:tt )*) => { ... };
+    (ERROR_CHECK STRUCT from($fvar:ident: $ftyp:ty) -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*) => { ... };
+    (ERROR_CHECK TUPLE context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
+        -> ($( $e:expr ),*) $( $tail:tt )*) => { ... };
+    (ERROR_CHECK STRUCT context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
+        -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*) => { ... };
+    (ERROR_CHECK $imode:tt ) => { ... };
+    (IDENT $ident:ident) => { ... };
+}
+

Main macro that does all the work

+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/quick_error/quick_error.m.html b/quick_error/quick_error.m.html new file mode 100644 index 0000000..3a6ca2f --- /dev/null +++ b/quick_error/quick_error.m.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to macro.quick_error.html...

+ + + \ No newline at end of file diff --git a/quick_error/sidebar-items.js b/quick_error/sidebar-items.js new file mode 100644 index 0000000..6b8a460 --- /dev/null +++ b/quick_error/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"macro":[["quick_error","Main macro that does all the work"]],"struct":[["Context","Generic context type"]],"trait":[["ResultExt","Result extension trait adding a `context` method"]]}); \ No newline at end of file diff --git a/quick_error/struct.Context.html b/quick_error/struct.Context.html new file mode 100644 index 0000000..749afc0 --- /dev/null +++ b/quick_error/struct.Context.html @@ -0,0 +1,118 @@ + + + + + + + + + + quick_error::Context - Rust + + + + + + + + + + + + + + + + + + +
+

Struct quick_error::Context + + [] + + [src]

+
pub struct Context<X, E>(pub X, pub E);

Generic context type

+ +

Used mostly as a transport for ResultExt::context method

+

Trait Implementations

impl<X: Debug, E: Debug> Debug for Context<X, E>
[src]

+

+

Formats the value using the given formatter.

+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/quick_error/trait.ResultExt.html b/quick_error/trait.ResultExt.html new file mode 100644 index 0000000..9adc176 --- /dev/null +++ b/quick_error/trait.ResultExt.html @@ -0,0 +1,130 @@ + + + + + + + + + + quick_error::ResultExt - Rust + + + + + + + + + + + + + + + + + + +
+

Trait quick_error::ResultExt + + [] + + [src]

+
pub trait ResultExt<T, E> {
+    fn context<X>(self, x: X) -> Result<T, Context<X, E>>;
+}

Result extension trait adding a context method

+
+

Required Methods

+
+

The method is use to add context information to current operation

+ +

The context data is then used in error constructor to store additional +information within error. For example, you may add a filename as a +context for file operation. See crate documentation for the actual +example.

+
+

Implementors

+
    +
  • impl<T, E> ResultExt<T, E> for Result<T, E>
  • +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/rustdoc.css b/rustdoc.css new file mode 100644 index 0000000..567c8fb --- /dev/null +++ b/rustdoc.css @@ -0,0 +1,780 @@ +/** + * Copyright 2013 The Rust Project Developers. See the COPYRIGHT + * file at the top-level directory of this distribution and at + * http://rust-lang.org/COPYRIGHT. + * + * Licensed under the Apache License, Version 2.0 or the MIT license + * , at your + * option. This file may not be copied, modified, or distributed + * except according to those terms. + */ + +/* See FiraSans-LICENSE.txt for the Fira Sans license. */ +@font-face { + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 400; + src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff'); +} +@font-face { + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 500; + src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff'); +} + +/* See SourceSerifPro-LICENSE.txt for the Source Serif Pro license and + * Heuristica-LICENSE.txt for the Heuristica license. */ +@font-face { + font-family: 'Source Serif Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff'); +} +@font-face { + font-family: 'Source Serif Pro'; + font-style: italic; + font-weight: 400; + src: url("Heuristica-Italic.woff") format('woff'); +} +@font-face { + font-family: 'Source Serif Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff'); +} + +/* See SourceCodePro-LICENSE.txt for the Source Code Pro license. */ +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 400; + /* Avoid using locally installed font because bad versions are in circulation: + * see https://github.com/rust-lang/rust/issues/24355 */ + src: url("SourceCodePro-Regular.woff") format('woff'); +} +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 600; + src: url("SourceCodePro-Semibold.woff") format('woff'); +} + +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +/* General structure and fonts */ + +body { + font: 16px/1.4 "Source Serif Pro", Georgia, Times, "Times New Roman", serif; + margin: 0; + position: relative; + padding: 10px 15px 20px 15px; + + -webkit-font-feature-settings: "kern", "liga"; + -moz-font-feature-settings: "kern", "liga"; + font-feature-settings: "kern", "liga"; +} + +h1 { + font-size: 1.5em; +} +h2 { + font-size: 1.4em; +} +h3 { + font-size: 1.3em; +} +h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) { + font-weight: 500; + margin: 20px 0 15px 0; + padding-bottom: 6px; +} +h1.fqn { + border-bottom: 1px dashed; + margin-top: 0; + position: relative; +} +h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) { + border-bottom: 1px solid; +} +h3.impl, h3.method, h4.method, h3.type, h4.type, h4.associatedconstant { + font-weight: 600; + margin-top: 10px; + margin-bottom: 10px; + position: relative; +} +h3.impl, h3.method, h3.type { + margin-top: 15px; +} +h1, h2, h3, h4, .sidebar, a.source, .search-input, .content table :not(code)>a, .collapse-toggle { + font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +ol, ul { + padding-left: 25px; +} +ul ul, ol ul, ul ol, ol ol { + margin-bottom: 0; +} + +p { + margin: 0 0 .6em 0; +} + +code, pre { + font-family: "Source Code Pro", Menlo, Monaco, Consolas, "DejaVu Sans Mono", Inconsolata, monospace; + white-space: pre-wrap; +} +.docblock code, .docblock-short code { + border-radius: 3px; + padding: 0 0.2em; +} +.docblock pre code, .docblock-short pre code { + padding: 0; +} +pre { + padding: 14px; +} + +.source .content pre { + padding: 20px; +} + +img { + max-width: 100%; +} + +.source .content { + margin-top: 50px; + max-width: none; + overflow: visible; + margin-left: 0px; + min-width: 70em; +} + +nav.sub { + font-size: 16px; + text-transform: uppercase; +} + +.sidebar { + width: 200px; + position: absolute; + left: 0; + top: 0; + min-height: 100%; +} + +.sidebar .current { + margin-right: -20px; +} + +.content, nav { max-width: 960px; } + +/* Everything else */ + +.js-only, .hidden { display: none !important; } + +.sidebar { + padding: 10px; +} +.sidebar img { + margin: 20px auto; + display: block; +} + +.sidebar .location { + border: 1px solid; + font-size: 17px; + margin: 30px 0 20px 0; + text-align: center; + word-wrap: break-word; +} + +.location:empty { + border: none; +} + +.location a:first-child { font-weight: 500; } + +.block { + padding: 0 10px; + margin-bottom: 14px; +} +.block h2, .block h3 { + margin-top: 0; + margin-bottom: 8px; + text-align: center; +} +.block ul, .block li { + margin: 0; + padding: 0; + list-style: none; +} + +.block a { + display: block; + text-overflow: ellipsis; + overflow: hidden; + line-height: 15px; + padding: 7px 5px; + font-size: 14px; + font-weight: 300; + transition: border 500ms ease-out; +} + +.content { + padding: 15px 0; +} + +.source .content pre.rust { + white-space: pre; + overflow: auto; + padding-left: 0; +} +#search { + margin-left: 230px; +} +.content pre.line-numbers { + float: left; + border: none; + position: relative; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.line-numbers span { cursor: pointer; } + +.docblock-short p { + display: inline; +} + +.docblock-short.nowrap { + display: block; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.docblock-short p { + overflow: hidden; + text-overflow: ellipsis; + margin: 0; +} +.docblock-short code { white-space: nowrap; } + +.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 { + border-bottom: 1px solid; +} + +.docblock h1 { font-size: 1.3em; } +.docblock h2 { font-size: 1.15em; } +.docblock h3, .docblock h4, .docblock h5 { font-size: 1em; } + +.docblock { + margin-left: 24px; +} + +.content .out-of-band { + font-size: 23px; + margin: 0px; + padding: 0px; + text-align: right; + display: inline-block; + font-weight: normal; + position: absolute; + right: 0; +} + +h3.impl > .out-of-band { + font-size: 21px; +} + +h4 > code, h3 > code, .invisible > code { + position: inherit; +} + +.in-band, code { + z-index: 5; +} + +.invisible { + background: rgba(0, 0, 0, 0); + width: 100%; + display: inline-block; +} + +.content .in-band { + margin: 0px; + padding: 0px; + display: inline-block; +} + +#main { position: relative; } +#main > .since { + top: inherit; + font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +.content table { + border-spacing: 0 5px; + border-collapse: separate; +} +.content td { vertical-align: top; } +.content td:first-child { padding-right: 20px; } +.content td p:first-child { margin-top: 0; } +.content td h1, .content td h2 { margin-left: 0; font-size: 1.1em; } + +.docblock table { + border: 1px solid; + margin: .5em 0; + border-collapse: collapse; + width: 100%; +} + +.docblock table td { + padding: .5em; + border-top: 1px dashed; + border-bottom: 1px dashed; +} + +.docblock table th { + padding: .5em; + text-align: left; + border-top: 1px solid; + border-bottom: 1px solid; +} + +.fields + table { + margin-bottom: 1em; +} + +.content .item-list { + list-style-type: none; + padding: 0; +} + +.content .item-list li { margin-bottom: 3px; } + +.content .multi-column { + -moz-column-count: 5; + -moz-column-gap: 2.5em; + -webkit-column-count: 5; + -webkit-column-gap: 2.5em; + column-count: 5; + column-gap: 2.5em; +} +.content .multi-column li { width: 100%; display: inline-block; } + +.content .method { + font-size: 1em; + position: relative; +} +/* Shift "where ..." part of method or fn definition down a line */ +.content .method .where, +.content .fn .where, +.content .where.fmt-newline { + display: block; + color: #4E4C4C; + font-size: 0.8em; +} + +.content .methods > div { margin-left: 40px; } + +.content .impl-items .docblock, .content .impl-items .stability { + margin-left: 40px; +} +.content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant { + margin-left: 20px; +} + +.content .stability code { + font-size: 90%; +} + +nav { + border-bottom: 1px solid; + padding-bottom: 10px; + margin-bottom: 10px; +} +nav.main { + padding: 20px 0; + text-align: center; +} +nav.main .current { + border-top: 1px solid; + border-bottom: 1px solid; +} +nav.main .separator { + border: 1px solid; + display: inline-block; + height: 23px; + margin: 0 20px; +} +nav.sum { text-align: right; } +nav.sub form { display: inline; } + +nav.sub, .content { + margin-left: 230px; +} + +a { + text-decoration: none; + background: transparent; +} + +.docblock a:hover, .docblock-short a:hover, .stability a { + text-decoration: underline; +} + +.content span.enum, .content a.enum, .block a.current.enum { color: #5e9766; } +.content span.struct, .content a.struct, .block a.current.struct { color: #df3600; } +.content span.type, .content a.type, .block a.current.type { color: #e57300; } +.content span.macro, .content a.macro, .block a.current.macro { color: #068000; } +.block a.current.crate { font-weight: 500; } + +.search-input { + width: 100%; + /* Override Normalize.css: we have margins and do + not want to overflow - the `moz` attribute is necessary + until Firefox 29, too early to drop at this point */ + -moz-box-sizing: border-box !important; + box-sizing: border-box !important; + outline: none; + border: none; + border-radius: 1px; + margin-top: 5px; + padding: 10px 16px; + font-size: 17px; + transition: border-color 300ms ease; + transition: border-radius 300ms ease-in-out; + transition: box-shadow 300ms ease-in-out; +} + +.search-input:focus { + border-color: #66afe9; + border-radius: 2px; + border: 0; + outline: 0; + box-shadow: 0 0 8px #078dd8; +} + +.search-results .desc { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + display: block; +} + +.search-results a { + display: block; +} + +.content .search-results td:first-child { padding-right: 0; } +.content .search-results td:first-child a { padding-right: 10px; } + +tr.result span.primitive::after { content: ' (primitive type)'; font-style: italic; color: black; +} + +body.blur > :not(#help) { + filter: blur(8px); + -webkit-filter: blur(8px); + opacity: .7; +} + +#help { + width: 100%; + height: 100vh; + position: fixed; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; +} +#help > div { + flex: 0 0 auto; + box-shadow: 0 0 6px rgba(0,0,0,.2); + width: 550px; + height: 330px; + border: 1px solid; +} +#help dt { + float: left; + border-radius: 4px; + border: 1px solid; + width: 23px; + text-align: center; + clear: left; + display: block; + margin-top: -1px; +} +#help dd { margin: 5px 33px; } +#help .infos { padding-left: 0; } +#help h1, #help h2 { margin-top: 0; } +#help > div div { + width: 50%; + float: left; + padding: 20px; +} + +.stab { + display: table; + border-width: 1px; + border-style: solid; + padding: 3px; + margin-bottom: 5px; + font-size: 90%; +} +.stab p { + display: inline; +} + +.stab summary { + display: list-item; +} + +.stab .microscope { + font-size: 1.5em; +} + +.module-item .stab { + display: inline; + border-width: 0; + padding: 0; + margin: 0; + background: inherit !important; +} + +.module-item.unstable { + opacity: 0.65; +} + +.since { + font-weight: normal; + font-size: initial; + position: absolute; + right: 0; + top: 0; +} + +.variants_table { + width: 100%; +} + +.variants_table tbody tr td:first-child { + width: 1%; /* make the variant name as small as possible */ +} + +td.summary-column { + width: 100%; +} + +.summary { + padding-right: 0px; +} + +pre.rust .question-mark { + font-weight: bold; +} + +pre.rust { position: relative; } +a.test-arrow { + display: inline-block; + position: absolute; + padding: 5px 10px 5px 10px; + border-radius: 5px; + font-size: 130%; + top: 5px; + right: 5px; +} +a.test-arrow:hover{ + text-decoration: none; +} + +.section-header:hover a:after { + content: '\2002\00a7\2002'; +} + +.section-header:hover a { + text-decoration: none; +} + +.section-header a { + color: inherit; +} + +.collapse-toggle { + font-weight: 300; + position: absolute; + left: -23px; + color: #999; + top: 0; +} + +h3 > .collapse-toggle, h4 > .collapse-toggle { + font-size: 0.8em; + top: 5px; +} + +.toggle-wrapper > .collapse-toggle { + left: -24px; + margin-top: 0px; +} + +.toggle-wrapper { + position: relative; +} + +.toggle-wrapper.collapsed { + height: 1em; + transition: height .2s; +} + +.collapse-toggle > .inner { + display: inline-block; + width: 1.2ch; + text-align: center; +} + +.ghost { + display: none; +} + +.ghost + .since { + position: initial; + display: table-cell; +} + +.since + .srclink { + display: table-cell; + padding-left: 10px; +} + +.item-spacer { + width: 100%; + height: 12px; +} + +span.since { + position: initial; + font-size: 20px; + margin-right: 5px; +} + +.toggle-wrapper > .collapse-toggle { + left: 0; +} + +.variant + .toggle-wrapper > a { + margin-top: 5px; +} + +.sub-variant, .sub-variant > h3 { + margin-top: 0 !important; +} + +.enum > .toggle-wrapper + .docblock, .struct > .toggle-wrapper + .docblock { + margin-left: 30px; + margin-bottom: 20px; + margin-top: 5px; +} + +.enum > .collapsed, .struct > .collapsed { + margin-bottom: 25px; +} + +.enum .variant, .struct .structfield { + display: block; +} + +.attributes { + display: block; + margin: 0px 0px 0px 30px !important; +} +.toggle-attributes.collapsed { + margin-bottom: 5px; +} + +:target > code { + opacity: 1; +} + +/* Media Queries */ + +@media (max-width: 700px) { + body { + padding-top: 0px; + } + + .sidebar { + height: 40px; + min-height: 40px; + width: 100%; + margin: 0px; + padding: 0px; + position: static; + } + + .sidebar .location { + float: right; + margin: 0px; + padding: 3px 10px 1px 10px; + min-height: 39px; + background: inherit; + text-align: left; + font-size: 24px; + } + + .sidebar .location:empty { + padding: 0; + } + + .sidebar img { + width: 35px; + margin-top: 5px; + margin-bottom: 0px; + float: left; + } + + nav.sub { + margin: 0 auto; + } + + .sidebar .block { + display: none; + } + + .content { + margin-left: 0px; + } + + .content .in-band { + width: 100%; + } + + .content .out-of-band { + display: none; + } + + .toggle-wrapper > .collapse-toggle { + left: 0px; + } + + .toggle-wrapper { + height: 1.5em; + } +} + +@media print { + nav.sub, .content .out-of-band, .collapse-toggle { + display: none; + } +} diff --git a/search-index.js b/search-index.js new file mode 100644 index 0000000..1176640 --- /dev/null +++ b/search-index.js @@ -0,0 +1,3 @@ +var searchIndex = {}; +searchIndex["quick_error"] = {"doc":"A macro which makes errors easy to write","items":[[3,"Context","quick_error","Generic context type",null,null],[12,"0","","",0,null],[12,"1","","",0,null],[8,"ResultExt","","Result extension trait adding a `context` method",null,null],[10,"context","","The method is use to add context information to current operation",1,{"inputs":[{"name":"self"},{"name":"x"}],"output":{"name":"result"}}],[11,"fmt","","",0,{"inputs":[{"name":"self"},{"name":"formatter"}],"output":{"name":"result"}}],[14,"quick_error","","Main macro that does all the work",null,null]],"paths":[[3,"Context"],[8,"ResultExt"]]}; +initSearch(searchIndex); diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index cbce984..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,1350 +0,0 @@ -#![warn(missing_docs, rust_2018_idioms)] -//! A macro which makes errors easy to write -//! -//! Minimum type is like this: -//! -//! ```rust -//! #[macro_use] extern crate quick_error; -//! # fn main() {} -//! -//! quick_error! { -//! #[derive(Debug)] -//! pub enum SomeError { -//! Variant1 {} -//! } -//! } -//! ``` -//! Both ``pub`` and non-public types may be declared, and all meta attributes -//! (such as ``#[derive(Debug)]``) are forwarded as is. The `Debug` must be -//! implemented (but you may do that yourself if you like). The documentation -//! comments ``/// something`` (as well as other meta attrbiutes) on variants -//! are allowed. -//! -//! # Allowed Syntax -//! -//! You may add arbitrary parameters to any struct variant: -//! -//! ```rust -//! # #[macro_use] extern crate quick_error; -//! # fn main() {} -//! # -//! quick_error! { -//! #[derive(Debug)] -//! pub enum SomeError { -//! /// IO Error -//! Io(err: std::io::Error) {} -//! /// Utf8 Error -//! Utf8(err: std::str::Utf8Error) {} -//! } -//! } -//! ``` -//! -//! Struct variants are also possible: -//! -//! ```rust -//! # #[macro_use] extern crate quick_error; -//! # fn main() {} -//! # -//! quick_error! { -//! #[derive(Debug)] -//! pub enum SomeError { -//! Io { err: std::io::Error, msg: String } {} -//! } -//! } -//! ``` -//! -//! Note unlike in normal Enum declarations you declare names of fields (which -//! are omitted from type). How they can be used is outlined below. -//! -//! Now you might have noticed trailing braces `{}`. They are used to define -//! implementations. By default: -//! -//! * `Error::source()` returns None (even if type wraps some value) -//! * `Display` outputs debug representation -//! * No `From` implementations are defined -//! -//! ```rust -//! # #[macro_use] extern crate quick_error; -//! # fn main() {} -//! # -//! quick_error! { -//! #[derive(Debug)] -//! pub enum SomeError { -//! Io(err: std::io::Error) { -//! display("{}", err) -//! } -//! Utf8(err: std::str::Utf8Error) { -//! display("utf8 error") -//! } -//! } -//! } -//! ``` -//! -//! To change `source` method to return some error, add `source(value)`, for -//! example: -//! -//! ```rust -//! # #[macro_use] extern crate quick_error; -//! # fn main() {} -//! # -//! quick_error! { -//! #[derive(Debug)] -//! pub enum SomeError { -//! Io(err: std::io::Error) { -//! source(err) -//! } -//! Utf8(err: std::str::Utf8Error) { -//! display("utf8 error") -//! } -//! Other(err: Box) { -//! source(&**err) -//! } -//! } -//! } -//! ``` -//! Note you don't need to wrap value in `Some`, its implicit. In case you want -//! `None` returned just omit the `source`. You can't return `None` -//! conditionally. -//! -//! To change how each clause is `Display`ed add `display(pattern,..args)`, -//! for example: -//! -//! ```rust -//! # #[macro_use] extern crate quick_error; -//! # fn main() {} -//! # -//! quick_error! { -//! #[derive(Debug)] -//! pub enum SomeError { -//! Io(err: std::io::Error) { -//! display("I/O error: {}", err) -//! } -//! Utf8(err: std::str::Utf8Error) { -//! display("Utf8 error, valid up to {}", err.valid_up_to()) -//! } -//! } -//! } -//! ``` -//! -//! If you need a reference to the error when `Display`ing, you can instead use -//! `display(x) -> (pattern, ..args)`, where `x` sets the name of the reference. -//! -//! ```rust -//! # #[macro_use] extern crate quick_error; -//! # fn main() {} -//! # -//! use std::error::Error; // put methods like `source()` of this trait into scope -//! -//! quick_error! { -//! #[derive(Debug)] -//! pub enum SomeError { -//! Io(err: std::io::Error) { -//! display(x) -> ("I/O: {}", err) -//! } -//! Utf8(err: std::str::Utf8Error) { -//! display(self_) -> ("UTF-8 error. Valid up to {}", err.valid_up_to()) -//! } -//! } -//! } -//! ``` -//! -//! To convert to the type from any other, use one of the three forms of -//! `from` clause. -//! -//! For example, to convert simple wrapper use bare `from()`: -//! -//! ```rust -//! # #[macro_use] extern crate quick_error; -//! # fn main() {} -//! # -//! quick_error! { -//! #[derive(Debug)] -//! pub enum SomeError { -//! Io(err: std::io::Error) { -//! from() -//! } -//! } -//! } -//! ``` -//! -//! This implements ``From``. -//! -//! To convert to singleton enumeration type (discarding the value), use -//! the `from(type)` form: -//! -//! ```rust -//! # #[macro_use] extern crate quick_error; -//! # fn main() {} -//! # -//! quick_error! { -//! #[derive(Debug)] -//! pub enum SomeError { -//! FormatError { -//! from(std::fmt::Error) -//! } -//! } -//! } -//! ``` -//! -//! And the most powerful form is `from(var: type) -> (arguments...)`. It -//! might be used to convert to type with multiple arguments or for arbitrary -//! value conversions: -//! -//! ```rust -//! # #[macro_use] extern crate quick_error; -//! # fn main() {} -//! # -//! quick_error! { -//! #[derive(Debug)] -//! pub enum SomeError { -//! FailedOperation(s: &'static str, errno: i32) { -//! from(errno: i32) -> ("os error", errno) -//! from(e: std::io::Error) -> ("io error", e.raw_os_error().unwrap()) -//! } -//! /// Converts from both kinds of utf8 errors -//! Utf8(err: std::str::Utf8Error) { -//! from() -//! from(err: std::string::FromUtf8Error) -> (err.utf8_error()) -//! } -//! } -//! } -//! ``` -//! # Context -//! -//! Since quick-error 1.1 we also have a `context` declaration, which is -//! similar to (the longest form of) `from`, but allows adding some context to -//! the error. We need a longer example to demonstrate this: -//! -//! ```rust -//! # #[macro_use] extern crate quick_error; -//! # use std::io; -//! # use std::fs::File; -//! # use std::path::{Path, PathBuf}; -//! # -//! use quick_error::ResultExt; -//! -//! quick_error! { -//! #[derive(Debug)] -//! pub enum Error { -//! File(filename: PathBuf, err: io::Error) { -//! context(path: &'a Path, err: io::Error) -//! -> (path.to_path_buf(), err) -//! } -//! } -//! } -//! -//! fn openfile(path: &Path) -> Result<(), Error> { -//! File::open(path).context(path)?; -//! -//! // If we didn't have context, the line above would be written as; -//! // -//! // File::open(path) -//! // .map_err(|err| Error::File(path.to_path_buf(), err))?; -//! -//! Ok(()) -//! } -//! -//! # fn main() { -//! # openfile(Path::new("/etc/somefile")).ok(); -//! # } -//! ``` -//! -//! Each `context(a: A, b: B)` clause implements -//! `From> for Error`. Which means multiple `context` clauses -//! are a subject to the normal coherence rules. Unfortunately, we can't -//! provide full support of generics for the context, but you may either use a -//! lifetime `'a` for references or `AsRef` (the latter means `A: -//! AsRef`, and `Type` must be concrete). It's also occasionally useful -//! to use a tuple as a type of the first argument. -//! -//! You also need to `use quick_error::ResultExt` extension trait to get -//! working `.context()` method. -//! -//! More info on context in [this article](http://bit.ly/1PsuxDt). -//! -//! All forms of `from`, `display`, `source`, and `context` -//! clauses can be combined and put in arbitrary order. Only `from` and -//! `context` can be used multiple times in single variant of enumeration. -//! Docstrings are also okay. Empty braces can be omitted as of quick_error -//! 0.1.3. -//! -//! # Private Enums -//! -//! Since quick-error 1.2.0 we have a way to make a private enum that is -//! wrapped by public structure: -//! -//! ```rust -//! #[macro_use] extern crate quick_error; -//! # fn main() {} -//! -//! quick_error! { -//! #[derive(Debug)] -//! pub enum PubError wraps ErrorEnum { -//! Variant1 {} -//! } -//! } -//! ``` -//! -//! This generates data structures like this -//! -//! ```rust -//! -//! pub struct PubError(ErrorEnum); -//! -//! enum ErrorEnum { -//! Variant1, -//! } -//! -//! ``` -//! -//! Which in turn allows you to export just `PubError` in your crate and keep -//! actual enumeration private to the crate. This is useful to keep backwards -//! compatibility for error types. Currently there is no shorcuts to define -//! error constructors for the inner type, but we consider adding some in -//! future versions. -//! -//! It's possible to declare internal enum as public too. -//! -//! - -/// Main macro that does all the work -#[macro_export] -macro_rules! quick_error { - - ( $(#[$meta:meta])* - pub enum $name:ident { $($chunks:tt)* } - ) => { - quick_error!(SORT [pub enum $name $(#[$meta])* ] - items [] buf [] - queue [ $($chunks)* ]); - }; - ( $(#[$meta:meta])* - enum $name:ident { $($chunks:tt)* } - ) => { - quick_error!(SORT [enum $name $(#[$meta])* ] - items [] buf [] - queue [ $($chunks)* ]); - }; - - ( $(#[$meta:meta])* - pub enum $name:ident wraps $enum_name:ident { $($chunks:tt)* } - ) => { - quick_error!(WRAPPER $enum_name [ pub struct ] $name $(#[$meta])*); - quick_error!(SORT [enum $enum_name $(#[$meta])* ] - items [] buf [] - queue [ $($chunks)* ]); - }; - - ( $(#[$meta:meta])* - pub enum $name:ident wraps pub $enum_name:ident { $($chunks:tt)* } - ) => { - quick_error!(WRAPPER $enum_name [ pub struct ] $name $(#[$meta])*); - quick_error!(SORT [pub enum $enum_name $(#[$meta])* ] - items [] buf [] - queue [ $($chunks)* ]); - }; - ( $(#[$meta:meta])* - enum $name:ident wraps $enum_name:ident { $($chunks:tt)* } - ) => { - quick_error!(WRAPPER $enum_name [ struct ] $name $(#[$meta])*); - quick_error!(SORT [enum $enum_name $(#[$meta])* ] - items [] buf [] - queue [ $($chunks)* ]); - }; - - ( $(#[$meta:meta])* - enum $name:ident wraps pub $enum_name:ident { $($chunks:tt)* } - ) => { - quick_error!(WRAPPER $enum_name [ struct ] $name $(#[$meta])*); - quick_error!(SORT [pub enum $enum_name $(#[$meta])* ] - items [] buf [] - queue [ $($chunks)* ]); - }; - - - ( - WRAPPER $internal:ident [ $($strdef:tt)* ] $strname:ident - $(#[$meta:meta])* - ) => { - $(#[$meta])* - $($strdef)* $strname ( $internal ); - - impl ::std::fmt::Display for $strname { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) - -> ::std::fmt::Result - { - ::std::fmt::Display::fmt(&self.0, f) - } - } - - impl From<$internal> for $strname { - fn from(err: $internal) -> Self { - $strname(err) - } - } - - impl ::std::error::Error for $strname { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - self.0.source() - } - } - }; - - // Queue is empty, can do the work - (SORT [enum $name:ident $( #[$meta:meta] )*] - items [$($( #[$imeta:meta] )* - => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] - {$( $ifuncs:tt )*} )* ] - buf [ ] - queue [ ] - ) => { - quick_error!(ENUM_DEFINITION [enum $name $( #[$meta] )*] - body [] - queue [$($( #[$imeta] )* - => $iitem: $imode [$( $ivar: $ityp ),*] )*] - ); - quick_error!(IMPLEMENTATIONS $name {$( - $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*} - )*}); - $( - quick_error!(ERROR_CHECK $imode $($ifuncs)*); - )* - }; - (SORT [pub enum $name:ident $( #[$meta:meta] )*] - items [$($( #[$imeta:meta] )* - => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*] - {$( $ifuncs:tt )*} )* ] - buf [ ] - queue [ ] - ) => { - quick_error!(ENUM_DEFINITION [pub enum $name $( #[$meta] )*] - body [] - queue [$($( #[$imeta] )* - => $iitem: $imode [$( $ivar: $ityp ),*] )*] - ); - quick_error!(IMPLEMENTATIONS $name {$( - $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*} - )*}); - $( - quick_error!(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 )*] - ) => { - quick_error!(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 )*] - ) => { - quick_error!(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 )*] - ) => { - quick_error!(SORT [$( $def )*] - 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 )*] - ) => { - quick_error!(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 )*] - ) => { - quick_error!(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 )*] - ) => { - quick_error!(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 )*] - ) => { - quick_error!(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 )*] - ) => { - quick_error!(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 [ ] - ) => { - quick_error!(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 [ ] - ) => { - #[allow(unknown_lints)] // no unused_doc_comments in older rust - #[allow(renamed_and_removed_lints)] - #[allow(unused_doc_comment)] - #[allow(unused_doc_comments)] - $(#[$meta])* - pub enum $name { - $( - $(#[$imeta])* - $iitem $(($( $ttyp ),+))* $({$( $svar: $styp ),*})*, - )* - } - }; - // Private enum (Queue Empty) - (ENUM_DEFINITION [enum $name:ident $( #[$meta:meta] )*] - body [$($( #[$imeta:meta] )* - => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ] - queue [ ] - ) => { - #[allow(unknown_lints)] // no unused_doc_comments in older rust - #[allow(renamed_and_removed_lints)] - #[allow(unused_doc_comment)] - #[allow(unused_doc_comments)] - $(#[$meta])* - enum $name { - $( - $(#[$imeta])* - $iitem $(($( $ttyp ),+))* $({$( $svar: $styp ),*})*, - )* - } - }; - // 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 )*] - ) => { - quick_error!(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 )*] - ) => { - quick_error!(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 )*] - ) => { - quick_error!(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(unused_variables)] - #[allow(unknown_lints)] // no unused_doc_comments in older rust - #[allow(renamed_and_removed_lints)] - #[allow(unused_doc_comment)] - #[allow(unused_doc_comments)] - impl ::std::fmt::Display for $name { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) - -> ::std::fmt::Result - { - match *self { - $( - $(#[$imeta])* - quick_error!(ITEM_PATTERN - $name $item: $imode [$( ref $var ),*] - ) => { - let display_fn = quick_error!(FIND_DISPLAY_IMPL - $name $item: $imode - {$( $funcs )*}); - - display_fn(self, fmt) - } - )* - } - } - } - #[allow(unused_variables)] - #[allow(unknown_lints)] // no unused_doc_comments in older rust - #[allow(renamed_and_removed_lints)] - #[allow(unused_doc_comment)] - #[allow(unused_doc_comments)] - impl ::std::error::Error for $name { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match *self { - $( - $(#[$imeta])* - quick_error!(ITEM_PATTERN - $name $item: $imode [$( ref $var ),*] - ) => { - quick_error!(FIND_SOURCE_IMPL - $item: $imode [$( $var ),*] - {$( $funcs )*}) - } - )* - } - } - } - $( - quick_error!(FIND_FROM_IMPL - $name $item: $imode [$( $var:$typ ),*] - {$( $funcs )*}); - )* - $( - quick_error!(FIND_CONTEXT_IMPL - $name $item: $imode [$( $var:$typ ),*] - {$( $funcs )*}); - )* - }; - (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt - { display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*} - ) => { - |quick_error!(IDENT $self_): &$name, f: &mut ::std::fmt::Formatter<'_>| { write!(f, $( $exprs )*) } - }; - (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt - { display($pattern:expr) $( $tail:tt )*} - ) => { - |_, f: &mut ::std::fmt::Formatter<'_>| { write!(f, $pattern) } - }; - (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt - { display($pattern:expr, $( $exprs:tt )*) $( $tail:tt )*} - ) => { - |_, f: &mut ::std::fmt::Formatter<'_>| { write!(f, $pattern, $( $exprs )*) } - }; - (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt - { $t:tt $( $tail:tt )*} - ) => { - quick_error!(FIND_DISPLAY_IMPL - $name $item: $imode - {$( $tail )*}) - }; - (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt - { } - ) => { - |self_: &$name, f: &mut ::std::fmt::Formatter<'_>| { - write!(f, "{:?}", self_) - } - }; - (FIND_SOURCE_IMPL $item:ident: $imode:tt - [$( $var:ident ),*] - { source($expr:expr) $( $tail:tt )*} - ) => { - Some($expr) - }; - (FIND_SOURCE_IMPL $item:ident: $imode:tt - [$( $var:ident ),*] - { $t:tt $( $tail:tt )*} - ) => { - quick_error!(FIND_SOURCE_IMPL - $item: $imode [$( $var ),*] - { $($tail)* }) - }; - (FIND_SOURCE_IMPL $item:ident: $imode:tt - [$( $var:ident ),*] - { } - ) => { - None - }; - // ----------------------------- FROM IMPL -------------------------- - (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt - [$( $var:ident: $typ:ty ),*] - { from() $( $tail:tt )*} - ) => { - $( - impl From<$typ> for $name { - fn from($var: $typ) -> $name { - $name::$item($var) - } - } - )* - quick_error!(FIND_FROM_IMPL - $name $item: $imode [$( $var:$typ ),*] - {$( $tail )*}); - }; - (FIND_FROM_IMPL $name:ident $item:ident: UNIT - [ ] - { from($ftyp:ty) $( $tail:tt )*} - ) => { - impl From<$ftyp> for $name { - fn from(_discarded_error: $ftyp) -> $name { - $name::$item - } - } - quick_error!(FIND_FROM_IMPL - $name $item: UNIT [ ] - {$( $tail )*}); - }; - (FIND_FROM_IMPL $name:ident $item:ident: TUPLE - [$( $var:ident: $typ:ty ),*] - { from($fvar:ident: $ftyp:ty) -> ($( $texpr:expr ),*) $( $tail:tt )*} - ) => { - impl From<$ftyp> for $name { - fn from($fvar: $ftyp) -> $name { - $name::$item($( $texpr ),*) - } - } - quick_error!(FIND_FROM_IMPL - $name $item: TUPLE [$( $var:$typ ),*] - { $($tail)* }); - }; - (FIND_FROM_IMPL $name:ident $item:ident: STRUCT - [$( $var:ident: $typ:ty ),*] - { from($fvar:ident: $ftyp:ty) -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )*} - ) => { - impl From<$ftyp> for $name { - fn from($fvar: $ftyp) -> $name { - $name::$item { - $( $tvar: $texpr ),* - } - } - } - quick_error!(FIND_FROM_IMPL - $name $item: STRUCT [$( $var:$typ ),*] - { $($tail)* }); - }; - (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt - [$( $var:ident: $typ:ty ),*] - { $t:tt $( $tail:tt )*} - ) => { - quick_error!(FIND_FROM_IMPL - $name $item: $imode [$( $var:$typ ),*] - {$( $tail )*} - ); - }; - (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt - [$( $var:ident: $typ:ty ),*] - { } - ) => { - }; - // ----------------------------- CONTEXT IMPL -------------------------- - (FIND_CONTEXT_IMPL $name:ident $item:ident: TUPLE - [$( $var:ident: $typ:ty ),*] - { context($cvar:ident: AsRef<$ctyp:ty>, $fvar:ident: $ftyp:ty) - -> ($( $texpr:expr ),*) $( $tail:tt )* } - ) => { - impl> From<$crate::Context> for $name { - fn from( - $crate::Context($cvar, $fvar): $crate::Context) - -> $name - { - $name::$item($( $texpr ),*) - } - } - quick_error!(FIND_CONTEXT_IMPL - $name $item: TUPLE [$( $var:$typ ),*] - { $($tail)* }); - }; - (FIND_CONTEXT_IMPL $name:ident $item:ident: TUPLE - [$( $var:ident: $typ:ty ),*] - { context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty) - -> ($( $texpr:expr ),*) $( $tail:tt )* } - ) => { - impl<'a> From<$crate::Context<$ctyp, $ftyp>> for $name { - fn from( - $crate::Context($cvar, $fvar): $crate::Context<$ctyp, $ftyp>) - -> $name - { - $name::$item($( $texpr ),*) - } - } - quick_error!(FIND_CONTEXT_IMPL - $name $item: TUPLE [$( $var:$typ ),*] - { $($tail)* }); - }; - (FIND_CONTEXT_IMPL $name:ident $item:ident: STRUCT - [$( $var:ident: $typ:ty ),*] - { context($cvar:ident: AsRef<$ctyp:ty>, $fvar:ident: $ftyp:ty) - -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )* } - ) => { - impl> From<$crate::Context> for $name { - fn from( - $crate::Context($cvar, $fvar): $crate::Context<$ctyp, $ftyp>) - -> $name - { - $name::$item { - $( $tvar: $texpr ),* - } - } - } - quick_error!(FIND_CONTEXT_IMPL - $name $item: STRUCT [$( $var:$typ ),*] - { $($tail)* }); - }; - (FIND_CONTEXT_IMPL $name:ident $item:ident: STRUCT - [$( $var:ident: $typ:ty ),*] - { context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty) - -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )* } - ) => { - impl<'a> From<$crate::Context<$ctyp, $ftyp>> for $name { - fn from( - $crate::Context($cvar, $fvar): $crate::Context<$ctyp, $ftyp>) - -> $name - { - $name::$item { - $( $tvar: $texpr ),* - } - } - } - quick_error!(FIND_CONTEXT_IMPL - $name $item: STRUCT [$( $var:$typ ),*] - { $($tail)* }); - }; - (FIND_CONTEXT_IMPL $name:ident $item:ident: $imode:tt - [$( $var:ident: $typ:ty ),*] - { $t:tt $( $tail:tt )*} - ) => { - quick_error!(FIND_CONTEXT_IMPL - $name $item: $imode [$( $var:$typ ),*] - {$( $tail )*} - ); - }; - (FIND_CONTEXT_IMPL $name:ident $item:ident: $imode:tt - [$( $var:ident: $typ:ty ),*] - { } - ) => { - }; - // ----------------------------- ITEM IMPL -------------------------- - (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 )*) - => { quick_error!(ERROR_CHECK $imode $($tail)*); }; - (ERROR_CHECK $imode:tt display($pattern: expr) $( $tail:tt )*) - => { quick_error!(ERROR_CHECK $imode $($tail)*); }; - (ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*) - => { quick_error!(ERROR_CHECK $imode $($tail)*); }; - (ERROR_CHECK $imode:tt source($expr:expr) $($tail:tt)*) - => { quick_error!(ERROR_CHECK $imode $($tail)*); }; - (ERROR_CHECK $imode:tt from() $($tail:tt)*) - => { quick_error!(ERROR_CHECK $imode $($tail)*); }; - (ERROR_CHECK $imode:tt from($ftyp:ty) $($tail:tt)*) - => { quick_error!(ERROR_CHECK $imode $($tail)*); }; - (ERROR_CHECK TUPLE from($fvar:ident: $ftyp:ty) -> ($( $e:expr ),*) $( $tail:tt )*) - => { quick_error!(ERROR_CHECK TUPLE $($tail)*); }; - (ERROR_CHECK STRUCT from($fvar:ident: $ftyp:ty) -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*) - => { quick_error!(ERROR_CHECK STRUCT $($tail)*); }; - - (ERROR_CHECK TUPLE context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty) - -> ($( $e:expr ),*) $( $tail:tt )*) - => { quick_error!(ERROR_CHECK TUPLE $($tail)*); }; - (ERROR_CHECK STRUCT context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty) - -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*) - => { quick_error!(ERROR_CHECK STRUCT $($tail)*); }; - - (ERROR_CHECK $imode:tt ) => {}; - // Utility functions - (IDENT $ident:ident) => { $ident } -} - -/// Generic context type -/// -/// Used mostly as a transport for `ResultExt::context` method -#[derive(Debug)] -pub struct Context(pub X, pub E); - -/// Result extension trait adding a `context` method -pub trait ResultExt { - /// The method is use to add context information to current operation - /// - /// The context data is then used in error constructor to store additional - /// information within error. For example, you may add a filename as a - /// context for file operation. See crate documentation for the actual - /// example. - fn context(self, x: X) -> Result>; -} - -impl ResultExt for Result { - fn context(self, x: X) -> Result> { - self.map_err(|e| Context(x, e)) - } -} - -#[cfg(test)] -mod test { - use std::error::Error; - use std::num::{ParseFloatError, ParseIntError}; - use std::path::{Path, PathBuf}; - use std::str::Utf8Error; - use std::string::FromUtf8Error; - - use super::ResultExt; - - quick_error! { - #[derive(Debug)] - pub enum Bare { - One - Two - } - } - - #[test] - fn bare_item_direct() { - assert_eq!(format!("{}", Bare::One), "One".to_string()); - assert_eq!(format!("{:?}", Bare::One), "One".to_string()); - assert!(Bare::One.source().is_none()); - } - - #[test] - fn bare_item_trait() { - let err: &dyn Error = &Bare::Two; - assert_eq!(format!("{}", err), "Two".to_string()); - assert_eq!(format!("{:?}", err), "Two".to_string()); - assert!(err.source().is_none()); - } - - quick_error! { - #[derive(Debug)] - pub enum Wrapper wraps Wrapped { - One - Two(s: String) { - display("two: {}", s) - from() - } - } - } - - #[test] - fn wrapper() { - assert_eq!( - format!("{}", Wrapper::from(Wrapped::One)), - "One".to_string() - ); - assert_eq!( - format!("{}", Wrapper::from(Wrapped::from(String::from("hello")))), - "two: hello".to_string() - ); - assert_eq!( - format!("{:?}", Wrapper::from(Wrapped::One)), - "Wrapper(One)".to_string() - ); - } - - quick_error! { - #[derive(Debug, PartialEq)] - pub enum TupleWrapper { - /// ParseFloat Error - ParseFloatError(err: ParseFloatError) { - from() - display("parse float error: {err}", err=err) - source(err) - } - Other(descr: &'static str) { - display("Error: {}", descr) - } - /// FromUtf8 Error - FromUtf8Error(err: Utf8Error, source: Vec) { - source(err) - display(me) -> ("{desc} at index {pos}: {err}", desc="utf8 error", pos=err.valid_up_to(), err=err) - from(err: FromUtf8Error) -> (err.utf8_error().clone(), err.into_bytes()) - } - Discard { - from(&'static str) - } - Singleton { - display("Just a string") - } - } - } - - #[test] - fn tuple_wrapper_err() { - let source = "one and a half times pi".parse::().unwrap_err(); - let err = TupleWrapper::ParseFloatError(source.clone()); - assert_eq!(format!("{}", err), format!("parse float error: {}", source)); - assert_eq!( - format!("{:?}", err), - format!("ParseFloatError({:?})", source) - ); - assert_eq!( - format!("{:?}", err.source().unwrap()), - format!("{:?}", source) - ); - } - - #[test] - fn tuple_wrapper_trait_str() { - let desc = "hello"; - let err: &dyn Error = &TupleWrapper::Other(desc); - assert_eq!(format!("{}", err), format!("Error: {}", desc)); - assert_eq!(format!("{:?}", err), format!("Other({:?})", desc)); - assert!(err.source().is_none()); - } - - #[test] - fn tuple_wrapper_trait_two_fields() { - let invalid_utf8: Vec = vec![0, 159, 146, 150]; - let source = String::from_utf8(invalid_utf8.clone()) - .unwrap_err() - .utf8_error(); - let err: &dyn Error = &TupleWrapper::FromUtf8Error(source.clone(), invalid_utf8.clone()); - assert_eq!( - format!("{}", err), - format!( - "{desc} at index {pos}: {source}", - desc = "utf8 error", - pos = source.valid_up_to(), - source = source - ) - ); - assert_eq!( - format!("{:?}", err), - format!("FromUtf8Error({:?}, {:?})", source, invalid_utf8) - ); - assert_eq!( - format!("{:?}", err.source().unwrap()), - format!("{:?}", source) - ); - } - - #[test] - fn tuple_wrapper_from() { - let source = "one and a half times pi".parse::().unwrap_err(); - let err = TupleWrapper::ParseFloatError(source.clone()); - let err_from: TupleWrapper = From::from(source); - assert_eq!(err_from, err); - } - - #[test] - fn tuple_wrapper_custom_from() { - let invalid_utf8: Vec = vec![0, 159, 146, 150]; - let source = String::from_utf8(invalid_utf8.clone()).unwrap_err(); - let err = TupleWrapper::FromUtf8Error(source.utf8_error().clone(), invalid_utf8); - let err_from: TupleWrapper = From::from(source); - assert_eq!(err_from, err); - } - - #[test] - fn tuple_wrapper_discard() { - let err: TupleWrapper = From::from("hello"); - assert_eq!(format!("{}", err), format!("Discard")); - assert_eq!(format!("{:?}", err), format!("Discard")); - assert!(err.source().is_none()); - } - - #[test] - fn tuple_wrapper_singleton() { - let err: TupleWrapper = TupleWrapper::Singleton; - assert_eq!(format!("{}", err), format!("Just a string")); - assert_eq!(format!("{:?}", err), format!("Singleton")); - assert!(err.source().is_none()); - } - - quick_error! { - #[derive(Debug, PartialEq)] - pub enum StructWrapper { - // Utf8 Error - Utf8Error{ err: Utf8Error, hint: Option<&'static str> } { - source(err) - display(me) -> ("{desc} at index {pos}: {err}", desc="utf8 error", pos=err.valid_up_to(), err=err) - from(err: Utf8Error) -> { err: err, hint: None } - } - // Utf8 Error - ExcessComma { descr: &'static str, } { - display("Error: {}", descr) - } - } - } - - #[test] - fn struct_wrapper_err() { - let invalid_utf8: Vec = vec![0, 159, 146, 150]; - let source = String::from_utf8(invalid_utf8.clone()) - .unwrap_err() - .utf8_error(); - let err: &dyn Error = &StructWrapper::Utf8Error { - err: source.clone(), - hint: Some("nonsense"), - }; - assert_eq!( - format!("{}", err), - format!( - "{desc} at index {pos}: {source}", - desc = "utf8 error", - pos = source.valid_up_to(), - source = source - ) - ); - assert_eq!( - format!("{:?}", err), - format!( - "Utf8Error {{ err: {:?}, hint: {:?} }}", - source, - Some("nonsense") - ) - ); - assert_eq!( - format!("{:?}", err.source().unwrap()), - format!("{:?}", source) - ); - } - - #[test] - fn struct_wrapper_struct_from() { - let invalid_utf8: Vec = vec![0, 159, 146, 150]; - let source = String::from_utf8(invalid_utf8.clone()) - .unwrap_err() - .utf8_error(); - let err = StructWrapper::Utf8Error { - err: source.clone(), - hint: None, - }; - let err_from: StructWrapper = From::from(source); - assert_eq!(err_from, err); - } - - #[test] - fn struct_wrapper_excess_comma() { - let descr = "hello"; - let err = StructWrapper::ExcessComma { descr: descr }; - assert_eq!(format!("{}", err), format!("Error: {}", descr)); - assert_eq!( - format!("{:?}", err), - format!("ExcessComma {{ descr: {:?} }}", descr) - ); - assert!(err.source().is_none()); - } - - quick_error! { - #[derive(Debug)] - pub enum ContextErr { - Float(src: String, err: ParseFloatError) { - context(s: &'a str, e: ParseFloatError) -> (s.to_string(), e) - display("Float error {:?}: {}", src, err) - } - Int { src: String, err: ParseIntError } { - context(s: &'a str, e: ParseIntError) - -> {src: s.to_string(), err: e} - display("Int error {:?}: {}", src, err) - } - Utf8(path: PathBuf, err: Utf8Error) { - context(p: AsRef, e: Utf8Error) - -> (p.as_ref().to_path_buf(), e) - display("Path error at {:?}: {}", path, err) - } - Utf8Str(s: String, err: ::std::io::Error) { - context(s: AsRef, e: ::std::io::Error) - -> (s.as_ref().to_string(), e) - display("Str error {:?}: {}", s, err) - } - } - } - - #[test] - fn parse_float_error() { - fn parse_float(s: &str) -> Result { - Ok(s.parse().context(s)?) - } - assert_eq!( - format!("{}", parse_float("12ab").unwrap_err()), - r#"Float error "12ab": invalid float literal"# - ); - } - - #[test] - fn parse_int_error() { - fn parse_int(s: &str) -> Result { - Ok(s.parse().context(s)?) - } - assert_eq!( - format!("{}", parse_int("12.5").unwrap_err()), - r#"Int error "12.5": invalid digit found in string"# - ); - } - - #[test] - fn debug_context() { - fn parse_int(s: &str) -> i32 { - s.parse().context(s).unwrap() - } - assert_eq!(parse_int("12"), 12); - assert_eq!( - format!("{:?}", "x".parse::().context("x")), - r#"Err(Context("x", ParseIntError { kind: InvalidDigit }))"# - ); - } - - #[test] - fn path_context() { - fn parse_utf>(s: &[u8], p: P) -> Result<(), ContextErr> { - ::std::str::from_utf8(s).context(p)?; - Ok(()) - } - let etext = parse_utf(b"a\x80\x80", "/etc").unwrap_err().to_string(); - assert!(etext.starts_with("Path error at \"/etc\": invalid utf-8")); - let etext = parse_utf(b"\x80\x80", PathBuf::from("/tmp")) - .unwrap_err() - .to_string(); - assert!(etext.starts_with("Path error at \"/tmp\": invalid utf-8")); - } - - #[test] - fn conditional_compilation() { - quick_error! { - #[allow(dead_code)] - #[derive(Debug)] - pub enum Test { - #[cfg(feature = "foo")] - Variant - } - } - } - - #[test] - #[allow(deprecated)] - fn cause_struct_wrapper_err() { - let invalid_utf8: Vec = vec![0, 159, 146, 150]; - let cause = String::from_utf8(invalid_utf8.clone()) - .unwrap_err() - .utf8_error(); - let err: &dyn Error = &StructWrapper::Utf8Error { - err: cause.clone(), - hint: Some("nonsense"), - }; - assert_eq!( - format!("{}", err), - format!( - "{desc} at index {pos}: {cause}", - desc = "utf8 error", - pos = cause.valid_up_to(), - cause = cause - ) - ); - assert_eq!( - format!("{:?}", err), - format!( - "Utf8Error {{ err: {:?}, hint: {:?} }}", - cause, - Some("nonsense") - ) - ); - assert_eq!( - format!("{:?}", err.cause().unwrap()), - format!("{:?}", cause) - ); - } -} diff --git a/src/quick_error/lib.rs.html b/src/quick_error/lib.rs.html new file mode 100644 index 0000000..9489e9c --- /dev/null +++ b/src/quick_error/lib.rs.html @@ -0,0 +1,2710 @@ + + + + + + + + + + lib.rs.html -- source + + + + + + + + + + + + + + + + + + +
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+
+#![warn(missing_docs)]
+//! A macro which makes errors easy to write
+//!
+//! Minimum type is like this:
+//!
+//! ```rust
+//! #[macro_use] extern crate quick_error;
+//! # fn main() {}
+//!
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum SomeError {
+//!         Variant1 {}
+//!     }
+//! }
+//! ```
+//! Both ``pub`` and non-public types may be declared, and all meta attributes
+//! (such as ``#[derive(Debug)]``) are forwarded as is. The `Debug` must be
+//! implemented (but you may do that yourself if you like). The documentation
+//! comments ``/// something`` (as well as other meta attrbiutes) on variants
+//! are allowed.
+//!
+//! # Allowed Syntax
+//!
+//! You may add arbitrary parameters to any struct variant:
+//!
+//! ```rust
+//! # #[macro_use] extern crate quick_error;
+//! # fn main() {}
+//! #
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum SomeError {
+//!         /// IO Error
+//!         Io(err: std::io::Error) {}
+//!         /// Utf8 Error
+//!         Utf8(err: std::str::Utf8Error) {}
+//!     }
+//! }
+//! ```
+//!
+//! Note unlike in normal Enum declarations you declare names of fields (which
+//! are omitted from type). How they can be used is outlined below.
+//!
+//! Now you might have noticed trailing braces `{}`. They are used to define
+//! implementations. By default:
+//!
+//! * `Error::description()` returns variant name as static string
+//! * `Error::cause()` returns None (even if type wraps some value)
+//! * `Display` outputs `description()`
+//! * No `From` implementations are defined
+//!
+//! To define description simply add `description(value)` inside braces:
+//!
+//! ```rust
+//! # #[macro_use] extern crate quick_error;
+//! # fn main() {}
+//! #
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum SomeError {
+//!         Io(err: std::io::Error) {
+//!             description(err.description())
+//!         }
+//!         Utf8(err: std::str::Utf8Error) {
+//!             description("utf8 error")
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! Normal rules for borrowing apply. So most of the time description either
+//! returns constant string or forwards description from enclosed type.
+//!
+//! To change `cause` method to return some error, add `cause(value)`, for
+//! example:
+//!
+//! ```rust
+//! # #[macro_use] extern crate quick_error;
+//! # fn main() {}
+//! #
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum SomeError {
+//!         Io(err: std::io::Error) {
+//!             cause(err)
+//!             description(err.description())
+//!         }
+//!         Utf8(err: std::str::Utf8Error) {
+//!             description("utf8 error")
+//!         }
+//!         Other(err: Box<std::error::Error>) {
+//!             cause(&**err)
+//!             description(err.description())
+//!         }
+//!     }
+//! }
+//! ```
+//! Note you don't need to wrap value in `Some`, its implicit. In case you want
+//! `None` returned just omit the `cause`. You can't return `None`
+//! conditionally.
+//!
+//! To change how each clause is `Display`ed add `display(pattern,..args)`,
+//! for example:
+//!
+//! ```rust
+//! # #[macro_use] extern crate quick_error;
+//! # fn main() {}
+//! #
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum SomeError {
+//!         Io(err: std::io::Error) {
+//!             display("I/O error: {}", err)
+//!         }
+//!         Utf8(err: std::str::Utf8Error) {
+//!             display("Utf8 error, valid up to {}", err.valid_up_to())
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! If you need a reference to the error when `Display`ing, you can instead use
+//! `display(x) -> (pattern, ..args)`, where `x` sets the name of the reference.
+//!
+//! ```rust
+//! # #[macro_use] extern crate quick_error;
+//! # fn main() {}
+//! #
+//! use std::error::Error; // put methods like `description()` of this trait into scope
+//!
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum SomeError {
+//!         Io(err: std::io::Error) {
+//!             display(x) -> ("{}: {}", x.description(), err)
+//!         }
+//!         Utf8(err: std::str::Utf8Error) {
+//!             display(self_) -> ("{}, valid up to {}", self_.description(), err.valid_up_to())
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! To convert to the type from any other, use one of the three forms of
+//! `from` clause.
+//!
+//! For example, to convert simple wrapper use bare `from()`:
+//!
+//! ```rust
+//! # #[macro_use] extern crate quick_error;
+//! # fn main() {}
+//! #
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum SomeError {
+//!         Io(err: std::io::Error) {
+//!             from()
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! This implements ``From<io::Error>``.
+//!
+//! To convert to singleton enumeration type (discarding the value), use
+//! the `from(type)` form:
+//!
+//! ```rust
+//! # #[macro_use] extern crate quick_error;
+//! # fn main() {}
+//! #
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum SomeError {
+//!         FormatError {
+//!             from(std::fmt::Error)
+//!         }
+//!     }
+//! }
+//! ```
+//!
+//! And the most powerful form is `from(var: type) -> (arguments...)`. It
+//! might be used to convert to type with multiple arguments or for arbitrary
+//! value conversions:
+//!
+//! ```rust
+//! # #[macro_use] extern crate quick_error;
+//! # fn main() {}
+//! #
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum SomeError {
+//!         FailedOperation(s: &'static str, errno: i32) {
+//!             from(errno: i32) -> ("os error", errno)
+//!             from(e: std::io::Error) -> ("io error", e.raw_os_error().unwrap())
+//!         }
+//!         /// Converts from both kinds of utf8 errors
+//!         Utf8(err: std::str::Utf8Error) {
+//!             from()
+//!             from(err: std::string::FromUtf8Error) -> (err.utf8_error())
+//!         }
+//!     }
+//! }
+//! ```
+//! # Context
+//!
+//! Since quick-error 1.1 we also have a `context` declaration, which is
+//! similar to (the longest form of) `from`, but allows adding some context to
+//! the error. We need a longer example to demonstrate this:
+//!
+//! ```rust
+//! # #[macro_use] extern crate quick_error;
+//! # use std::io;
+//! # use std::fs::File;
+//! # use std::path::{Path, PathBuf};
+//! #
+//! use quick_error::ResultExt;
+//!
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum Error {
+//!         File(filename: PathBuf, err: io::Error) {
+//!             context(path: &'a Path, err: io::Error)
+//!                 -> (path.to_path_buf(), err)
+//!         }
+//!     }
+//! }
+//!
+//! fn openfile(path: &Path) -> Result<(), Error> {
+//!     try!(File::open(path).context(path));
+//!
+//!     // If we didn't have context, the line above would be written as;
+//!     //
+//!     // try!(File::open(path)
+//!     //     .map_err(|err| Error::File(path.to_path_buf(), err)));
+//!
+//!     Ok(())
+//! }
+//!
+//! # fn main() {
+//! #     openfile(Path::new("/etc/somefile")).ok();
+//! # }
+//! ```
+//!
+//! Each `context(a: A, b: B)` clause implements
+//! `From<Context<A, B>> for Error`. Which means multiple `context` clauses
+//! are a subject to the normal coherence rules. Unfortunately, we can't
+//! provide full support of generics for the context, but you may either use a
+//! lifetime `'a` for references or `AsRef<Type>` (the latter means `A:
+//! AsRef<Type>`, and `Type` must be concrete). It's also occasionally useful
+//! to use a tuple as a type of the first argument.
+//!
+//! You also need to `use quick_error::ResultExt` extension trait to get
+//! working `.context()` method.
+//!
+//! More info on context in [this article](http://bit.ly/1PsuxDt).
+//!
+//! All forms of `from`, `display`, `description`, `cause`, and `context`
+//! clauses can be combined and put in arbitrary order. Only `from` and
+//! `context` can be used multiple times in single variant of enumeration.
+//! Docstrings are also okay.  Empty braces can be omitted as of quick_error
+//! 0.1.3.
+//!
+//! # Private Enums
+//!
+//! Since quick-error 1.2.0 we  have a way to make a private enum that is
+//! wrapped by public structure:
+//!
+//! ```rust
+//! #[macro_use] extern crate quick_error;
+//! # fn main() {}
+//!
+//! quick_error! {
+//!     #[derive(Debug)]
+//!     pub enum PubError wraps ErrorEnum {
+//!         Variant1 {}
+//!     }
+//! }
+//! ```
+//!
+//! This generates data structures like this
+//!
+//! ```rust
+//!
+//! pub struct PubError(ErrorEnum);
+//!
+//! enum ErrorEnum {
+//!     Variant1,
+//! }
+//!
+//! ```
+//!
+//! Which in turn allows you to export just `PubError` in your crate and keep
+//! actual enumeration private to the crate. This is useful to keep backwards
+//! compatibility for error types. Currently there is no shorcuts to define
+//! error constructors for the inner type, but we consider adding some in
+//! future versions.
+//!
+//! It's possible to declare internal enum as public too.
+//!
+//!
+
+
+/// Main macro that does all the work
+#[macro_export]
+macro_rules! quick_error {
+
+    (   $(#[$meta:meta])*
+        pub enum $name:ident { $($chunks:tt)* }
+    ) => {
+        quick_error!(SORT [pub enum $name $(#[$meta])* ]
+            items [] buf []
+            queue [ $($chunks)* ]);
+    };
+    (   $(#[$meta:meta])*
+        enum $name:ident { $($chunks:tt)* }
+    ) => {
+        quick_error!(SORT [enum $name $(#[$meta])* ]
+            items [] buf []
+            queue [ $($chunks)* ]);
+    };
+
+    (   $(#[$meta:meta])*
+        pub enum $name:ident wraps $enum_name:ident { $($chunks:tt)* }
+    ) => {
+        quick_error!(WRAPPER $enum_name [ pub struct ] $name $(#[$meta])*);
+        quick_error!(SORT [enum $enum_name $(#[$meta])* ]
+            items [] buf []
+            queue [ $($chunks)* ]);
+    };
+
+    (   $(#[$meta:meta])*
+        pub enum $name:ident wraps pub $enum_name:ident { $($chunks:tt)* }
+    ) => {
+        quick_error!(WRAPPER $enum_name [ pub struct ] $name $(#[$meta])*);
+        quick_error!(SORT [pub enum $enum_name $(#[$meta])* ]
+            items [] buf []
+            queue [ $($chunks)* ]);
+    };
+    (   $(#[$meta:meta])*
+        enum $name:ident wraps $enum_name:ident { $($chunks:tt)* }
+    ) => {
+        quick_error!(WRAPPER $enum_name [ struct ] $name $(#[$meta])*);
+        quick_error!(SORT [enum $enum_name $(#[$meta])* ]
+            items [] buf []
+            queue [ $($chunks)* ]);
+    };
+
+    (   $(#[$meta:meta])*
+        enum $name:ident wraps pub $enum_name:ident { $($chunks:tt)* }
+    ) => {
+        quick_error!(WRAPPER $enum_name [ struct ] $name $(#[$meta])*);
+        quick_error!(SORT [pub enum $enum_name $(#[$meta])* ]
+            items [] buf []
+            queue [ $($chunks)* ]);
+    };
+
+
+    (
+        WRAPPER $internal:ident [ $($strdef:tt)* ] $strname:ident
+        $(#[$meta:meta])*
+    ) => {
+        $(#[$meta])*
+        $($strdef)* $strname ( $internal );
+
+        impl ::std::fmt::Display for $strname {
+            fn fmt(&self, f: &mut ::std::fmt::Formatter)
+                -> ::std::fmt::Result
+            {
+                ::std::fmt::Display::fmt(&self.0, f)
+            }
+        }
+
+        impl From<$internal> for $strname {
+            fn from(err: $internal) -> Self {
+                $strname(err)
+            }
+        }
+
+        impl ::std::error::Error for $strname {
+            fn description(&self) -> &str {
+                self.0.description()
+            }
+            fn cause(&self) -> Option<&::std::error::Error> {
+                self.0.cause()
+            }
+        }
+    };
+
+    // Queue is empty, can do the work
+    (SORT [enum $name:ident $( #[$meta:meta] )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [ ]
+        queue [ ]
+    ) => {
+        quick_error!(ENUM_DEFINITION [enum $name $( #[$meta] )*]
+            body []
+            queue [$($( #[$imeta] )*
+                      => $iitem: $imode [$( $ivar: $ityp ),*] )*]
+        );
+        quick_error!(IMPLEMENTATIONS $name {$(
+           $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*}
+           )*});
+        $(
+            quick_error!(ERROR_CHECK $imode $($ifuncs)*);
+        )*
+    };
+    (SORT [pub enum $name:ident $( #[$meta:meta] )*]
+        items [$($( #[$imeta:meta] )*
+                  => $iitem:ident: $imode:tt [$( $ivar:ident: $ityp:ty ),*]
+                                {$( $ifuncs:tt )*} )* ]
+        buf [ ]
+        queue [ ]
+    ) => {
+        quick_error!(ENUM_DEFINITION [pub enum $name $( #[$meta] )*]
+            body []
+            queue [$($( #[$imeta] )*
+                      => $iitem: $imode [$( $ivar: $ityp ),*] )*]
+        );
+        quick_error!(IMPLEMENTATIONS $name {$(
+           $iitem: $imode [$(#[$imeta])*] [$( $ivar: $ityp ),*] {$( $ifuncs )*}
+           )*});
+        $(
+            quick_error!(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 )*]
+    ) => {
+        quick_error!(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 )*]
+    ) => {
+        quick_error!(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 )*]
+    ) => {
+        quick_error!(SORT [$( $def )*]
+            enum [$( $(#[$emeta])* => $eitem $(( $($etyp),* ))* )*
+                     $(#[$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 )*]
+    ) => {
+        quick_error!(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 )*]
+    ) => {
+        quick_error!(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 )*]
+    ) => {
+        quick_error!(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 )*]
+    ) => {
+        quick_error!(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 )*]
+    ) => {
+        quick_error!(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 [ ]
+    ) => {
+        quick_error!(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 [ ]
+    ) => {
+        #[allow(unknown_lints)]  // no unused_doc_comments in older rust
+        #[allow(unused_doc_comment)]
+        $(#[$meta])*
+        pub enum $name {
+            $(
+                $(#[$imeta])*
+                $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*,
+            )*
+        }
+    };
+    // Private enum (Queue Empty)
+    (ENUM_DEFINITION [enum $name:ident $( #[$meta:meta] )*]
+        body [$($( #[$imeta:meta] )*
+            => $iitem:ident ($(($( $ttyp:ty ),+))*) {$({$( $svar:ident: $styp:ty ),*})*} )* ]
+        queue [ ]
+    ) => {
+        #[allow(unknown_lints)]  // no unused_doc_comments in older rust
+        #[allow(unused_doc_comment)]
+        $(#[$meta])*
+        enum $name {
+            $(
+                $(#[$imeta])*
+                $iitem $(($( $ttyp ),*))* $({$( $svar: $styp ),*})*,
+            )*
+        }
+    };
+    // 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 )*]
+    ) => {
+        quick_error!(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 )*]
+    ) => {
+        quick_error!(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 )*]
+    ) => {
+        quick_error!(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(unused)]
+        #[allow(unknown_lints)]  // no unused_doc_comments in older rust
+        #[allow(unused_doc_comment)]
+        impl ::std::fmt::Display for $name {
+            fn fmt(&self, fmt: &mut ::std::fmt::Formatter)
+                -> ::std::fmt::Result
+            {
+                match *self {
+                    $(
+                        $(#[$imeta])*
+                        quick_error!(ITEM_PATTERN
+                            $name $item: $imode [$( ref $var ),*]
+                        ) => {
+                            let display_fn = quick_error!(FIND_DISPLAY_IMPL
+                                $name $item: $imode
+                                {$( $funcs )*});
+
+                            display_fn(self, fmt)
+                        }
+                    )*
+                }
+            }
+        }
+        #[allow(unused)]
+        #[allow(unknown_lints)]  // no unused_doc_comments in older rust
+        #[allow(unused_doc_comment)]
+        impl ::std::error::Error for $name {
+            fn description(&self) -> &str {
+                match *self {
+                    $(
+                        $(#[$imeta])*
+                        quick_error!(ITEM_PATTERN
+                            $name $item: $imode [$( ref $var ),*]
+                        ) => {
+                            quick_error!(FIND_DESCRIPTION_IMPL
+                                $item: $imode self fmt [$( $var ),*]
+                                {$( $funcs )*})
+                        }
+                    )*
+                }
+            }
+            fn cause(&self) -> Option<&::std::error::Error> {
+                match *self {
+                    $(
+                        $(#[$imeta])*
+                        quick_error!(ITEM_PATTERN
+                            $name $item: $imode [$( ref $var ),*]
+                        ) => {
+                            quick_error!(FIND_CAUSE_IMPL
+                                $item: $imode [$( $var ),*]
+                                {$( $funcs )*})
+                        }
+                    )*
+                }
+            }
+        }
+        $(
+            quick_error!(FIND_FROM_IMPL
+                $name $item: $imode [$( $var:$typ ),*]
+                {$( $funcs )*});
+        )*
+        $(
+            quick_error!(FIND_CONTEXT_IMPL
+                $name $item: $imode [$( $var:$typ ),*]
+                {$( $funcs )*});
+        )*
+    };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { display($self_:tt) -> ($( $exprs:tt )*) $( $tail:tt )*}
+    ) => {
+        |quick_error!(IDENT $self_): &$name, f: &mut ::std::fmt::Formatter| { write!(f, $( $exprs )*) }
+    };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { display($pattern:expr) $( $tail:tt )*}
+    ) => {
+        |_, f: &mut ::std::fmt::Formatter| { write!(f, $pattern) }
+    };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { display($pattern:expr, $( $exprs:tt )*) $( $tail:tt )*}
+    ) => {
+        |_, f: &mut ::std::fmt::Formatter| { write!(f, $pattern, $( $exprs )*) }
+    };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { $t:tt $( $tail:tt )*}
+    ) => {
+        quick_error!(FIND_DISPLAY_IMPL
+            $name $item: $imode
+            {$( $tail )*})
+    };
+    (FIND_DISPLAY_IMPL $name:ident $item:ident: $imode:tt
+        { }
+    ) => {
+        |self_: &$name, f: &mut ::std::fmt::Formatter| {
+            write!(f, "{}", ::std::error::Error::description(self_))
+        }
+    };
+    (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 )*}
+    ) => {
+        quick_error!(FIND_DESCRIPTION_IMPL
+            $item: $imode $me $fmt [$( $var ),*]
+            {$( $tail )*})
+    };
+    (FIND_DESCRIPTION_IMPL $item:ident: $imode:tt $me:ident $fmt:ident
+        [$( $var:ident ),*]
+        { }
+    ) => {
+        stringify!($item)
+    };
+    (FIND_CAUSE_IMPL $item:ident: $imode:tt
+        [$( $var:ident ),*]
+        { cause($expr:expr) $( $tail:tt )*}
+    ) => {
+        Some($expr)
+    };
+    (FIND_CAUSE_IMPL $item:ident: $imode:tt
+        [$( $var:ident ),*]
+        { $t:tt $( $tail:tt )*}
+    ) => {
+        quick_error!(FIND_CAUSE_IMPL
+            $item: $imode [$( $var ),*]
+            { $($tail)* })
+    };
+    (FIND_CAUSE_IMPL $item:ident: $imode:tt
+        [$( $var:ident ),*]
+        { }
+    ) => {
+        None
+    };
+    // ----------------------------- FROM IMPL --------------------------
+    (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { from() $( $tail:tt )*}
+    ) => {
+        $(
+            impl From<$typ> for $name {
+                fn from($var: $typ) -> $name {
+                    $name::$item($var)
+                }
+            }
+        )*
+        quick_error!(FIND_FROM_IMPL
+            $name $item: $imode [$( $var:$typ ),*]
+            {$( $tail )*});
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: UNIT
+        [ ]
+        { from($ftyp:ty) $( $tail:tt )*}
+    ) => {
+        impl From<$ftyp> for $name {
+            fn from(_discarded_error: $ftyp) -> $name {
+                $name::$item
+            }
+        }
+        quick_error!(FIND_FROM_IMPL
+            $name $item: UNIT [  ]
+            {$( $tail )*});
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: TUPLE
+        [$( $var:ident: $typ:ty ),*]
+        { from($fvar:ident: $ftyp:ty) -> ($( $texpr:expr ),*) $( $tail:tt )*}
+    ) => {
+        impl From<$ftyp> for $name {
+            fn from($fvar: $ftyp) -> $name {
+                $name::$item($( $texpr ),*)
+            }
+        }
+        quick_error!(FIND_FROM_IMPL
+            $name $item: TUPLE [$( $var:$typ ),*]
+            { $($tail)* });
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: STRUCT
+        [$( $var:ident: $typ:ty ),*]
+        { from($fvar:ident: $ftyp:ty) -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )*}
+    ) => {
+        impl From<$ftyp> for $name {
+            fn from($fvar: $ftyp) -> $name {
+                $name::$item {
+                    $( $tvar: $texpr ),*
+                }
+            }
+        }
+        quick_error!(FIND_FROM_IMPL
+            $name $item: STRUCT [$( $var:$typ ),*]
+            { $($tail)* });
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { $t:tt $( $tail:tt )*}
+    ) => {
+        quick_error!(FIND_FROM_IMPL
+            $name $item: $imode [$( $var:$typ ),*]
+            {$( $tail )*}
+        );
+    };
+    (FIND_FROM_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { }
+    ) => {
+    };
+    // ----------------------------- CONTEXT IMPL --------------------------
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: TUPLE
+        [$( $var:ident: $typ:ty ),*]
+        { context($cvar:ident: AsRef<$ctyp:ty>, $fvar:ident: $ftyp:ty)
+            -> ($( $texpr:expr ),*) $( $tail:tt )* }
+    ) => {
+        impl<T: AsRef<$ctyp>> From<$crate::Context<T, $ftyp>> for $name {
+            fn from(
+                $crate::Context($cvar, $fvar): $crate::Context<T, $ftyp>)
+                -> $name
+            {
+                $name::$item($( $texpr ),*)
+            }
+        }
+        quick_error!(FIND_CONTEXT_IMPL
+            $name $item: TUPLE [$( $var:$typ ),*]
+            { $($tail)* });
+    };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: TUPLE
+        [$( $var:ident: $typ:ty ),*]
+        { context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
+            -> ($( $texpr:expr ),*) $( $tail:tt )* }
+    ) => {
+        impl<'a> From<$crate::Context<$ctyp, $ftyp>> for $name {
+            fn from(
+                $crate::Context($cvar, $fvar): $crate::Context<$ctyp, $ftyp>)
+                -> $name
+            {
+                $name::$item($( $texpr ),*)
+            }
+        }
+        quick_error!(FIND_CONTEXT_IMPL
+            $name $item: TUPLE [$( $var:$typ ),*]
+            { $($tail)* });
+    };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: STRUCT
+        [$( $var:ident: $typ:ty ),*]
+        { context($cvar:ident: AsRef<$ctyp:ty>, $fvar:ident: $ftyp:ty)
+            -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )* }
+    ) => {
+        impl<T: AsRef<$ctyp>> From<$crate::Context<T, $ftyp>> for $name {
+            fn from(
+                $crate::Context($cvar, $fvar): $crate::Context<$ctyp, $ftyp>)
+                -> $name
+            {
+                $name::$item {
+                    $( $tvar: $texpr ),*
+                }
+            }
+        }
+        quick_error!(FIND_CONTEXT_IMPL
+            $name $item: STRUCT [$( $var:$typ ),*]
+            { $($tail)* });
+    };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: STRUCT
+        [$( $var:ident: $typ:ty ),*]
+        { context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
+            -> {$( $tvar:ident: $texpr:expr ),*} $( $tail:tt )* }
+    ) => {
+        impl<'a> From<$crate::Context<$ctyp, $ftyp>> for $name {
+            fn from(
+                $crate::Context($cvar, $fvar): $crate::Context<$ctyp, $ftyp>)
+                -> $name
+            {
+                $name::$item {
+                    $( $tvar: $texpr ),*
+                }
+            }
+        }
+        quick_error!(FIND_CONTEXT_IMPL
+            $name $item: STRUCT [$( $var:$typ ),*]
+            { $($tail)* });
+    };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { $t:tt $( $tail:tt )*}
+    ) => {
+        quick_error!(FIND_CONTEXT_IMPL
+            $name $item: $imode [$( $var:$typ ),*]
+            {$( $tail )*}
+        );
+    };
+    (FIND_CONTEXT_IMPL $name:ident $item:ident: $imode:tt
+        [$( $var:ident: $typ:ty ),*]
+        { }
+    ) => {
+    };
+    // ----------------------------- ITEM IMPL --------------------------
+    (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 )*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt display($pattern: expr) $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt display($pattern: expr, $( $exprs:tt )*) $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt description($expr:expr) $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt cause($expr:expr) $($tail:tt)*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt from() $($tail:tt)*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK $imode:tt from($ftyp:ty) $($tail:tt)*)
+    => { quick_error!(ERROR_CHECK $imode $($tail)*); };
+    (ERROR_CHECK TUPLE from($fvar:ident: $ftyp:ty) -> ($( $e:expr ),*) $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK TUPLE $($tail)*); };
+    (ERROR_CHECK STRUCT from($fvar:ident: $ftyp:ty) -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK STRUCT $($tail)*); };
+
+    (ERROR_CHECK TUPLE context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
+        -> ($( $e:expr ),*) $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK TUPLE $($tail)*); };
+    (ERROR_CHECK STRUCT context($cvar:ident: $ctyp:ty, $fvar:ident: $ftyp:ty)
+        -> {$( $v:ident: $e:expr ),*} $( $tail:tt )*)
+    => { quick_error!(ERROR_CHECK STRUCT $($tail)*); };
+
+    (ERROR_CHECK $imode:tt ) => {};
+    // Utility functions
+    (IDENT $ident:ident) => { $ident }
+}
+
+
+/// Generic context type
+///
+/// Used mostly as a transport for `ResultExt::context` method
+#[derive(Debug)]
+pub struct Context<X, E>(pub X, pub E);
+
+/// Result extension trait adding a `context` method
+pub trait ResultExt<T, E> {
+    /// The method is use to add context information to current operation
+    ///
+    /// The context data is then used in error constructor to store additional
+    /// information within error. For example, you may add a filename as a
+    /// context for file operation. See crate documentation for the actual
+    /// example.
+    fn context<X>(self, x: X) -> Result<T, Context<X, E>>;
+}
+
+impl<T, E> ResultExt<T, E> for Result<T, E> {
+    fn context<X>(self, x: X) -> Result<T, Context<X, E>> {
+        self.map_err(|e| Context(x, e))
+    }
+}
+
+
+
+#[cfg(test)]
+mod test {
+    use std::num::{ParseFloatError, ParseIntError};
+    use std::str::Utf8Error;
+    use std::string::FromUtf8Error;
+    use std::error::Error;
+    use std::path::{Path, PathBuf};
+
+    use super::ResultExt;
+
+    quick_error! {
+        #[derive(Debug)]
+        pub enum Bare {
+            One
+            Two
+        }
+    }
+
+    #[test]
+    fn bare_item_direct() {
+        assert_eq!(format!("{}", Bare::One), "One".to_string());
+        assert_eq!(format!("{:?}", Bare::One), "One".to_string());
+        assert_eq!(Bare::One.description(), "One".to_string());
+        assert!(Bare::One.cause().is_none());
+    }
+    #[test]
+    fn bare_item_trait() {
+        let err: &Error = &Bare::Two;
+        assert_eq!(format!("{}", err), "Two".to_string());
+        assert_eq!(format!("{:?}", err), "Two".to_string());
+        assert_eq!(err.description(), "Two".to_string());
+        assert!(err.cause().is_none());
+    }
+
+    quick_error! {
+        #[derive(Debug)]
+        pub enum Wrapper wraps Wrapped {
+            One
+            Two(s: String) {
+                display("two: {}", s)
+                from()
+            }
+        }
+    }
+
+    #[test]
+    fn wrapper() {
+        assert_eq!(format!("{}", Wrapper::from(Wrapped::One)),
+            "One".to_string());
+        assert_eq!(format!("{}",
+            Wrapper::from(Wrapped::from(String::from("hello")))),
+            "two: hello".to_string());
+        assert_eq!(format!("{:?}", Wrapper::from(Wrapped::One)),
+            "Wrapper(One)".to_string());
+        assert_eq!(Wrapper::from(Wrapped::One).description(),
+            "One".to_string());
+    }
+
+    quick_error! {
+        #[derive(Debug, PartialEq)]
+        pub enum TupleWrapper {
+            /// ParseFloat Error
+            ParseFloatError(err: ParseFloatError) {
+                from()
+                description(err.description())
+                display("parse float error: {err}", err=err)
+                cause(err)
+            }
+            Other(descr: &'static str) {
+                description(descr)
+                display("Error: {}", descr)
+            }
+            /// FromUtf8 Error
+            FromUtf8Error(err: Utf8Error, source: Vec<u8>) {
+                cause(err)
+                display(me) -> ("{desc} at index {pos}: {err}", desc=me.description(), pos=err.valid_up_to(), err=err)
+                description("utf8 error")
+                from(err: FromUtf8Error) -> (err.utf8_error().clone(), err.into_bytes())
+            }
+            Discard {
+                from(&'static str)
+            }
+            Singleton {
+                display("Just a string")
+            }
+        }
+    }
+
+    #[test]
+    fn tuple_wrapper_err() {
+        let cause = "one and a half times pi".parse::<f32>().unwrap_err();
+        let err = TupleWrapper::ParseFloatError(cause.clone());
+        assert_eq!(format!("{}", err), format!("parse float error: {}", cause));
+        assert_eq!(format!("{:?}", err), format!("ParseFloatError({:?})", cause));
+        assert_eq!(err.description(), cause.description());
+        assert_eq!(format!("{:?}", err.cause().unwrap()), format!("{:?}", cause));
+    }
+
+    #[test]
+    fn tuple_wrapper_trait_str() {
+        let desc = "hello";
+        let err: &Error = &TupleWrapper::Other(desc);
+        assert_eq!(format!("{}", err), format!("Error: {}", desc));
+        assert_eq!(format!("{:?}", err), format!("Other({:?})", desc));
+        assert_eq!(err.description(), desc);
+        assert!(err.cause().is_none());
+    }
+
+    #[test]
+    fn tuple_wrapper_trait_two_fields() {
+        let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
+        let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err().utf8_error();
+        let err: &Error = &TupleWrapper::FromUtf8Error(cause.clone(), invalid_utf8.clone());
+        assert_eq!(format!("{}", err), format!("{desc} at index {pos}: {cause}", desc=err.description(), pos=cause.valid_up_to(), cause=cause));
+        assert_eq!(format!("{:?}", err), format!("FromUtf8Error({:?}, {:?})", cause, invalid_utf8));
+        assert_eq!(err.description(), "utf8 error");
+        assert_eq!(format!("{:?}", err.cause().unwrap()), format!("{:?}", cause));
+    }
+
+    #[test]
+    fn tuple_wrapper_from() {
+        let cause = "one and a half times pi".parse::<f32>().unwrap_err();
+        let err = TupleWrapper::ParseFloatError(cause.clone());
+        let err_from: TupleWrapper = From::from(cause);
+        assert_eq!(err_from, err);
+    }
+
+    #[test]
+    fn tuple_wrapper_custom_from() {
+        let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
+        let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err();
+        let err = TupleWrapper::FromUtf8Error(cause.utf8_error().clone(), invalid_utf8);
+        let err_from: TupleWrapper = From::from(cause);
+        assert_eq!(err_from, err);
+    }
+
+    #[test]
+    fn tuple_wrapper_discard() {
+        let err: TupleWrapper = From::from("hello");
+        assert_eq!(format!("{}", err), format!("Discard"));
+        assert_eq!(format!("{:?}", err), format!("Discard"));
+        assert_eq!(err.description(), "Discard");
+        assert!(err.cause().is_none());
+    }
+
+    #[test]
+    fn tuple_wrapper_singleton() {
+        let err: TupleWrapper = TupleWrapper::Singleton;
+        assert_eq!(format!("{}", err), format!("Just a string"));
+        assert_eq!(format!("{:?}", err), format!("Singleton"));
+        assert_eq!(err.description(), "Singleton");
+        assert!(err.cause().is_none());
+    }
+
+    quick_error! {
+        #[derive(Debug, PartialEq)]
+        pub enum StructWrapper {
+            // Utf8 Error
+            Utf8Error{ err: Utf8Error, hint: Option<&'static str> } {
+                cause(err)
+                display(me) -> ("{desc} at index {pos}: {err}", desc=me.description(), pos=err.valid_up_to(), err=err)
+                description("utf8 error")
+                from(err: Utf8Error) -> { err: err, hint: None }
+            }
+            // Utf8 Error
+            ExcessComma { descr: &'static str, } {
+                description(descr)
+                display("Error: {}", descr)
+            }
+        }
+    }
+
+    #[test]
+    fn struct_wrapper_err() {
+        let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
+        let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err().utf8_error();
+        let err: &Error = &StructWrapper::Utf8Error{ err: cause.clone(), hint: Some("nonsense") };
+        assert_eq!(format!("{}", err), format!("{desc} at index {pos}: {cause}", desc=err.description(), pos=cause.valid_up_to(), cause=cause));
+        assert_eq!(format!("{:?}", err), format!("Utf8Error {{ err: {:?}, hint: {:?} }}", cause, Some("nonsense")));
+        assert_eq!(err.description(), "utf8 error");
+        assert_eq!(format!("{:?}", err.cause().unwrap()), format!("{:?}", cause));
+    }
+
+    #[test]
+    fn struct_wrapper_struct_from() {
+        let invalid_utf8: Vec<u8> = vec![0, 159, 146, 150];
+        let cause = String::from_utf8(invalid_utf8.clone()).unwrap_err().utf8_error();
+        let err = StructWrapper::Utf8Error{ err: cause.clone(), hint: None };
+        let err_from: StructWrapper = From::from(cause);
+        assert_eq!(err_from, err);
+    }
+
+    #[test]
+    fn struct_wrapper_excess_comma() {
+        let descr = "hello";
+        let err = StructWrapper::ExcessComma { descr: descr };
+        assert_eq!(format!("{}", err), format!("Error: {}", descr));
+        assert_eq!(format!("{:?}", err), format!("ExcessComma {{ descr: {:?} }}", descr));
+        assert_eq!(err.description(), descr);
+        assert!(err.cause().is_none());
+    }
+
+    quick_error! {
+        #[derive(Debug)]
+        pub enum ContextErr {
+            Float(src: String, err: ParseFloatError) {
+                context(s: &'a str, e: ParseFloatError) -> (s.to_string(), e)
+                display("Float error {:?}: {}", src, err)
+            }
+            Int { src: String, err: ParseIntError } {
+                context(s: &'a str, e: ParseIntError)
+                    -> {src: s.to_string(), err: e}
+                display("Int error {:?}: {}", src, err)
+            }
+            Utf8(path: PathBuf, err: Utf8Error) {
+                context(p: AsRef<Path>, e: Utf8Error)
+                    -> (p.as_ref().to_path_buf(), e)
+                display("Path error at {:?}: {}", path, err)
+            }
+            Utf8Str(s: String, err: ::std::io::Error) {
+                context(s: AsRef<str>, e: ::std::io::Error)
+                    -> (s.as_ref().to_string(), e)
+                display("Str error {:?}: {}", s, err)
+            }
+        }
+    }
+
+    #[test]
+    fn parse_float_error() {
+        fn parse_float(s: &str) -> Result<f32, ContextErr> {
+            Ok(try!(s.parse().context(s)))
+        }
+        assert_eq!(format!("{}", parse_float("12ab").unwrap_err()),
+            r#"Float error "12ab": invalid float literal"#);
+    }
+
+    #[test]
+    fn parse_int_error() {
+        fn parse_int(s: &str) -> Result<i32, ContextErr> {
+            Ok(try!(s.parse().context(s)))
+        }
+        assert_eq!(format!("{}", parse_int("12.5").unwrap_err()),
+            r#"Int error "12.5": invalid digit found in string"#);
+    }
+
+    #[test]
+    fn debug_context() {
+        fn parse_int(s: &str) -> i32 {
+            s.parse().context(s).unwrap()
+        }
+        assert_eq!(parse_int("12"), 12);
+        assert_eq!(format!("{:?}", "x".parse::<i32>().context("x")),
+            r#"Err(Context("x", ParseIntError { kind: InvalidDigit }))"#);
+    }
+
+    #[test]
+    fn path_context() {
+        fn parse_utf<P: AsRef<Path>>(s: &[u8], p: P)
+            -> Result<(), ContextErr>
+        {
+            try!(::std::str::from_utf8(s).context(p));
+            Ok(())
+        }
+        let etext = parse_utf(b"a\x80\x80", "/etc").unwrap_err().to_string();
+        assert!(etext.starts_with(
+            "Path error at \"/etc\": invalid utf-8"));
+        let etext = parse_utf(b"\x80\x80", PathBuf::from("/tmp")).unwrap_err()
+            .to_string();
+        assert!(etext.starts_with(
+            "Path error at \"/tmp\": invalid utf-8"));
+    }
+
+    #[test]
+    fn conditional_compilation() {
+        quick_error! {
+            #[allow(dead_code)]
+            #[derive(Debug)]
+            pub enum Test {
+                #[cfg(feature = "foo")]
+                Variant
+            }
+        }
+    }
+}
+
+
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/vagga.yaml b/vagga.yaml deleted file mode 100644 index 35eb296..0000000 --- a/vagga.yaml +++ /dev/null @@ -1,36 +0,0 @@ -commands: - - cargo: !Command - description: Run any cargo command - container: ubuntu - run: [cargo] - - test: !Command - description: Run unit tests - container: ubuntu - run: [cargo, test] - - _bulk: !Command - description: Run `bulk` command (for version bookkeeping) - container: ubuntu - run: [bulk] - -containers: - - ubuntu: - setup: - - !Ubuntu xenial - - !Install [ca-certificates, build-essential, vim] - - - !TarInstall - url: "https://static.rust-lang.org/dist/rust-1.31.0-x86_64-unknown-linux-gnu.tar.gz" - script: "./install.sh --prefix=/usr \ - --components=rustc,rust-std-x86_64-unknown-linux-gnu,cargo" - - &bulk !Tar - url: "https://github.com/tailhook/bulk/releases/download/v0.4.10/bulk-v0.4.10.tar.gz" - sha256: 481513f8a0306a9857d045497fb5b50b50a51e9ff748909ecf7d2bda1de275ab - path: / - - environ: - HOME: /work/target - USER: pc