commit 3f686f4a854787e3ddf7330b90911db716d1641d Author: LucioFranco Date: Mon Jun 15 16:39:27 2020 +0000 Deploy to GitHub pages diff --git a/.lock b/.lock new file mode 100755 index 0000000..e69de29 diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt new file mode 100644 index 0000000..af77776 --- /dev/null +++ b/COPYRIGHT.txt @@ -0,0 +1,45 @@ +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. + +* 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.ttf.woff, + SourceSerifPro-Bold.ttf.woff, SourceSerifPro-It.ttf.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/FiraSans-LICENSE.txt b/FiraSans-LICENSE.txt new file mode 100644 index 0000000..d444ea9 --- /dev/null +++ b/FiraSans-LICENSE.txt @@ -0,0 +1,94 @@ +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +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..7d742c5 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..d8e0363 Binary files /dev/null and b/FiraSans-Regular.woff differ 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.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/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.ttf.woff b/SourceSerifPro-Bold.ttf.woff new file mode 100644 index 0000000..ca25431 Binary files /dev/null and b/SourceSerifPro-Bold.ttf.woff differ diff --git a/SourceSerifPro-It.ttf.woff b/SourceSerifPro-It.ttf.woff new file mode 100644 index 0000000..a287bbe Binary files /dev/null and b/SourceSerifPro-It.ttf.woff differ diff --git a/SourceSerifPro-LICENSE.md b/SourceSerifPro-LICENSE.md new file mode 100644 index 0000000..22cb755 --- /dev/null +++ b/SourceSerifPro-LICENSE.md @@ -0,0 +1,93 @@ +Copyright 2014-2018 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe 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.ttf.woff b/SourceSerifPro-Regular.ttf.woff new file mode 100644 index 0000000..a3d55cf Binary files /dev/null and b/SourceSerifPro-Regular.ttf.woff differ diff --git a/aliases.js b/aliases.js new file mode 100644 index 0000000..b05b099 --- /dev/null +++ b/aliases.js @@ -0,0 +1,5 @@ +var ALIASES = {}; +ALIASES["tower"] = {}; +ALIASES["tower_layer"] = {}; +ALIASES["tower_service"] = {}; +ALIASES["tower_test"] = {}; diff --git a/brush.svg b/brush.svg new file mode 100644 index 0000000..ea266e8 --- /dev/null +++ b/brush.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dark.css b/dark.css new file mode 100644 index 0000000..0e47c69 --- /dev/null +++ b/dark.css @@ -0,0 +1 @@ +body{background-color:#353535;color:#ddd;}h1,h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){color:#ddd;}h1.fqn{border-bottom-color:#d2d2d2;}h2,h3:not(.impl):not(.method):not(.type):not(.tymethod),h4:not(.method):not(.type):not(.tymethod){border-bottom-color:#d2d2d2;}.in-band{background-color:#353535;}.invisible{background:rgba(0,0,0,0);}.docblock code,.docblock-short code{background-color:#2A2A2A;}pre{background-color:#2A2A2A;}.sidebar{background-color:#505050;}.sidebar .current{background-color:#333;}.source .sidebar{background-color:#353535;}.sidebar .location{border-color:#fff;background:#575757;color:#DDD;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#444;}.line-numbers span{color:#3B91E2;}.line-numbers .line-highlighted{background-color:#0a042f !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#DDD;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#ddd;}.content .highlighted{color:#eee !important;background-color:#616161;}.content .highlighted a,.content .highlighted span{color:#eee !important;}.content .highlighted.trait{background-color:#013191;}.content .highlighted.traitalias{background-color:#013191;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.mod{background-color:#803a1b;}.content .highlighted.externcrate{background-color:#396bac;}.content .highlighted.enum{background-color:#5b4e68;}.content .highlighted.struct{background-color:#194e9f;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#4950ed;}.content .highlighted.type{background-color:#38902c;}.content .highlighted.foreigntype{background-color:#b200d6;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#217d1c;}.content .highlighted.constant,.content .highlighted.static{background-color:#0063cc;}.content .highlighted.primitive{background-color:#00708a;}.content .highlighted.keyword{background-color:#884719;}.content .stability::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#82b089;}.content span.struct,.content a.struct,.block a.current.struct{color:#2dbfb8;}.content span.type,.content a.type,.block a.current.type{color:#ff7f00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#dd7de8;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#09bd00;}.content span.union,.content a.union,.block a.current.union{color:#a6ae37;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#82a5c9;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#43aec7;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#bda000;}.content span.trait,.content a.trait,.block a.current.trait{color:#b78cf2;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#b397da;}.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:#2BAB63;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8d8d8b;}pre.rust .doccomment{color:#8ca375;}nav:not(.sidebar){border-bottom-color:#4e4e4e;}nav.main .current{border-top-color:#eee;border-bottom-color:#eee;}nav.main .separator{border-color:#eee;}a{color:#ddd;}.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.stability a{color:#D2991D;}.stab.internal a{color:#304FFE;}a.test-arrow{color:#dedede;}.collapse-toggle{color:#999;}#crate-search{color:#111;background-color:#f0f0f0;border-color:#000;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input{color:#111;background-color:#f0f0f0;box-shadow:0 0 0 1px #000,0 0 0 2px transparent;}.search-input:focus{border-color:#008dfd;}.search-focus:disabled{background-color:#c5c4c4;}#crate-search+.search-input:focus{box-shadow:0 0 8px 4px #078dd8;}.module-item .stab{color:#ddd;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;color:#2f2f2f;}.stab.internal{background:#FFB9B3;border-color:#B71C1C;color:#2f2f2f;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;color:#2f2f2f;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;color:#2f2f2f;}.stab.portability>code{color:#ddd;}#help>div{background:#4d4d4d;border-color:#bfbfbf;}#help dt{border-color:#bfbfbf;background:rgba(0,0,0,0);color:black;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:#ddd;}.line-numbers :target{background-color:transparent;}pre.rust .kw{color:#ab8ac1;}pre.rust .kw-2,pre.rust .prelude-ty{color:#769acb;}pre.rust .number,pre.rust .string{color:#83a300;}pre.rust .self,pre.rust .bool-val,pre.rust .prelude-val,pre.rust .attribute,pre.rust .attribute .ident{color:#ee6868;}pre.rust .macro,pre.rust .macro-nonterminal{color:#3E999F;}pre.rust .lifetime{color:#d97f26;}pre.rust .question-mark{color:#ff9011;}.example-wrap>pre.line-number{border-color:#4a4949;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background-color:#494a3d;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.6);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.6);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.6);}.information>.compile_fail:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.6);}.information>.ignore:hover{color:rgba(255,142,0,1);}.search-failed a{color:#0089ff;}.tooltip .tooltiptext{background-color:black;color:#fff;}.tooltip .tooltiptext::after{border-color:transparent black transparent transparent;}#titles>div:not(.selected){background-color:#252525;border-top-color:#252525;}#titles>div:hover,#titles>div.selected{border-top-color:#0089ff;}#titles>div>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#505050;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#505050;border-right-color:#000;}#sidebar-filler{background-color:#505050;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu{border-color:#e0e0e0;background:#f0f0f0;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus{border-color:#ffb900;}#theme-choices{border-color:#e0e0e0;background-color:#353535;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#4e4e4e;}@media (max-width:700px){#theme-picker{background:#f0f0f0;}}#all-types{background-color:#505050;}#all-types:hover{background-color:#606060;}.search-results td span.alias{color:#fff;}.search-results td span.grey{color:#ccc;}#sidebar-toggle{background-color:#565656;}#sidebar-toggle:hover{background-color:#676767;}#source-sidebar{background-color:#565656;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#444;}div.files>.selected{background-color:#333;}.setting-line>.title{border-bottom-color:#ddd;} \ No newline at end of file diff --git a/down-arrow.svg b/down-arrow.svg new file mode 100644 index 0000000..35437e7 --- /dev/null +++ b/down-arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..b8ad237 Binary files /dev/null and b/favicon.ico differ diff --git a/implementors/core/clone/trait.Clone.js b/implementors/core/clone/trait.Clone.js new file mode 100644 index 0000000..671fa97 --- /dev/null +++ b/implementors/core/clone/trait.Clone.js @@ -0,0 +1,5 @@ +(function() {var implementors = {}; +implementors["tower"] = [{"text":"impl<L: Clone> Clone for ServiceBuilder<L>","synthetic":false,"types":["tower::builder::ServiceBuilder"]}]; +implementors["tower_layer"] = [{"text":"impl Clone for Identity","synthetic":false,"types":["tower_layer::identity::Identity"]},{"text":"impl<Inner: Clone, Outer: Clone> Clone for Stack<Inner, Outer>","synthetic":false,"types":["tower_layer::stack::Stack"]}]; +implementors["tower_test"] = [{"text":"impl<T: Clone> Clone for Spawn<T>","synthetic":false,"types":["tower_test::mock::spawn::Spawn"]},{"text":"impl<T, U> Clone for Mock<T, U>","synthetic":false,"types":["tower_test::mock::Mock"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/default/trait.Default.js b/implementors/core/default/trait.Default.js new file mode 100644 index 0000000..a50f493 --- /dev/null +++ b/implementors/core/default/trait.Default.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["tower_layer"] = [{"text":"impl Default for Identity","synthetic":false,"types":["tower_layer::identity::Identity"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Debug.js b/implementors/core/fmt/trait.Debug.js new file mode 100644 index 0000000..bfd9c87 --- /dev/null +++ b/implementors/core/fmt/trait.Debug.js @@ -0,0 +1,5 @@ +(function() {var implementors = {}; +implementors["tower"] = [{"text":"impl<L: Debug> Debug for ServiceBuilder<L>","synthetic":false,"types":["tower::builder::ServiceBuilder"]}]; +implementors["tower_layer"] = [{"text":"impl Debug for Identity","synthetic":false,"types":["tower_layer::identity::Identity"]},{"text":"impl<Inner, Outer> Debug for Stack<Inner, Outer> where
    Inner: Debug,
    Outer: Debug
","synthetic":false,"types":["tower_layer::stack::Stack"]}]; +implementors["tower_test"] = [{"text":"impl Debug for Closed","synthetic":false,"types":["tower_test::mock::error::Closed"]},{"text":"impl<T: Debug> Debug for ResponseFuture<T>","synthetic":false,"types":["tower_test::mock::future::ResponseFuture"]},{"text":"impl<T: Debug> Debug for Spawn<T>","synthetic":false,"types":["tower_test::mock::spawn::Spawn"]},{"text":"impl<T: Debug, U: Debug> Debug for Mock<T, U>","synthetic":false,"types":["tower_test::mock::Mock"]},{"text":"impl<T: Debug, U: Debug> Debug for Handle<T, U>","synthetic":false,"types":["tower_test::mock::Handle"]},{"text":"impl<T: Debug> Debug for SendResponse<T>","synthetic":false,"types":["tower_test::mock::SendResponse"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Display.js b/implementors/core/fmt/trait.Display.js new file mode 100644 index 0000000..aaffd1a --- /dev/null +++ b/implementors/core/fmt/trait.Display.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["tower_test"] = [{"text":"impl Display for Closed","synthetic":false,"types":["tower_test::mock::error::Closed"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/future/future/trait.Future.js b/implementors/core/future/future/trait.Future.js new file mode 100644 index 0000000..9d76883 --- /dev/null +++ b/implementors/core/future/future/trait.Future.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["tower_test"] = [{"text":"impl<T> Future for ResponseFuture<T>","synthetic":false,"types":["tower_test::mock::future::ResponseFuture"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Freeze.js b/implementors/core/marker/trait.Freeze.js new file mode 100644 index 0000000..ec063eb --- /dev/null +++ b/implementors/core/marker/trait.Freeze.js @@ -0,0 +1,5 @@ +(function() {var implementors = {}; +implementors["tower"] = [{"text":"impl<L> Freeze for ServiceBuilder<L> where
    L: Freeze, 
","synthetic":true,"types":["tower::builder::ServiceBuilder"]}]; +implementors["tower_layer"] = [{"text":"impl Freeze for Identity","synthetic":true,"types":["tower_layer::identity::Identity"]},{"text":"impl<Inner, Outer> Freeze for Stack<Inner, Outer> where
    Inner: Freeze,
    Outer: Freeze, 
","synthetic":true,"types":["tower_layer::stack::Stack"]}]; +implementors["tower_test"] = [{"text":"impl<T, U> !Freeze for Mock<T, U>","synthetic":true,"types":["tower_test::mock::Mock"]},{"text":"impl<T, U> Freeze for Handle<T, U>","synthetic":true,"types":["tower_test::mock::Handle"]},{"text":"impl<T> Freeze for SendResponse<T>","synthetic":true,"types":["tower_test::mock::SendResponse"]},{"text":"impl Freeze for Closed","synthetic":true,"types":["tower_test::mock::error::Closed"]},{"text":"impl<T> Freeze for ResponseFuture<T>","synthetic":true,"types":["tower_test::mock::future::ResponseFuture"]},{"text":"impl<T> Freeze for Spawn<T> where
    T: Freeze, 
","synthetic":true,"types":["tower_test::mock::spawn::Spawn"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Send.js b/implementors/core/marker/trait.Send.js new file mode 100644 index 0000000..43ac582 --- /dev/null +++ b/implementors/core/marker/trait.Send.js @@ -0,0 +1,5 @@ +(function() {var implementors = {}; +implementors["tower"] = [{"text":"impl<L> Send for ServiceBuilder<L> where
    L: Send
","synthetic":true,"types":["tower::builder::ServiceBuilder"]}]; +implementors["tower_layer"] = [{"text":"impl Send for Identity","synthetic":true,"types":["tower_layer::identity::Identity"]},{"text":"impl<Inner, Outer> Send for Stack<Inner, Outer> where
    Inner: Send,
    Outer: Send
","synthetic":true,"types":["tower_layer::stack::Stack"]}]; +implementors["tower_test"] = [{"text":"impl<T, U> Send for Mock<T, U> where
    T: Send,
    U: Send
","synthetic":true,"types":["tower_test::mock::Mock"]},{"text":"impl<T, U> Send for Handle<T, U> where
    T: Send,
    U: Send
","synthetic":true,"types":["tower_test::mock::Handle"]},{"text":"impl<T> Send for SendResponse<T> where
    T: Send
","synthetic":true,"types":["tower_test::mock::SendResponse"]},{"text":"impl Send for Closed","synthetic":true,"types":["tower_test::mock::error::Closed"]},{"text":"impl<T> Send for ResponseFuture<T> where
    T: Send
","synthetic":true,"types":["tower_test::mock::future::ResponseFuture"]},{"text":"impl<T> Send for Spawn<T> where
    T: Send
","synthetic":true,"types":["tower_test::mock::spawn::Spawn"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Sync.js b/implementors/core/marker/trait.Sync.js new file mode 100644 index 0000000..6036c41 --- /dev/null +++ b/implementors/core/marker/trait.Sync.js @@ -0,0 +1,5 @@ +(function() {var implementors = {}; +implementors["tower"] = [{"text":"impl<L> Sync for ServiceBuilder<L> where
    L: Sync
","synthetic":true,"types":["tower::builder::ServiceBuilder"]}]; +implementors["tower_layer"] = [{"text":"impl Sync for Identity","synthetic":true,"types":["tower_layer::identity::Identity"]},{"text":"impl<Inner, Outer> Sync for Stack<Inner, Outer> where
    Inner: Sync,
    Outer: Sync
","synthetic":true,"types":["tower_layer::stack::Stack"]}]; +implementors["tower_test"] = [{"text":"impl<T, U> Sync for Mock<T, U> where
    T: Send,
    U: Send
","synthetic":true,"types":["tower_test::mock::Mock"]},{"text":"impl<T, U> Sync for Handle<T, U> where
    T: Send,
    U: Send
","synthetic":true,"types":["tower_test::mock::Handle"]},{"text":"impl<T> Sync for SendResponse<T> where
    T: Send
","synthetic":true,"types":["tower_test::mock::SendResponse"]},{"text":"impl Sync for Closed","synthetic":true,"types":["tower_test::mock::error::Closed"]},{"text":"impl<T> Sync for ResponseFuture<T> where
    T: Send
","synthetic":true,"types":["tower_test::mock::future::ResponseFuture"]},{"text":"impl<T> Sync for Spawn<T> where
    T: Sync
","synthetic":true,"types":["tower_test::mock::spawn::Spawn"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Unpin.js b/implementors/core/marker/trait.Unpin.js new file mode 100644 index 0000000..31028b4 --- /dev/null +++ b/implementors/core/marker/trait.Unpin.js @@ -0,0 +1,5 @@ +(function() {var implementors = {}; +implementors["tower"] = [{"text":"impl<L> Unpin for ServiceBuilder<L> where
    L: Unpin
","synthetic":true,"types":["tower::builder::ServiceBuilder"]}]; +implementors["tower_layer"] = [{"text":"impl Unpin for Identity","synthetic":true,"types":["tower_layer::identity::Identity"]},{"text":"impl<Inner, Outer> Unpin for Stack<Inner, Outer> where
    Inner: Unpin,
    Outer: Unpin
","synthetic":true,"types":["tower_layer::stack::Stack"]}]; +implementors["tower_test"] = [{"text":"impl<T, U> Unpin for Mock<T, U>","synthetic":true,"types":["tower_test::mock::Mock"]},{"text":"impl<T, U> Unpin for Handle<T, U>","synthetic":true,"types":["tower_test::mock::Handle"]},{"text":"impl<T> Unpin for SendResponse<T>","synthetic":true,"types":["tower_test::mock::SendResponse"]},{"text":"impl Unpin for Closed","synthetic":true,"types":["tower_test::mock::error::Closed"]},{"text":"impl<T> Unpin for Spawn<T> where
    T: Unpin
","synthetic":true,"types":["tower_test::mock::spawn::Spawn"]},{"text":"impl<'pin, T> Unpin for ResponseFuture<T> where
    __ResponseFuture<'pin, T>: Unpin
","synthetic":false,"types":["tower_test::mock::future::ResponseFuture"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/ops/drop/trait.Drop.js b/implementors/core/ops/drop/trait.Drop.js new file mode 100644 index 0000000..1cfeb68 --- /dev/null +++ b/implementors/core/ops/drop/trait.Drop.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["tower_test"] = [{"text":"impl<T, U> Drop for Mock<T, U>","synthetic":false,"types":["tower_test::mock::Mock"]},{"text":"impl<T, U> Drop for Handle<T, U>","synthetic":false,"types":["tower_test::mock::Handle"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/pin_project/__private/trait.PinnedDrop.js b/implementors/pin_project/__private/trait.PinnedDrop.js new file mode 100644 index 0000000..a431a59 --- /dev/null +++ b/implementors/pin_project/__private/trait.PinnedDrop.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["tower_test"] = [{"text":"impl<T> PinnedDrop for ResponseFuture<T>","synthetic":false,"types":["tower_test::mock::future::ResponseFuture"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/pin_project/trait.UnsafeUnpin.js b/implementors/pin_project/trait.UnsafeUnpin.js new file mode 100644 index 0000000..dcf0e5b --- /dev/null +++ b/implementors/pin_project/trait.UnsafeUnpin.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["tower_test"] = [{"text":"impl<T> UnsafeUnpin for ResponseFuture<T>","synthetic":false,"types":["tower_test::mock::future::ResponseFuture"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/error/trait.Error.js b/implementors/std/error/trait.Error.js new file mode 100644 index 0000000..596b035 --- /dev/null +++ b/implementors/std/error/trait.Error.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["tower_test"] = [{"text":"impl Error for Closed","synthetic":false,"types":["tower_test::mock::error::Closed"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/panic/trait.RefUnwindSafe.js b/implementors/std/panic/trait.RefUnwindSafe.js new file mode 100644 index 0000000..81fc835 --- /dev/null +++ b/implementors/std/panic/trait.RefUnwindSafe.js @@ -0,0 +1,5 @@ +(function() {var implementors = {}; +implementors["tower"] = [{"text":"impl<L> RefUnwindSafe for ServiceBuilder<L> where
    L: RefUnwindSafe
","synthetic":true,"types":["tower::builder::ServiceBuilder"]}]; +implementors["tower_layer"] = [{"text":"impl RefUnwindSafe for Identity","synthetic":true,"types":["tower_layer::identity::Identity"]},{"text":"impl<Inner, Outer> RefUnwindSafe for Stack<Inner, Outer> where
    Inner: RefUnwindSafe,
    Outer: RefUnwindSafe
","synthetic":true,"types":["tower_layer::stack::Stack"]}]; +implementors["tower_test"] = [{"text":"impl<T, U> RefUnwindSafe for Mock<T, U>","synthetic":true,"types":["tower_test::mock::Mock"]},{"text":"impl<T, U> !RefUnwindSafe for Handle<T, U>","synthetic":true,"types":["tower_test::mock::Handle"]},{"text":"impl<T> !RefUnwindSafe for SendResponse<T>","synthetic":true,"types":["tower_test::mock::SendResponse"]},{"text":"impl RefUnwindSafe for Closed","synthetic":true,"types":["tower_test::mock::error::Closed"]},{"text":"impl<T> !RefUnwindSafe for ResponseFuture<T>","synthetic":true,"types":["tower_test::mock::future::ResponseFuture"]},{"text":"impl<T> !RefUnwindSafe for Spawn<T>","synthetic":true,"types":["tower_test::mock::spawn::Spawn"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/std/panic/trait.UnwindSafe.js b/implementors/std/panic/trait.UnwindSafe.js new file mode 100644 index 0000000..8620868 --- /dev/null +++ b/implementors/std/panic/trait.UnwindSafe.js @@ -0,0 +1,5 @@ +(function() {var implementors = {}; +implementors["tower"] = [{"text":"impl<L> UnwindSafe for ServiceBuilder<L> where
    L: UnwindSafe
","synthetic":true,"types":["tower::builder::ServiceBuilder"]}]; +implementors["tower_layer"] = [{"text":"impl UnwindSafe for Identity","synthetic":true,"types":["tower_layer::identity::Identity"]},{"text":"impl<Inner, Outer> UnwindSafe for Stack<Inner, Outer> where
    Inner: UnwindSafe,
    Outer: UnwindSafe
","synthetic":true,"types":["tower_layer::stack::Stack"]}]; +implementors["tower_test"] = [{"text":"impl<T, U> UnwindSafe for Mock<T, U>","synthetic":true,"types":["tower_test::mock::Mock"]},{"text":"impl<T, U> !UnwindSafe for Handle<T, U>","synthetic":true,"types":["tower_test::mock::Handle"]},{"text":"impl<T> !UnwindSafe for SendResponse<T>","synthetic":true,"types":["tower_test::mock::SendResponse"]},{"text":"impl UnwindSafe for Closed","synthetic":true,"types":["tower_test::mock::error::Closed"]},{"text":"impl<T> !UnwindSafe for ResponseFuture<T>","synthetic":true,"types":["tower_test::mock::future::ResponseFuture"]},{"text":"impl<T> !UnwindSafe for Spawn<T>","synthetic":true,"types":["tower_test::mock::spawn::Spawn"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/tower/layer/trait.Layer.js b/implementors/tower/layer/trait.Layer.js new file mode 100644 index 0000000..b32af6a --- /dev/null +++ b/implementors/tower/layer/trait.Layer.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["tower"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/tower/trait.Service.js b/implementors/tower/trait.Service.js new file mode 100644 index 0000000..b32af6a --- /dev/null +++ b/implementors/tower/trait.Service.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["tower"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/tower_layer/trait.Layer.js b/implementors/tower_layer/trait.Layer.js new file mode 100644 index 0000000..d2dc46a --- /dev/null +++ b/implementors/tower_layer/trait.Layer.js @@ -0,0 +1,3 @@ +(function() {var implementors = {}; +implementors["tower_layer"] = []; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/tower_service/trait.Service.js b/implementors/tower_service/trait.Service.js new file mode 100644 index 0000000..49eaee9 --- /dev/null +++ b/implementors/tower_service/trait.Service.js @@ -0,0 +1,4 @@ +(function() {var implementors = {}; +implementors["tower_service"] = []; +implementors["tower_test"] = [{"text":"impl<T, U> Service<T> for Mock<T, U>","synthetic":false,"types":["tower_test::mock::Mock"]}]; +if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/light.css b/light.css new file mode 100644 index 0000000..78ed8dd --- /dev/null +++ b/light.css @@ -0,0 +1 @@ + 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;}.invisible{background:rgba(0,0,0,0);}.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;}.sidebar .version{border-bottom-color:#DDD;}.sidebar-title{border-top-color:#777;border-bottom-color:#777;}.block a:hover{background:#F5F5F5;}.line-numbers span{color:#c67e2d;}.line-numbers .line-highlighted{background-color:#f6fdb0 !important;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom-color:#ddd;}.docblock table,.docblock table td,.docblock table th{border-color:#ddd;}.content .method .where,.content .fn .where,.content .where.fmt-newline{color:#4E4C4C;}.content .highlighted{color:#000 !important;background-color:#ccc;}.content .highlighted a,.content .highlighted span{color:#000 !important;}.content .highlighted.trait{background-color:#c7b6ff;}.content .highlighted.traitalias{background-color:#c7b6ff;}.content .highlighted.mod,.content .highlighted.externcrate{background-color:#afc6e4;}.content .highlighted.enum{background-color:#b4d1b9;}.content .highlighted.struct{background-color:#e7b1a0;}.content .highlighted.union{background-color:#b7bd49;}.content .highlighted.fn,.content .highlighted.method,.content .highlighted.tymethod{background-color:#c6afb3;}.content .highlighted.type{background-color:#ffc891;}.content .highlighted.foreigntype{background-color:#f5c4ff;}.content .highlighted.attr,.content .highlighted.derive,.content .highlighted.macro{background-color:#8ce488;}.content .highlighted.constant,.content .highlighted.static{background-color:#c3e0ff;}.content .highlighted.primitive{background-color:#9aecff;}.content .highlighted.keyword{background-color:#f99650;}.content .stability::before{color:#ccc;}.content span.enum,.content a.enum,.block a.current.enum{color:#508157;}.content span.struct,.content a.struct,.block a.current.struct{color:#ad448e;}.content span.type,.content a.type,.block a.current.type{color:#ba5d00;}.content span.foreigntype,.content a.foreigntype,.block a.current.foreigntype{color:#cd00e2;}.content span.attr,.content a.attr,.block a.current.attr,.content span.derive,.content a.derive,.block a.current.derive,.content span.macro,.content a.macro,.block a.current.macro{color:#068000;}.content span.union,.content a.union,.block a.current.union{color:#767b27;}.content span.constant,.content a.constant,.block a.current.constant,.content span.static,.content a.static,.block a.current.static{color:#546e8a;}.content span.primitive,.content a.primitive,.block a.current.primitive{color:#2c8093;}.content span.externcrate,.content span.mod,.content a.mod,.block a.current.mod{color:#4d76ae;}.content span.trait,.content a.trait,.block a.current.trait{color:#7c5af3;}.content span.traitalias,.content a.traitalias,.block a.current.traitalias{color:#6841f1;}.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:#9a6e31;}.content span.keyword,.content a.keyword,.block a.current.keyword{color:#de5249;}pre.rust .comment{color:#8E908C;}pre.rust .doccomment{color:#4D4D4C;}nav:not(.sidebar){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:not(.type-decl) a:not(.srclink):not(.test-arrow),.docblock-short a:not(.srclink):not(.test-arrow),.stability a{color:#3873AD;}.stab.internal a{color:#304FFE;}a.test-arrow{color:#f5f5f5;}.collapse-toggle{color:#999;}#crate-search{color:#555;background-color:white;border-color:#e0e0e0;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input{color:#555;background-color:white;box-shadow:0 0 0 1px #e0e0e0,0 0 0 2px transparent;}.search-input:focus{border-color:#66afe9;}.search-focus:disabled{background-color:#e6e6e6;}#crate-search+.search-input:focus{box-shadow:0 0 8px #078dd8;}.module-item .stab{color:#000;}.stab.unstable{background:#FFF5D6;border-color:#FFC600;}.stab.internal{background:#FFB9B3;border-color:#B71C1C;}.stab.deprecated{background:#F3DFFF;border-color:#7F0087;}.stab.portability{background:#C4ECFF;border-color:#7BA5DB;}.stab.portability>code{color:#000;}#help>div{background:#e9e9e9;border-color:#bfbfbf;}.since{color:grey;}tr.result span.primitive::after,tr.result span.keyword::after{color:black;}.line-numbers :target{background-color:transparent;}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;}.example-wrap>pre.line-number{border-color:#c7c7c7;}a.test-arrow{background-color:rgba(78,139,202,0.2);}a.test-arrow:hover{background-color:#4e8bca;}.toggle-label{color:#999;}:target>code,:target>.in-band{background:#FDFFD3;}pre.compile_fail{border-left:2px solid rgba(255,0,0,.4);}pre.compile_fail:hover,.information:hover+pre.compile_fail{border-left:2px solid #f00;}pre.ignore{border-left:2px solid rgba(255,142,0,.4);}pre.ignore:hover,.information:hover+pre.ignore{border-left:2px solid #ff9200;}.tooltip.compile_fail{color:rgba(255,0,0,.3);}.information>.compile_fail:hover{color:#f00;}.tooltip.ignore{color:rgba(255,142,0,.3);}.information>.ignore:hover{color:rgba(255,142,0,1);}.search-failed a{color:#0089ff;}.tooltip .tooltiptext{background-color:black;color:#fff;}.tooltip .tooltiptext::after{border-color:transparent black transparent transparent;}#titles>div:not(.selected){background-color:#e6e6e6;border-top-color:#e6e6e6;}#titles>div:hover,#titles>div.selected{border-top-color:#0089ff;}#titles>div>div.count{color:#888;}@media (max-width:700px){.sidebar-menu{background-color:#F1F1F1;border-bottom-color:#e0e0e0;border-right-color:#e0e0e0;}.sidebar-elems{background-color:#F1F1F1;border-right-color:#000;}#sidebar-filler{background-color:#F1F1F1;border-bottom-color:#e0e0e0;}}kbd{color:#000;background-color:#fafbfc;border-color:#d1d5da;border-bottom-color:#c6cbd1;box-shadow-color:#c6cbd1;}#theme-picker,#settings-menu{border-color:#e0e0e0;background-color:#fff;}#theme-picker:hover,#theme-picker:focus,#settings-menu:hover,#settings-menu:focus{border-color:#717171;}#theme-choices{border-color:#ccc;background-color:#fff;}#theme-choices>button:not(:first-child){border-top-color:#e0e0e0;}#theme-choices>button:hover,#theme-choices>button:focus{background-color:#eee;}@media (max-width:700px){#theme-picker{background:#fff;}}#all-types{background-color:#fff;}#all-types:hover{background-color:#f9f9f9;}.search-results td span.alias{color:#000;}.search-results td span.grey{color:#999;}#sidebar-toggle{background-color:#F1F1F1;}#sidebar-toggle:hover{background-color:#E0E0E0;}#source-sidebar{background-color:#F1F1F1;}#source-sidebar>.title{border-bottom-color:#ccc;}div.files>a:hover,div.name:hover{background-color:#E0E0E0;}div.files>.selected{background-color:#fff;}.setting-line>.title{border-bottom-color:#D5D5D5;} \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 0000000..b912f0c --- /dev/null +++ b/main.js @@ -0,0 +1,7 @@ +if(!String.prototype.startsWith){String.prototype.startsWith=function(searchString,position){position=position||0;return this.indexOf(searchString,position)===position}}if(!String.prototype.endsWith){String.prototype.endsWith=function(suffix,length){var l=length||this.length;return this.indexOf(suffix,l-suffix.length)!==-1}}if(!DOMTokenList.prototype.add){DOMTokenList.prototype.add=function(className){if(className&&!hasClass(this,className)){if(this.className&&this.className.length>0){this.className+=" "+className}else{this.className=className}}}}if(!DOMTokenList.prototype.remove){DOMTokenList.prototype.remove=function(className){if(className&&this.className){this.className=(" "+this.className+" ").replace(" "+className+" "," ").trim()}}}function getSearchInput(){return document.getElementsByClassName("search-input")[0]}function getSearchElement(){return document.getElementById("search")}(function(){"use strict";var itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias"];var disableShortcuts=getCurrentValue("rustdoc-disable-shortcuts")==="true";var search_input=getSearchInput();var currentTab=0;var titleBeforeSearch=document.title;function getPageId(){var id=document.location.href.split("#")[1];if(id){return id.split("?")[0].split("&")[0]}return null}function showSidebar(){var elems=document.getElementsByClassName("sidebar-elems")[0];if(elems){addClass(elems,"show-it")}var sidebar=document.getElementsByClassName("sidebar")[0];if(sidebar){addClass(sidebar,"mobile");var filler=document.getElementById("sidebar-filler");if(!filler){var div=document.createElement("div");div.id="sidebar-filler";sidebar.appendChild(div)}}var themePickers=document.getElementsByClassName("theme-picker");if(themePickers&&themePickers.length>0){themePickers[0].style.display="none"}}function hideSidebar(){var elems=document.getElementsByClassName("sidebar-elems")[0];if(elems){removeClass(elems,"show-it")}var sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"mobile");var filler=document.getElementById("sidebar-filler");if(filler){filler.remove()}document.getElementsByTagName("body")[0].style.marginTop="";var themePickers=document.getElementsByClassName("theme-picker");if(themePickers&&themePickers.length>0){themePickers[0].style.display=null}}function showSearchResults(search){if(search===null||typeof search==='undefined'){search=getSearchElement()}addClass(main,"hidden");removeClass(search,"hidden")}function hideSearchResults(search){if(search===null||typeof search==='undefined'){search=getSearchElement()}addClass(search,"hidden");removeClass(main,"hidden")}var TY_PRIMITIVE=itemTypes.indexOf("primitive");var TY_KEYWORD=itemTypes.indexOf("keyword");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 window.history&&typeof window.history.pushState==="function"}function isHidden(elem){return elem.offsetHeight===0}var main=document.getElementById("main");var savedHash="";function handleHashes(ev){var search=getSearchElement();if(ev!==null&&search&&!hasClass(search,"hidden")&&ev.newURL){hideSearchResults(search);var hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(hash,"","?search=#"+hash)}var elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}if(savedHash!==window.location.hash){savedHash=window.location.hash;if(savedHash.length===0){return}var elem=document.getElementById(savedHash.slice(1));if(!elem||!isHidden(elem)){return}var parent=elem.parentNode;if(parent&&hasClass(parent,"impl-items")){onEachLazy(parent.getElementsByClassName("collapsed"),function(e){if(e.parentNode===parent){e.click();return true}});if(isHidden(elem)){if(hasClass(parent.lastElementChild,"collapse-toggle")){parent.lastElementChild.click()}}}}}function highlightSourceLines(match,ev){if(typeof match==="undefined"){hideSidebar();match=window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/)}if(!match){return}var from=parseInt(match[1],10);var to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to0){collapseDocs(collapses[0],"show")}}}}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 getHelpElement(){return document.getElementById("help")}function displayHelp(display,ev,help){var help=help?help:getHelpElement();if(display===true){if(hasClass(help,"hidden")){ev.preventDefault();removeClass(help,"hidden");addClass(document.body,"blur")}}else if(hasClass(help,"hidden")===false){ev.preventDefault();addClass(help,"hidden");removeClass(document.body,"blur")}}function handleEscape(ev){var help=getHelpElement();var search=getSearchElement();if(hasClass(help,"hidden")===false){displayHelp(false,ev,help)}else if(hasClass(search,"hidden")===false){ev.preventDefault();hideSearchResults(search);document.title=titleBeforeSearch}defocusSearchBar()}function handleShortcut(ev){if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts===true){return}if(document.activeElement.tagName==="INPUT"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":displayHelp(false,ev);ev.preventDefault();focusSearchBar();break;case"+":case"-":ev.preventDefault();toggleAllDocs();break;case"?":if(ev.shiftKey){displayHelp(true,ev)}break}}}function findParentElement(elem,tagName){do{if(elem&&elem.tagName===tagName){return elem}elem=elem.parentNode}while(elem);return null}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);var handleSourceHighlight=(function(){var prev_line_id=0;var set_fragment=function(name){var x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSourceLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return function(ev){var cur_line_id=parseInt(ev.target.id,10);ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){var tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}})();document.addEventListener("click",function(ev){if(hasClass(ev.target,"collapse-toggle")){collapseDocs(ev.target,"toggle")}else if(hasClass(ev.target.parentNode,"collapse-toggle")){collapseDocs(ev.target.parentNode,"toggle")}else if(ev.target.tagName==="SPAN"&&hasClass(ev.target.parentNode,"line-numbers")){handleSourceHighlight(ev)}else if(hasClass(getHelpElement(),"hidden")===false){var help=getHelpElement();var is_inside_help_popup=ev.target!==help&&help.contains(ev.target);if(is_inside_help_popup===false){addClass(help,"hidden");removeClass(document.body,"blur")}}else{var a=findParentElement(ev.target,"A");if(a&&a.hash){expandSection(a.hash.replace(/^#/,""))}}});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-1){var obj=searchIndex[results[i].id];obj.lev=results[i].lev;if(isType!==true||obj.type){var res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}}return out}function sortResults(results,isType){var ar=[];for(var entry in results){if(results.hasOwnProperty(entry)){ar.push(results[entry])}}results=ar;var i;var nresults=results.length;for(i=0;ib?+1:-1)}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});var length=results.length;for(i=0;i"));return{name:val.substring(0,val.indexOf("<")),generics:values.split(/\s*,\s*/),}}return{name:val,generics:[],}}function checkGenerics(obj,val){var lev_distance=MAX_LEV_DISTANCE+1;if(val.generics.length>0){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=obj[GENERICS_DATA].slice(0);var total=0;var done=0;var vlength=val.generics.length;for(var y=0;yGENERICS_DATA&&obj[GENERICS_DATA].length>=val.generics.length){var elems=obj[GENERICS_DATA].slice(0);var allFound=true;for(var y=0;allFound===true&&yGENERICS_DATA&&obj[GENERICS_DATA].length!==0){var tmp_lev=checkGenerics(obj,val);if(tmp_lev<=MAX_LEV_DISTANCE){return tmp_lev}}else{return 0}}if(literalSearch===true){if(obj.length>GENERICS_DATA&&obj[GENERICS_DATA].length>0){var length=obj[GENERICS_DATA].length;for(x=0;xGENERICS_DATA&&obj[GENERICS_DATA].length>0){var olength=obj[GENERICS_DATA].length;for(x=0;x0){var length=obj.type[INPUTS_DATA].length;for(var i=0;iOUTPUT_DATA){var ret=obj.type[OUTPUT_DATA];if(!obj.type[OUTPUT_DATA].length){ret=[ret]}for(var x=0;xlength){return MAX_LEV_DISTANCE+1}for(var i=0;ilength){break}var lev_total=0;var aborted=false;for(var x=0;xMAX_LEV_DISTANCE){aborted=true;break}lev_total+=lev}if(aborted===false){ret_lev=Math.min(ret_lev,Math.round(lev_total/clength))}}return ret_lev}function typePassesFilter(filter,type){if(filter<0)return true;if(filter===type)return true;var name=itemTypes[type];switch(itemTypes[filter]){case"constant":return(name=="associatedconstant");case"fn":return(name=="method"||name=="tymethod");case"type":return(name=="primitive"||name=="keyword")}return false}function generateId(ty){if(ty.parent&&ty.parent.name){return itemTypes[ty.ty]+ty.path+ty.parent.name+ty.name}return itemTypes[ty.ty]+ty.path+ty.name}var nSearchWords=searchWords.length;var i;var ty;var fullId;var returned;var in_args;if((val.charAt(0)==="\""||val.charAt(0)==="'")&&val.charAt(val.length-1)===val.charAt(0)){val=extractGenerics(val.substr(1,val.length-2));for(i=0;i")>-1){var trimmer=function(s){return s.trim()};var parts=val.split("->").map(trimmer);var input=parts[0];var inputs=input.split(",").map(trimmer).sort();for(i=0;iOUTPUT_DATA?type[OUTPUT_DATA].name:"";returned=checkReturned(ty,output,true);if(output.name==="*"||returned===true){in_args=false;var is_module=false;if(input==="*"){is_module=true}else{var allFound=true;for(var it=0;allFound===true&&it1?paths.length-1:1);var lev;var lev_distance;for(j=0;j1){lev=checkPath(contains,paths[paths.length-1],ty);if(lev>MAX_LEV_DISTANCE){continue}else if(lev>0){lev_add=lev/10}}returned=MAX_LEV_DISTANCE+1;in_args=MAX_LEV_DISTANCE+1;var index=-1;lev=MAX_LEV_DISTANCE+1;fullId=generateId(ty);if(searchWords[j].indexOf(split[i])>-1||searchWords[j].indexOf(val)>-1||searchWords[j].replace(/_/g,"").indexOf(val)>-1){if(typePassesFilter(typeFilter,ty.ty)&&results[fullId]===undefined){index=searchWords[j].replace(/_/g,"").indexOf(val)}}if((lev=levenshtein(searchWords[j],val))<=MAX_LEV_DISTANCE){if(typePassesFilter(typeFilter,ty.ty)===false){lev=MAX_LEV_DISTANCE+1}else{lev+=1}}if((in_args=findArg(ty,valGenerics))<=MAX_LEV_DISTANCE){if(typePassesFilter(typeFilter,ty.ty)===false){in_args=MAX_LEV_DISTANCE+1}}if((returned=checkReturned(ty,valGenerics))<=MAX_LEV_DISTANCE){if(typePassesFilter(typeFilter,ty.ty)===false){returned=MAX_LEV_DISTANCE+1}}lev+=lev_add;if(lev>0&&val.length>3&&searchWords[j].indexOf(val)>-1){if(val.length<6){lev-=1}else{lev=0}}if(in_args<=MAX_LEV_DISTANCE){if(results_in_args[fullId]===undefined){results_in_args[fullId]={id:j,index:index,lev:in_args,}}results_in_args[fullId].lev=Math.min(results_in_args[fullId].lev,in_args)}if(returned<=MAX_LEV_DISTANCE){if(results_returned[fullId]===undefined){results_returned[fullId]={id:j,index:index,lev:returned,}}results_returned[fullId].lev=Math.min(results_returned[fullId].lev,returned)}if(index!==-1||lev<=MAX_LEV_DISTANCE){if(index!==-1&&paths.length<2){lev=0}if(results[fullId]===undefined){results[fullId]={id:j,index:index,lev:lev,}}results[fullId].lev=Math.min(results[fullId].lev,lev)}}}var ret={"in_args":sortResults(results_in_args,true),"returned":sortResults(results_returned,true),"others":sortResults(results),};if(ALIASES&&ALIASES[window.currentCrate]&&ALIASES[window.currentCrate][query.raw]){var aliases=ALIASES[window.currentCrate][query.raw];for(i=0;iMAX_RESULTS){ret.others.pop()}}}return ret}function validateResult(name,path,keys,parent){for(var i=0;i-1||path.indexOf(keys[i])>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(keys[i])>-1)||levenshtein(name,keys[i])<=MAX_LEV_DISTANCE)){return false}}return true}function getQuery(raw){var matches,type,query;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;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){hideSearchResults();document.location.href=dst.href}};var mouseover_func=function(e){var el=e.target;while(el.tagName!=="TR"){el=el.parentNode}clearTimeout(hoverTimeout);hoverTimeout=setTimeout(function(){onEachLazy(document.getElementsByClassName("search-results"),function(e){onEachLazy(e.getElementsByClassName("result"),function(i_e){removeClass(i_e,"highlighted")})});addClass(el,"highlighted")},20)};onEachLazy(document.getElementsByClassName("search-results"),function(e){onEachLazy(e.getElementsByClassName("result"),function(i_e){i_e.onclick=click_func;i_e.onmouseover=mouseover_func})});search_input.onkeydown=function(e){var actives=[[],[],[]];var current=0;onEachLazy(document.getElementById("results").childNodes,function(e){onEachLazy(e.getElementsByClassName("highlighted"),function(e){actives[current].push(e)});current+=1});if(e.which===38){if(!actives[currentTab].length||!actives[currentTab][0].previousElementSibling){return}addClass(actives[currentTab][0].previousElementSibling,"highlighted");removeClass(actives[currentTab][0],"highlighted")}else if(e.which===40){if(!actives[currentTab].length){var results=document.getElementById("results").childNodes;if(results.length>0){var res=results[currentTab].getElementsByClassName("result");if(res.length>0){addClass(res[0],"highlighted")}}}else if(actives[currentTab][0].nextElementSibling){addClass(actives[currentTab][0].nextElementSibling,"highlighted");removeClass(actives[currentTab][0],"highlighted")}}else if(e.which===13){if(actives[currentTab].length){document.location.href=actives[currentTab][0].getElementsByTagName("a")[0].href}}else if(e.which===9){if(e.shiftKey){printTab(currentTab>0?currentTab-1:2)}else{printTab(currentTab>1?0:currentTab+1)}e.preventDefault()}else if(e.which===16){}else if(actives[currentTab].length>0){removeClass(actives[currentTab][0],"highlighted")}}}function buildHrefAndPath(item){var displayPath;var href;var type=itemTypes[item.ty];var name=item.name;var path=item.path;if(type==="mod"){displayPath=path+"::";href=rootPath+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="primitive"||type==="keyword"){displayPath="";href=rootPath+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];var pageType=parentType;var pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){var splitPath=item.path.split("::");var enumName=splitPath.pop();path=splitPath.join("::");displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="#variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}href=rootPath+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=rootPath+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function escape(content){var h1=document.createElement("h1");h1.textContent=content;return h1.innerHTML}function pathSplitter(path){var tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){var extraStyle="";if(display===false){extraStyle=" style=\"display: none;\""}var output="";var duplicates={};var length=0;if(array.length>0){output="";array.forEach(function(item){var name,type;name=item.name;type=itemTypes[item.ty];if(item.is_alias!==true){if(duplicates[item.fullPath]){return}duplicates[item.fullPath]=true}length+=1;output+=""});output+="
"+""+(item.is_alias===true?(""+item.alias+"  - see "):"")+item.displayPath+""+name+""+""+""+escape(item.desc)+" 
"}else{output="
No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:
"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){if(currentTab===tabNb){return"
"+text+"
("+nbElems+")
"}return"
"+text+"
("+nbElems+")
"}function showResults(results){if(results.others.length===1&&getCurrentValue("rustdoc-go-to-only-result")==="true"){var elem=document.createElement("a");elem.href=results.others[0].href;elem.style.display="none";document.body.appendChild(elem);elem.click()}var query=getQuery(search_input.value);currentResults=query.id;var ret_others=addTab(results.others,query);var ret_in_args=addTab(results.in_args,query,false);var ret_returned=addTab(results.returned,query,false);var output="

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

"+"
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"+ret_others[0]+ret_in_args[0]+ret_returned[0]+"
";var search=getSearchElement();search.innerHTML=output;showSearchResults(search);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;onEachLazy(search.getElementsByClassName("desc"),function(e){e.style.width=width+"px"});initSearchNav();var elems=document.getElementById("titles").childNodes;elems[0].onclick=function(){printTab(0)};elems[1].onclick=function(){printTab(1)};elems[2].onclick=function(){printTab(2)};printTab(currentTab)}function execSearch(query,searchWords,filterCrates){function getSmallest(arrays,positions,notDuplicates){var start=null;for(var it=0;itpositions[it]&&(start===null||start>arrays[it][positions[it]].lev)&&!notDuplicates[arrays[it][positions[it]].fullPath]){start=arrays[it][positions[it]].lev}}return start}function mergeArrays(arrays){var ret=[];var positions=[];var notDuplicates={};for(var x=0;xpositions[x]&&arrays[x][positions[x]].lev===smallest&&!notDuplicates[arrays[x][positions[x]].fullPath]){ret.push(arrays[x][positions[x]]);notDuplicates[arrays[x][positions[x]].fullPath]=true;positions[x]+=1}}}return ret}var queries=query.raw.split(",");var results={"in_args":[],"returned":[],"others":[],};for(var i=0;i1){return{"in_args":mergeArrays(results.in_args),"returned":mergeArrays(results.returned),"others":mergeArrays(results.others),}}else{return{"in_args":results.in_args[0],"returned":results.returned[0],"others":results.others[0],}}}function getFilterCrates(){var elem=document.getElementById("crate-search");if(elem&&elem.value!=="All crates"&&rawSearchIndex.hasOwnProperty(elem.value)){return elem.value}return undefined}function search(e,forced){var params=getQueryStringParams();var query=getQuery(search_input.value.trim());if(e){e.preventDefault()}if(query.query.length===0){return}if(forced!==true&&query.id===currentResults){if(query.query.length>0){putBackSearch(search_input)}return}document.title="Results for "+query.query+" - Rust";if(browserSupportsHistoryApi()){if(!history.state&&!params.search){history.pushState(query,"","?search="+encodeURIComponent(query.raw))}else{history.replaceState(query,"","?search="+encodeURIComponent(query.raw))}}var filterCrates=getFilterCrates();showResults(execSearch(query,index,filterCrates))}function buildIndex(rawSearchIndex){searchIndex=[];var searchWords=[];var i;for(var crate in rawSearchIndex){if(!rawSearchIndex.hasOwnProperty(crate)){continue}searchWords.push(crate);searchIndex.push({crate:crate,ty:1,name:crate,path:"",desc:rawSearchIndex[crate].doc,type:null,});var items=rawSearchIndex[crate].i;var paths=rawSearchIndex[crate].p;var len=paths.length;for(i=0;i0){search_input.value=params.search;search(e)}else{search_input.value="";hideSearchResults()}})}search()}index=buildIndex(rawSearchIndex);startSearch();if(rootPath==="../"||rootPath==="./"){var sidebar=document.getElementsByClassName("sidebar-elems")[0];if(sidebar){var div=document.createElement("div");div.className="block crate";div.innerHTML="

Crates

";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"+""+"
"+code.outerHTML+"
";list.appendChild(display)}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}function labelForToggleButton(sectionIsCollapsed){if(sectionIsCollapsed){return"+"}return"\u2212"}function onEveryMatchingChild(elem,className,func){if(elem&&className&&func){var length=elem.childNodes.length;var nodes=elem.childNodes;for(var i=0;i"+labelForToggleButton(sectionIsCollapsed)+"
]";return toggle}var toggle=createSimpleToggle(false);var hideMethodDocs=getCurrentValue("rustdoc-auto-hide-method-docs")==="true";var pageId=getPageId();var func=function(e){var next=e.nextElementSibling;if(!next){return}if(hasClass(next,"docblock")===true||(hasClass(next,"stability")===true&&hasClass(next.nextElementSibling,"docblock")===true)){var newToggle=toggle.cloneNode(true);insertAfter(newToggle,e.childNodes[e.childNodes.length-1]);if(hideMethodDocs===true&&hasClass(e,"method")===true){collapseDocs(newToggle,"hide",pageId)}}};var funcImpl=function(e){var next=e.nextElementSibling;if(next&&hasClass(next,"docblock")){next=next.nextElementSibling}if(!next){return}if(next.getElementsByClassName("method").length>0&&hasClass(e,"impl")){insertAfter(toggle.cloneNode(true),e.childNodes[e.childNodes.length-1])}};onEachLazy(document.getElementsByClassName("method"),func);onEachLazy(document.getElementsByClassName("associatedconstant"),func);onEachLazy(document.getElementsByClassName("impl"),funcImpl);var impl_call=function(){};if(hideMethodDocs===true){impl_call=function(e,newToggle,pageId){if(e.id.match(/^impl(?:-\d+)?$/)===null){if(hasClass(e,"impl")===true){collapseDocs(newToggle,"hide",pageId)}}}}var newToggle=document.createElement("a");newToggle.href="javascript:void(0)";newToggle.className="collapse-toggle hidden-default collapsed";newToggle.innerHTML="["+labelForToggleButton(true)+"] Show hidden undocumented items";function toggleClicked(){if(hasClass(this,"collapsed")){removeClass(this,"collapsed");onEachLazy(this.parentNode.getElementsByClassName("hidden"),function(x){if(hasClass(x,"content")===false){removeClass(x,"hidden");addClass(x,"x")}},true);this.innerHTML="["+labelForToggleButton(false)+"] Hide undocumented items"}else{addClass(this,"collapsed");onEachLazy(this.parentNode.getElementsByClassName("x"),function(x){if(hasClass(x,"content")===false){addClass(x,"hidden");removeClass(x,"x")}},true);this.innerHTML="["+labelForToggleButton(true)+"] Show hidden undocumented items"}}onEachLazy(document.getElementsByClassName("impl-items"),function(e){onEachLazy(e.getElementsByClassName("associatedconstant"),func);var hiddenElems=e.getElementsByClassName("hidden");var needToggle=false;var hlength=hiddenElems.length;for(var i=0;i0){inner[0].innerHTML="+"}}if(extraClass){addClass(wrapper,extraClass)}wrapper.appendChild(mainToggle);return wrapper}var currentType=document.getElementsByClassName("type-decl")[0];var className=null;if(currentType){currentType=currentType.getElementsByClassName("rust")[0];if(currentType){currentType.classList.forEach(function(item){if(item!=="main"){className=item;return true}})}}var showItemDeclarations=getCurrentValue("rustdoc-auto-hide-"+className);if(showItemDeclarations===null){if(className==="enum"||className==="macro"){showItemDeclarations="false"}else if(className==="struct"||className==="union"||className==="trait"){showItemDeclarations="true"}else{showItemDeclarations=getCurrentValue("rustdoc-auto-hide-declarations")}}showItemDeclarations=showItemDeclarations==="false";function buildToggleWrapper(e){if(hasClass(e,"autohide")){var wrap=e.previousElementSibling;if(wrap&&hasClass(wrap,"toggle-wrapper")){var inner_toggle=wrap.childNodes[0];var extra=e.childNodes[0].tagName==="H3";e.style.display="none";addClass(wrap,"collapsed");onEachLazy(inner_toggle.getElementsByClassName("inner"),function(e){e.innerHTML=labelForToggleButton(true)});onEachLazy(inner_toggle.getElementsByClassName("toggle-label"),function(e){e.style.display="inline-block";if(extra===true){i_e.innerHTML=" Show "+e.childNodes[0].innerHTML}})}}if(e.parentNode.id==="main"){var otherMessage="";var fontSize;var extraClass;if(hasClass(e,"type-decl")){fontSize="20px";otherMessage=" Show declaration";if(showItemDeclarations===false){extraClass="collapsed"}}else if(hasClass(e,"sub-variant")){otherMessage=" Show fields"}else if(hasClass(e,"non-exhaustive")){otherMessage=" This ";if(hasClass(e,"non-exhaustive-struct")){otherMessage+="struct"}else if(hasClass(e,"non-exhaustive-enum")){otherMessage+="enum"}else if(hasClass(e,"non-exhaustive-variant")){otherMessage+="enum variant"}else if(hasClass(e,"non-exhaustive-type")){otherMessage+="type"}otherMessage+=" is marked as non-exhaustive"}else if(hasClass(e.childNodes[0],"impl-items")){extraClass="marg-left"}e.parentNode.insertBefore(createToggle(otherMessage,fontSize,extraClass,hasClass(e,"type-decl")===false||showItemDeclarations===true),e);if(hasClass(e,"type-decl")===true&&showItemDeclarations===true){collapseDocs(e.previousSibling.childNodes[0],"toggle")}if(hasClass(e,"non-exhaustive")===true){collapseDocs(e.previousSibling.childNodes[0],"toggle")}}}onEachLazy(document.getElementsByClassName("docblock"),buildToggleWrapper);onEachLazy(document.getElementsByClassName("sub-variant"),buildToggleWrapper);function createToggleWrapper(tog){var span=document.createElement("span");span.className="toggle-label";span.style.display="none";span.innerHTML=" Expand attributes";tog.appendChild(span);var wrapper=document.createElement("div");wrapper.className="toggle-wrapper toggle-attributes";wrapper.appendChild(tog);return wrapper}var itemAttributesFunc=function(){};if(getCurrentValue("rustdoc-auto-hide-attributes")!=="false"){itemAttributesFunc=function(x){collapseDocs(x.previousSibling.childNodes[0],"toggle")}}var attributesToggle=createToggleWrapper(createSimpleToggle(false));onEachLazy(main.getElementsByClassName("attributes"),function(i_e){var attr_tog=attributesToggle.cloneNode(true);if(hasClass(i_e,"top-attr")===true){addClass(attr_tog,"top-attr")}i_e.parentNode.insertBefore(attr_tog,i_e);itemAttributesFunc(i_e)});var lineNumbersFunc=function(){};if(getCurrentValue("rustdoc-line-numbers")==="true"){lineNumbersFunc=function(x){var count=x.textContent.split("\n").length;var elems=[];for(var i=0;iLoading search results...";showSearchResults(search)}var sidebar_menu=document.getElementsByClassName("sidebar-menu")[0];if(sidebar_menu){sidebar_menu.onclick=function(){var sidebar=document.getElementsByClassName("sidebar")[0];if(hasClass(sidebar,"mobile")===true){hideSidebar()}else{showSidebar()}}}window.onresize=function(){hideSidebar()};autoCollapse(getPageId(),getCurrentValue("rustdoc-collapse")==="true");if(window.location.hash&&window.location.hash.length>0){expandSection(window.location.hash.replace(/^#/,""))}if(main){onEachLazy(main.getElementsByClassName("loading-content"),function(e){e.remove()});onEachLazy(main.childNodes,function(e){if(e.tagName==="H2"||e.tagName==="H3"){var nextTagName=e.nextElementSibling.tagName;if(nextTagName=="H2"||nextTagName=="H3"){e.nextElementSibling.style.display="flex"}else{e.nextElementSibling.style.display="block"}}})}function addSearchOptions(crates){var elem=document.getElementById("crate-search");if(!elem){return}var crates_text=[];if(Object.keys(crates).length>1){for(var crate in crates){if(crates.hasOwnProperty(crate)){crates_text.push(crate)}}}crates_text.sort(function(a,b){var lower_a=a.toLowerCase();var lower_b=b.toLowerCase();if(lower_alower_b){return 1}return 0});var savedCrate=getCurrentValue("rustdoc-saved-filter-crate");for(var i=0;i"
"+x[0]+"
"+x[1]+"
").join("");var div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";var infos=["Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given type.","Accepted types are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + * -> vec)","Search multiple things at once by splitting your query with comma (e.g., \ + str,u8 or String,struct:Vec,test)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");var div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;container.appendChild(div_shortcuts);container.appendChild(div_infos);popup.appendChild(container);insertAfter(popup,getSearchElement())}onHashChange(null);window.onhashchange=onHashChange;buildHelperPopup()}());function focusSearchBar(){getSearchInput().focus()}function defocusSearchBar(){getSearchInput().blur()} \ No newline at end of file diff --git a/normalize.css b/normalize.css new file mode 100644 index 0000000..45b6cb2 --- /dev/null +++ b/normalize.css @@ -0,0 +1,2 @@ +/*! 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} \ No newline at end of file diff --git a/noscript.css b/noscript.css new file mode 100644 index 0000000..351b41c --- /dev/null +++ b/noscript.css @@ -0,0 +1 @@ +#main>h2+div,#main>h2+h3,#main>h3+div{display:block;}.loading-content{display:none;}#main>h2+div,#main>h3+div{display:block;}#main>h2+h3{display:flex;} \ No newline at end of file diff --git a/rust-logo.png b/rust-logo.png new file mode 100644 index 0000000..74b4bd6 Binary files /dev/null and b/rust-logo.png differ diff --git a/rustdoc.css b/rustdoc.css new file mode 100644 index 0000000..7f04b79 --- /dev/null +++ b/rustdoc.css @@ -0,0 +1 @@ + @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');}@font-face {font-family:'Source Serif Pro';font-style:normal;font-weight:400;src:local('Source Serif Pro'),url("SourceSerifPro-Regular.ttf.woff") format('woff');}@font-face {font-family:'Source Serif Pro';font-style:italic;font-weight:400;src:local('Source Serif Pro Italic'),url("SourceSerifPro-It.ttf.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.ttf.woff") format('woff');}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;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;}html{content:"";}@media (prefers-color-scheme:light){html{content:"light";}}@media (prefers-color-scheme:dark){html{content:"dark";}}body{font:16px/1.4 "Source Serif Pro",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):not(.important),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;}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{flex-basis:100%;font-weight:600;margin-top:16px;margin-bottom:10px;position:relative;}h3.impl,h3.method,h3.type{padding-left:15px;}h1,h2,h3,h4,.sidebar,a.source,.search-input,.content table :not(code)>a,.collapse-toggle,div.item-list .out-of-band,#source-sidebar,#sidebar-toggle{font-family:"Fira Sans",sans-serif;}ol,ul{padding-left:25px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.6em;}p{margin:0 0 .6em 0;}summary{outline:none;}code,pre,a.test-arrow{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.1em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;}.source .content pre{padding:20px;}img{max-width:100%;}li{position:relative;}.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:fixed;left:0;top:0;bottom:0;overflow:auto;}.sidebar .block>ul>li{margin-right:-10px;}.content,nav{max-width:960px;}.hidden{display:none !important;}.logo-container{height:100px;width:100px;position:relative;margin:20px auto;display:block;margin-top:10px;}.logo-container>img{max-width:100px;max-height:100px;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;}.sidebar .location{border:1px solid;font-size:17px;margin:30px 10px 20px 10px;text-align:center;word-wrap:break-word;}.sidebar .version{font-size:15px;text-align:center;border-bottom:1px solid;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;}.location:empty{border:none;}.location a:first-child{font-weight:500;}.block{padding:0;margin-bottom:14px;}.block h2,.block h3{margin-top:0;margin-bottom:8px;text-align:center;}.block ul,.block li{margin:0 10px;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;}.sidebar-title{border-top:1px solid;border-bottom:1px solid;text-align:center;font-size:17px;margin-bottom:5px;}.sidebar-links{margin-bottom:15px;}.sidebar-links>a{padding-left:10px;width:100%;}.sidebar-menu{display:none;}.content{padding:15px 0;}.source .content pre.rust{white-space:pre;overflow:auto;padding-left:0;}.rustdoc:not(.source) .example-wrap{display:inline-flex;margin-bottom:10px;position:relative;}.example-wrap{width:100%;}.example-wrap>pre.line-number{overflow:initial;border:1px solid;border-top-left-radius:5px;border-bottom-left-radius:5px;padding:13px 8px;text-align:right;}.rustdoc:not(.source) .example-wrap>pre.rust{width:100%;overflow-x:auto;}.rustdoc:not(.source) .example-wrap>pre{margin:0;}#search{margin-left:230px;position:relative;}#results{position:absolute;right:0;left:0;overflow:auto;}#results>table{width:100%;table-layout:fixed;}.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 code,.docblock-short code{white-space:pre-wrap;}.docblock h1,.docblock h2,.docblock h3,.docblock h4,.docblock h5{border-bottom:1px solid;}#main>.docblock h1{font-size:1.3em;}#main>.docblock h2{font-size:1.15em;}#main>.docblock h3,#main>.docblock h4,#main>.docblock h5{font-size:1em;}#main>h2+div,#main>h2+h3,#main>h3+div{display:none;flex-wrap:wrap;}.docblock h1{font-size:1em;}.docblock h2{font-size:0.95em;}.docblock h3,.docblock h4,.docblock h5{font-size:0.9em;}.docblock{margin-left:24px;position:relative;}.content .out-of-band{float:right;font-size:23px;margin:0px;padding:0px;font-weight:normal;}h3.impl>.out-of-band{font-size:21px;}h4.method>.out-of-band{font-size:19px;}h4>code,h3>code,.invisible>code{max-width:calc(100% - 41px);display:block;}.invisible{width:100%;display:inline-block;}.content .in-band{margin:0px;padding:0px;}.in-band>code{display:inline-block;}#main{position:relative;}#main>.since{top:inherit;font-family:"Fira Sans",sans-serif;}.content table:not(.table-display){border-spacing:0 5px;}.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;}.content tr:first-child td{border-top:0;}.docblock table{margin:.5em 0;width:calc(100% - 2px);border:1px dashed;}.docblock table td{padding:.5em;border:1px dashed;}.docblock table th{padding:.5em;text-align:left;border:1px solid;}.fields+table{margin-bottom:1em;}.content .item-list{list-style-type:none;padding:0;}.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;}.content .method .where,.content .fn .where,.content .where.fmt-newline{display:block;font-size:0.8em;}.content .methods>div{margin-left:40px;margin-bottom:15px;}.content .docblock>.impl-items{margin-left:20px;margin-top:-34px;}.content .docblock>.impl-items>h4{border-bottom:0;}.content .docblock>.impl-items .table-display{margin:0;}.content .docblock>.impl-items table td{padding:0;}.toggle-wrapper.marg-left>.collapse-toggle{left:-24px;}.content .docblock>.impl-items .table-display,.impl-items table td{border:none;}.content .stability code{font-size:90%;}.content .stability{position:relative;margin-left:33px;margin-top:-13px;}.sub-variant>div>.stability{margin-top:initial;}.content .stability::before{content:'⬑';font-size:25px;position:absolute;top:-6px;left:-19px;}.content .impl-items .method,.content .impl-items>.type,.impl-items>.associatedconstant{margin-left:20px;}.content .impl-items .docblock,.content .impl-items .stability{margin-bottom:.6em;}.content .impl-items>.stability{margin-left:40px;}.methods>.stability,.content .impl-items>.stability{margin-top:-8px;}.impl-items{flex-basis:100%;}#main>.stability{margin-top:0;}nav:not(.sidebar){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;}.small-section-header:hover>.anchor{display:initial;}.in-band:hover>.anchor{display:inline-block;position:absolute;}.anchor{display:none;position:absolute;left:-7px;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-28px;padding-right:10px;}.anchor:before{content:'\2002\00a7\2002';}.docblock a:not(.srclink):not(.test-arrow):hover,.docblock-short a:not(.srclink):not(.test-arrow):hover,.stability a{text-decoration:underline;}.invisible>.srclink,h4>code+.srclink{position:absolute;top:0;right:0;font-size:17px;font-weight:normal;}.block a.current.crate{font-weight:500;}.search-container{position:relative;}.search-container>div{display:inline-flex;width:calc(100% - 34px);}#crate-search{margin-top:5px;padding:6px;padding-right:19px;flex:none;border:0;border-right:0;border-radius:4px 0 0 4px;outline:none;cursor:pointer;border-right:1px solid;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;text-overflow:"";background-repeat:no-repeat;background-color:transparent;background-size:20px;background-position:calc(100% - 1px) 56%;}.search-container>.top-button{position:absolute;right:0;top:10px;}.search-input{-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;width:100%;}#crate-search+.search-input{border-radius:0 1px 1px 0;width:calc(100% - 32px);}.search-input:focus{border-radius:2px;border:0;outline:0;}.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;width:50%;}.content .search-results td:first-child a{padding-right:10px;}.content .search-results td:first-child a:after{clear:both;content:"";display:block;}.content .search-results td:first-child a span{float:left;}tr.result span.primitive::after{content:' (primitive type)';font-style:italic;}tr.result span.keyword::after{content:' (keyword)';font-style:italic;}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:auto;border:1px solid;}#help dt{float:left;clear:left;display:block;}#help dd{margin:5px 35px;}#help .infos{padding-left:0;}#help h1,#help h2{margin-top:0;}#help>div div{width:50%;float:left;padding:20px;padding-left:17px;}.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 .emoji{font-size:1.5em;}.module-item .stab{border-radius:3px;display:inline-block;font-size:80%;line-height:1.2;margin-bottom:0;margin-right:.3em;padding:2px;vertical-align:text-bottom;}.module-item.unstable{opacity:0.65;}.since{font-weight:normal;font-size:initial;position:absolute;right:0;top:0;}.impl-items .since,.impl .since{flex-grow:0;padding-left:12px;padding-right:2px;position:initial;}.impl-items .srclink,.impl .srclink{flex-grow:0;font-size:17px;font-weight:normal;}.impl-items code,.impl code{flex-grow:1;}.impl-items h4,h4.impl,h3.impl{display:flex;flex-basis:100%;font-size:16px;margin-bottom:12px;justify-content:space-between;}.variants_table{width:100%;}.variants_table tbody tr td:first-child{width:1%;}td.summary-column{width:100%;}.summary{padding-right:0px;}pre.rust .question-mark{font-weight:bold;}a.test-arrow{display:inline-block;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:130%;top:5px;right:5px;z-index:1;}a.test-arrow:hover{text-decoration:none;}.section-header:hover a:before{position:absolute;left:-25px;padding-right:10px;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;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;margin-top:0;}.toggle-wrapper.collapsed{height:25px;transition:height .2s;margin-bottom:.6em;}.collapse-toggle>.inner{display:inline-block;width:1.2ch;text-align:center;}.collapse-toggle.hidden-default{position:relative;margin-left:20px;}.since+.srclink{display:table-cell;padding-left:10px;}.item-spacer{width:100%;height:12px;}.out-of-band>span.since{position:initial;font-size:20px;margin-right:5px;}.toggle-wrapper>.collapse-toggle{left:0;}.variant+.toggle-wrapper+.docblock>p{margin-top:5px;}.sub-variant,.sub-variant>h3{margin-top:1px !important;}#main>.sub-variant>h3{font-size:15px;margin-left:25px;margin-bottom:5px;}.sub-variant>div{margin-left:20px;margin-bottom:10px;}.sub-variant>div>span{display:block;position:relative;}.toggle-label{display:inline-block;margin-left:4px;margin-top:3px;}.enum>.toggle-wrapper+.docblock,.struct>.toggle-wrapper+.docblock{margin-left:30px;margin-bottom:20px;margin-top:5px;}.docblock>.section-header:first-child{margin-left:15px;margin-top:0;}.docblock>.section-header:first-child:hover>a:before{left:-10px;}.enum>.collapsed,.struct>.collapsed{margin-bottom:25px;}#main>.variant,#main>.structfield{display:block;}.attributes{display:block;margin-top:0px !important;margin-right:0px;margin-bottom:0px !important;margin-left:30px;}.toggle-attributes.collapsed{margin-bottom:0;}.impl-items>.toggle-attributes{margin-left:20px;}.impl-items .attributes{font-weight:500;}:target>code{opacity:1;}.information{position:absolute;left:-20px;margin-top:7px;z-index:1;}.tooltip{position:relative;display:inline-block;cursor:pointer;}.tooltip .tooltiptext{width:120px;display:none;text-align:center;padding:5px 3px;border-radius:6px;margin-left:5px;top:-5px;left:105%;z-index:10;}.tooltip:hover .tooltiptext{display:inline;}.tooltip .tooltiptext::after{content:" ";position:absolute;top:50%;left:11px;margin-top:-5px;border-width:5px;border-style:solid;}.tooltip .tooltiptext{border:1px solid;}pre.rust{position:relative;tab-width:4;-moz-tab-width:4;}.search-failed{text-align:center;margin-top:20px;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#titles{height:35px;}#titles>div{float:left;width:33.3%;text-align:center;font-size:18px;cursor:pointer;border-top:2px solid;}#titles>div:not(:last-child){margin-right:1px;width:calc(33.3% - 1px);}#titles>div>div.count{display:inline-block;font-size:16px;}#all-types{text-align:center;border:1px solid;margin:0 10px;margin-bottom:10px;display:block;border-radius:7px;}#all-types>p{margin:5px 0;}#sidebar-toggle{position:fixed;top:30px;left:300px;z-index:10;padding:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;cursor:pointer;font-weight:bold;transition:left .5s;font-size:1.2em;border:1px solid;border-left:0;}#source-sidebar{position:fixed;top:0;bottom:0;left:0;width:300px;z-index:1;overflow:auto;transition:left .5s;border-right:1px solid;}#source-sidebar>.title{font-size:1.5em;text-align:center;border-bottom:1px solid;margin-bottom:6px;}.theme-picker{position:absolute;left:211px;top:19px;}.theme-picker button{outline:none;}#settings-menu{position:absolute;right:0;top:10px;outline:none;}#theme-picker,#settings-menu{padding:4px;width:27px;height:29px;border:1px solid;border-radius:3px;cursor:pointer;}#theme-choices{display:none;position:absolute;left:0;top:28px;border:1px solid;border-radius:3px;z-index:1;cursor:pointer;}#theme-choices>button{border:none;width:100%;padding:4px;text-align:center;background:rgba(0,0,0,0);}#theme-choices>button:not(:first-child){border-top:1px solid;}@media (max-width:700px){body{padding-top:0px;}.rustdoc>.sidebar{height:45px;min-height:40px;margin:0;margin-left:-15px;padding:0 15px;position:static;z-index:11;}.sidebar>.location{float:right;margin:0px;margin-top:2px;padding:3px 10px 1px 10px;min-height:39px;background:inherit;text-align:left;font-size:24px;}.sidebar .location:empty{padding:0;}.sidebar .logo-container{width:35px;height:35px;margin-top:5px;margin-bottom:5px;float:left;margin-left:50px;}.sidebar .logo-container>img{max-width:35px;max-height:35px;}.sidebar-menu{position:fixed;z-index:10;font-size:2rem;cursor:pointer;width:45px;left:0;text-align:center;display:block;border-bottom:1px solid;border-right:1px solid;height:45px;}.rustdoc.source>.sidebar>.sidebar-menu{display:none;}.sidebar-elems{position:fixed;z-index:1;left:0;top:45px;bottom:0;overflow-y:auto;border-right:1px solid;display:none;}.sidebar>.block.version{border-bottom:none;margin-top:12px;}nav.sub{width:calc(100% - 32px);float:right;}.content{margin-left:0px;}#main{margin-top:45px;padding:0;}.content .in-band{width:100%;}.content h4>.out-of-band{position:inherit;}.toggle-wrapper>.collapse-toggle{left:0px;}.toggle-wrapper{height:1.5em;}#search{margin-left:0;}.content .impl-items .method,.content .impl-items>.type,.impl-items>.associatedconstant{display:flex;}.anchor{display:none !important;}h1.fqn{overflow:initial;}.theme-picker{left:10px;top:54px;z-index:1;}#titles>div>div.count{float:left;width:100%;}#titles{height:50px;}.sidebar.mobile{position:fixed;width:100%;margin-left:0;background-color:rgba(0,0,0,0);height:100%;}.sidebar{width:calc(100% + 30px);}.show-it{display:block;width:246px;}.show-it>.block.items{margin:8px 0;}.show-it>.block.items>ul{margin:0;}.show-it>.block.items>ul>li{text-align:center;margin:2px 0;}.show-it>.block.items>ul>li>a{font-size:21px;}#sidebar-filler{position:fixed;left:45px;width:calc(100% - 45px);top:0;height:45px;z-index:-1;border-bottom:1px solid;}.collapse-toggle{left:-20px;}.impl>.collapse-toggle{left:-10px;}#all-types{margin:10px;}#sidebar-toggle{top:100px;width:30px;font-size:1.5rem;text-align:center;padding:0;}#source-sidebar{z-index:11;}#main>.line-numbers{margin-top:0;}}@media print{nav.sub,.content .out-of-band,.collapse-toggle{display:none;}}@media (max-width:416px){#titles{height:73px;}#titles>div{height:73px;}}h3.important{margin:0;margin-bottom:13px;font-size:19px;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px;border-radius:3px;box-shadow:inset 0 -1px 0;cursor:default;}.hidden-by-impl-hider,.hidden-by-usual-hider{display:none !important;}#implementations-list>h3>span.in-band{width:100%;}.table-display{width:100%;border:0;border-collapse:collapse;border-spacing:0;font-size:16px;}.table-display tr td:first-child{padding-right:0;}.table-display tr td:last-child{float:right;}.table-display .out-of-band{position:relative;font-size:19px;display:block;}#implementors-list>.impl-items .table-display .out-of-band{font-size:17px;}.table-display td:hover .anchor{display:block;top:2px;left:-5px;}#main>ul{padding-left:10px;}#main>ul>li{list-style:none;}.non-exhaustive{margin-bottom:1em;}div.children{padding-left:27px;display:none;}div.name{cursor:pointer;position:relative;margin-left:16px;}div.files>a{display:block;padding:0 3px;}div.files>a:hover,div.name:hover{background-color:#a14b4b;}div.name.expand+.children{display:block;}div.name::before{content:"\25B6";padding-left:4px;font-size:0.7em;position:absolute;left:-16px;top:4px;}div.name.expand::before{transform:rotate(90deg);left:-15px;top:2px;}.type-decl>pre>.toggle-wrapper.toggle-attributes.top-attr{margin-left:0 !important;}.type-decl>pre>.docblock.attributes.top-attr{margin-left:1.8em !important;}.type-decl>pre>.toggle-attributes{margin-left:2.2em;}.type-decl>pre>.docblock.attributes{margin-left:4em;} \ No newline at end of file diff --git a/search-index.js b/search-index.js new file mode 100644 index 0000000..9956af0 --- /dev/null +++ b/search-index.js @@ -0,0 +1,6 @@ +var searchIndex={}; +searchIndex["tower"] = {"doc":"`fn(Request) -> Future`","i":[[8,"Layer","tower","Decorates a `Service`, transforming either the request or…",null,null],[16,"Service","","The wrapped service",0,null],[10,"layer","","Wrap the given service with the middleware, returning a…",0,[[["s"],["self"]]]],[8,"Service","","An asynchronous function from a `Request` to a `Response`.",null,null],[16,"Response","","Responses given by the service.",1,null],[16,"Error","","Errors produced by the service.",1,null],[16,"Future","","The future response value.",1,null],[10,"poll_ready","","Returns `Poll::Ready(Ok(()))` when the service is able to…",1,[[["self"],["context"]],[["result"],["poll",["result"]]]]],[10,"call","","Process the request and return the response asynchronously.",1,[[["self"],["request"]]]],[3,"ServiceBuilder","","Declaratively construct Service values.",null,null],[0,"builder","","Builder types to compose layers and services",null,null],[3,"ServiceBuilder","tower::builder","Declaratively construct Service values.",null,null],[11,"new","","Create a new `ServiceBuilder`.",2,[[],["self"]]],[11,"layer","","Add a new layer `T` into the `ServiceBuilder`.",2,[[["t"]],[["stack"],["servicebuilder",["stack"]]]]],[11,"into_inner","","Obtains the underlying `Layer` implementation.",2,[[],["l"]]],[11,"service","","Wrap the service `S` with the layers.",2,[[["s"]]]],[0,"layer","tower","A collection of `Layer` based tower services",null,null],[8,"Layer","tower::layer","Decorates a `Service`, transforming either the request or…",null,null],[16,"Service","","The wrapped service",0,null],[10,"layer","","Wrap the given service with the middleware, returning a…",0,[[["s"],["self"]]]],[0,"util","","`util` exports an Identity Layer and Chain, a mechanism…",null,null],[3,"Identity","tower::layer::util","A no-op middleware.",null,null],[3,"Stack","","Two middlewares chained together.",null,null],[6,"BoxError","tower","Alias for a type-erased error type.",null,null],[11,"from","tower::builder","",2,[[["t"]],["t"]]],[11,"into","","",2,[[],["u"]]],[11,"to_owned","","",2,[[["self"]],["t"]]],[11,"clone_into","","",2,[[["self"],["t"]]]],[11,"try_from","","",2,[[["u"]],["result"]]],[11,"try_into","","",2,[[],["result"]]],[11,"borrow","","",2,[[["self"]],["t"]]],[11,"borrow_mut","","",2,[[["self"]],["t"]]],[11,"type_id","","",2,[[["self"]],["typeid"]]],[11,"from","tower::layer::util","",3,[[["t"]],["t"]]],[11,"into","","",3,[[],["u"]]],[11,"to_owned","","",3,[[["self"]],["t"]]],[11,"clone_into","","",3,[[["self"],["t"]]]],[11,"try_from","","",3,[[["u"]],["result"]]],[11,"try_into","","",3,[[],["result"]]],[11,"borrow","","",3,[[["self"]],["t"]]],[11,"borrow_mut","","",3,[[["self"]],["t"]]],[11,"type_id","","",3,[[["self"]],["typeid"]]],[11,"from","","",4,[[["t"]],["t"]]],[11,"into","","",4,[[],["u"]]],[11,"to_owned","","",4,[[["self"]],["t"]]],[11,"clone_into","","",4,[[["self"],["t"]]]],[11,"try_from","","",4,[[["u"]],["result"]]],[11,"try_into","","",4,[[],["result"]]],[11,"borrow","","",4,[[["self"]],["t"]]],[11,"borrow_mut","","",4,[[["self"]],["t"]]],[11,"type_id","","",4,[[["self"]],["typeid"]]],[11,"clone","","",3,[[["self"]],["identity"]]],[11,"clone","","",4,[[["self"]],["stack"]]],[11,"layer","","",3,[[["s"],["self"]]]],[11,"layer","","",4,[[["s"],["self"]]]],[11,"fmt","","",4,[[["self"],["formatter"]],[["result",["error"]],["error"]]]],[11,"fmt","","",3,[[["self"],["formatter"]],[["result",["error"]],["error"]]]],[11,"default","","",3,[[],["identity"]]],[11,"clone","tower::builder","",2,[[["self"]],["servicebuilder"]]],[11,"fmt","","",2,[[["formatter"],["self"]],["result"]]],[11,"new","tower::layer::util","Create a new `Identity` value",3,[[],["identity"]]],[11,"new","","Create a new `Stack`.",4,[[["inner"],["outer"]],["stack"]]]],"p":[[8,"Layer"],[8,"Service"],[3,"ServiceBuilder"],[3,"Identity"],[3,"Stack"]]}; +searchIndex["tower_layer"] = {"doc":"Layer traits and extensions.","i":[[3,"Identity","tower_layer","A no-op middleware.",null,null],[3,"Stack","","Two middlewares chained together.",null,null],[11,"new","","Create a new `Identity` value",0,[[],["identity"]]],[11,"new","","Create a new `Stack`.",1,[[["inner"],["outer"]],["self"]]],[8,"Layer","","Decorates a `Service`, transforming either the request or…",null,null],[16,"Service","","The wrapped service",2,null],[10,"layer","","Wrap the given service with the middleware, returning a…",2,[[["s"],["self"]]]],[11,"from","","",0,[[["t"]],["t"]]],[11,"into","","",0,[[],["u"]]],[11,"to_owned","","",0,[[["self"]],["t"]]],[11,"clone_into","","",0,[[["self"],["t"]]]],[11,"try_from","","",0,[[["u"]],["result"]]],[11,"try_into","","",0,[[],["result"]]],[11,"borrow","","",0,[[["self"]],["t"]]],[11,"borrow_mut","","",0,[[["self"]],["t"]]],[11,"type_id","","",0,[[["self"]],["typeid"]]],[11,"from","","",1,[[["t"]],["t"]]],[11,"into","","",1,[[],["u"]]],[11,"to_owned","","",1,[[["self"]],["t"]]],[11,"clone_into","","",1,[[["self"],["t"]]]],[11,"try_from","","",1,[[["u"]],["result"]]],[11,"try_into","","",1,[[],["result"]]],[11,"borrow","","",1,[[["self"]],["t"]]],[11,"borrow_mut","","",1,[[["self"]],["t"]]],[11,"type_id","","",1,[[["self"]],["typeid"]]],[11,"layer","","",0,[[["s"],["self"]]]],[11,"layer","","",1,[[["s"],["self"]]]],[11,"clone","","",0,[[["self"]],["identity"]]],[11,"clone","","",1,[[["self"]],["stack"]]],[11,"default","","",0,[[],["identity"]]],[11,"fmt","","",0,[[["formatter"],["self"]],["result"]]],[11,"fmt","","",1,[[["formatter"],["self"]],["result"]]]],"p":[[3,"Identity"],[3,"Stack"],[8,"Layer"]]}; +searchIndex["tower_service"] = {"doc":"Definition of the core `Service` trait to Tower","i":[[8,"Service","tower_service","An asynchronous function from a `Request` to a `Response`.",null,null],[16,"Response","","Responses given by the service.",0,null],[16,"Error","","Errors produced by the service.",0,null],[16,"Future","","The future response value.",0,null],[10,"poll_ready","","Returns `Poll::Ready(Ok(()))` when the service is able to…",0,[[["self"],["context"]],[["poll",["result"]],["result"]]]],[10,"call","","Process the request and return the response asynchronously.",0,[[["self"],["request"]]]]],"p":[[8,"Service"]]}; +searchIndex["tower_test"] = {"doc":"Mock `Service` that can be used in tests.","i":[[0,"mock","tower_test","Mock `Service` that can be used in tests.",null,null],[3,"Mock","tower_test::mock","A mock service",null,null],[3,"Handle","","Handle to the `Mock`.",null,null],[3,"SendResponse","","Send a response in reply to a received request.",null,null],[5,"spawn_layer","","Spawn a layer onto a mock service.",null,[[["l"]]]],[5,"spawn","","Spawn a Service onto a mock task.",null,[[]]],[5,"spawn_with","","Spawn a Service via the provided wrapper closure.",null,[[["f"]]]],[5,"pair","","Create a new `Mock` and `Handle` pair.",null,[[]]],[0,"error","","Error types",null,null],[3,"Closed","tower_test::mock::error","Error yielded when a mocked service does not yet accept…",null,null],[0,"future","tower_test::mock","Future types",null,null],[3,"ResponseFuture","tower_test::mock::future","Future of the `Mock` response.",null,null],[0,"spawn","tower_test::mock","Spawn mock services onto a mock task.",null,null],[3,"Spawn","tower_test::mock::spawn","Service spawned on a mock task",null,null],[11,"new","","Create a new spawn.",0,[[["t"]],["self"]]],[11,"is_woken","","Check if this service has been woken up.",0,[[["self"]],["bool"]]],[11,"waker_ref_count","","Get how many futurs are holding onto the waker.",0,[[["self"]],["usize"]]],[11,"poll_ready","","Poll this service ready.",0,[[["self"]],[["result"],["poll",["result"]]]]],[11,"call","","Call the inner Service.",0,[[["self"],["request"]]]],[11,"into_inner","","Get the inner service.",0,[[],["t"]]],[11,"get_ref","","Get a reference to the inner service.",0,[[["self"]],["t"]]],[11,"get_mut","","Get a mutable reference to the inner service.",0,[[["self"]],["t"]]],[11,"poll_request","tower_test::mock","Asynchronously gets the next request",1,[[["self"]],[["option"],["poll",["option"]]]]],[11,"next_request","","Gets the next request.",1,[[["self"]]]],[11,"allow","","Allow a certain number of requests",1,[[["self"],["u64"]]]],[11,"send_error","","Make the next poll_ method error with the given error.",1,[[["self"],["into",["box"]],["box",["error"]]]]],[11,"send_response","","Resolve the pending request future for the linked request…",2,[[["t"]]]],[11,"send_error","","Resolve the pending request future for the linked request…",2,[[["into",["box"]],["box",["error"]]]]],[14,"assert_request_eq","tower_test","Asserts that the mock handle receives a new request equal…",null,null],[11,"from","tower_test::mock","",3,[[["t"]],["t"]]],[11,"into","","",3,[[],["u"]]],[11,"to_owned","","",3,[[["self"]],["t"]]],[11,"clone_into","","",3,[[["self"],["t"]]]],[11,"try_from","","",3,[[["u"]],["result"]]],[11,"try_into","","",3,[[],["result"]]],[11,"borrow","","",3,[[["self"]],["t"]]],[11,"borrow_mut","","",3,[[["self"]],["t"]]],[11,"type_id","","",3,[[["self"]],["typeid"]]],[11,"from","","",1,[[["t"]],["t"]]],[11,"into","","",1,[[],["u"]]],[11,"try_from","","",1,[[["u"]],["result"]]],[11,"try_into","","",1,[[],["result"]]],[11,"borrow","","",1,[[["self"]],["t"]]],[11,"borrow_mut","","",1,[[["self"]],["t"]]],[11,"type_id","","",1,[[["self"]],["typeid"]]],[11,"from","","",2,[[["t"]],["t"]]],[11,"into","","",2,[[],["u"]]],[11,"try_from","","",2,[[["u"]],["result"]]],[11,"try_into","","",2,[[],["result"]]],[11,"borrow","","",2,[[["self"]],["t"]]],[11,"borrow_mut","","",2,[[["self"]],["t"]]],[11,"type_id","","",2,[[["self"]],["typeid"]]],[11,"from","tower_test::mock::error","",4,[[["t"]],["t"]]],[11,"into","","",4,[[],["u"]]],[11,"to_string","","",4,[[["self"]],["string"]]],[11,"try_from","","",4,[[["u"]],["result"]]],[11,"try_into","","",4,[[],["result"]]],[11,"borrow","","",4,[[["self"]],["t"]]],[11,"borrow_mut","","",4,[[["self"]],["t"]]],[11,"type_id","","",4,[[["self"]],["typeid"]]],[11,"from","tower_test::mock::future","",5,[[["t"]],["t"]]],[11,"into","","",5,[[],["u"]]],[11,"try_from","","",5,[[["u"]],["result"]]],[11,"try_into","","",5,[[],["result"]]],[11,"borrow","","",5,[[["self"]],["t"]]],[11,"borrow_mut","","",5,[[["self"]],["t"]]],[11,"type_id","","",5,[[["self"]],["typeid"]]],[11,"try_poll","","",5,[[["pin"],["f"],["context"]],["poll"]]],[11,"from","tower_test::mock::spawn","",0,[[["t"]],["t"]]],[11,"into","","",0,[[],["u"]]],[11,"to_owned","","",0,[[["self"]],["t"]]],[11,"clone_into","","",0,[[["self"],["t"]]]],[11,"try_from","","",0,[[["u"]],["result"]]],[11,"try_into","","",0,[[],["result"]]],[11,"borrow","","",0,[[["self"]],["t"]]],[11,"borrow_mut","","",0,[[["self"]],["t"]]],[11,"type_id","","",0,[[["self"]],["typeid"]]],[11,"drop","tower_test::mock","",3,[[["self"]]]],[11,"drop","","",1,[[["self"]]]],[11,"clone","tower_test::mock::spawn","",0,[[["self"]],["self"]]],[11,"clone","tower_test::mock","",3,[[["self"]],["self"]]],[11,"fmt","tower_test::mock::error","",4,[[["formatter"],["self"]],["result"]]],[11,"fmt","tower_test::mock::future","",5,[[["formatter"],["self"]],["result"]]],[11,"fmt","tower_test::mock::spawn","",0,[[["formatter"],["self"]],["result"]]],[11,"fmt","tower_test::mock","",3,[[["formatter"],["self"]],["result"]]],[11,"fmt","","",1,[[["formatter"],["self"]],["result"]]],[11,"fmt","","",2,[[["formatter"],["self"]],["result"]]],[11,"fmt","tower_test::mock::error","",4,[[["formatter"],["self"]],["result"]]],[11,"poll","tower_test::mock::future","",5,[[["pin"],["self"],["context"]],["poll"]]],[11,"drop","","",5,[[["pin"],["self"]]]],[11,"poll_ready","tower_test::mock","",3,[[["self"],["context"]],[["poll",["result"]],["result"]]]],[11,"call","","",3,[[["self"],["t"]]]]],"p":[[3,"Spawn"],[3,"Handle"],[3,"SendResponse"],[3,"Mock"],[3,"Closed"],[3,"ResponseFuture"]]}; +addSearchOptions(searchIndex);initSearch(searchIndex); \ No newline at end of file diff --git a/settings.css b/settings.css new file mode 100644 index 0000000..6ce7665 --- /dev/null +++ b/settings.css @@ -0,0 +1 @@ +.setting-line{padding:5px;position:relative;}.setting-line>div{max-width:calc(100% - 74px);display:inline-block;vertical-align:top;font-size:17px;padding-top:2px;}.setting-line>.title{font-size:19px;width:100%;max-width:none;border-bottom:1px solid;}.toggle{position:relative;display:inline-block;width:45px;height:27px;margin-right:20px;}.toggle input{display:none;}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;-webkit-transition:.3s;transition:.3s;}.slider:before{position:absolute;content:"";height:19px;width:19px;left:4px;bottom:4px;background-color:white;-webkit-transition:.3s;transition:.3s;}input:checked+.slider{background-color:#2196F3;}input:focus+.slider{box-shadow:0 0 1px #2196F3;}input:checked+.slider:before{-webkit-transform:translateX(19px);-ms-transform:translateX(19px);transform:translateX(19px);}.setting-line>.sub-settings{padding-left:42px;width:100%;display:block;} \ No newline at end of file diff --git a/settings.html b/settings.html new file mode 100644 index 0000000..5cd1010 --- /dev/null +++ b/settings.html @@ -0,0 +1,2 @@ +Rustdoc settings

Rustdoc settings

Auto-hide item declarations
Auto-hide structs declaration
Auto-hide enums declaration
Auto-hide unions declaration
Auto-hide traits declaration
Auto-hide macros declaration
+
Auto-hide item attributes.
Auto-hide item methods' documentation
Auto-hide trait implementations documentation
Directly go to item in search if there is only one result
Show line numbers on code examples
Disable keyboard shortcuts
\ No newline at end of file diff --git a/settings.js b/settings.js new file mode 100644 index 0000000..9930309 --- /dev/null +++ b/settings.js @@ -0,0 +1 @@ +(function(){function changeSetting(settingName,isEnabled){updateLocalStorage('rustdoc-'+settingName,isEnabled)}function getSettingValue(settingName){return getCurrentValue('rustdoc-'+settingName)}function setEvents(){var elems=document.getElementsByClassName("slider");if(!elems||elems.length===0){return}for(var i=0;i"){sidebar.style.left="";this.style.left="";child.innerText="<";updateLocalStorage("rustdoc-source-sidebar-show","true")}else{sidebar.style.left="-300px";this.style.left="0";child.innerText=">";updateLocalStorage("rustdoc-source-sidebar-show","false")}}function createSidebarToggle(){var sidebarToggle=document.createElement("div");sidebarToggle.id="sidebar-toggle";sidebarToggle.onclick=toggleSidebar;var inner1=document.createElement("div");inner1.style.position="relative";var inner2=document.createElement("div");inner2.style.paddingTop="3px";if(getCurrentValue("rustdoc-source-sidebar-show")==="true"){inner2.innerText="<"}else{inner2.innerText=">";sidebarToggle.style.left="0"}inner1.appendChild(inner2);sidebarToggle.appendChild(inner1);return sidebarToggle}function createSourceSidebar(){if(window.rootPath.endsWith("/")===false){window.rootPath+="/"}var main=document.getElementById("main");var sidebarToggle=createSidebarToggle();main.insertBefore(sidebarToggle,main.firstChild);var sidebar=document.createElement("div");sidebar.id="source-sidebar";if(getCurrentValue("rustdoc-source-sidebar-show")!=="true"){sidebar.style.left="-300px"}var currentFile=getCurrentFilePath();var hasFoundFile=false;var title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(sourcesIndex).forEach(function(key){sourcesIndex[key].name=key;hasFoundFile=createDirEntry(sourcesIndex[key],sidebar,"",currentFile,hasFoundFile)});main.insertBefore(sidebar,main.firstChild)} \ No newline at end of file diff --git a/src/tower/builder/mod.rs.html b/src/tower/builder/mod.rs.html new file mode 100644 index 0000000..efd63da --- /dev/null +++ b/src/tower/builder/mod.rs.html @@ -0,0 +1,467 @@ +mod.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
+
+//! Builder types to compose layers and services
+
+use tower_layer::{Identity, Layer, Stack};
+
+use std::fmt;
+
+/// Declaratively construct Service values.
+///
+/// `ServiceBuilder` provides a [builder-like interface][builder] for composing
+/// layers to be applied to a `Service`.
+///
+/// # Service
+///
+/// A [`Service`](tower_service::Service) is a trait representing an
+/// asynchronous function of a request to a response. It is similar to `async
+/// fn(Request) -> Result<Response, Error>`.
+///
+/// A `Service` is typically bound to a single transport, such as a TCP
+/// connection.  It defines how _all_ inbound or outbound requests are handled
+/// by that connection.
+///
+///
+/// [builder]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
+///
+/// # Order
+///
+/// The order in which layers are added impacts how requests are handled. Layers
+/// that are added first will be called with the request first. The argument to
+/// `service` will be last to see the request.
+///
+/// ```
+/// # // this (and other) doctest is ignored because we don't have a way
+/// # // to say that it should only be run with cfg(feature = "...")
+/// # use tower::Service;
+/// # use tower::builder::ServiceBuilder;
+/// #[cfg(all(feature = "buffer", feature = "limit"))]
+/// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
+/// ServiceBuilder::new()
+///     .buffer(100)
+///     .concurrency_limit(10)
+///     .service(svc)
+/// # ;
+/// # }
+/// ```
+///
+/// In the above example, the buffer layer receives the request first followed
+/// by `concurrency_limit`. `buffer` enables up to 100 request to be in-flight
+/// **on top of** the requests that have already been forwarded to the next
+/// layer. Combined with `concurrency_limit`, this allows up to 110 requests to be
+/// in-flight.
+///
+/// ```
+/// # use tower::Service;
+/// # use tower::builder::ServiceBuilder;
+/// #[cfg(all(feature = "buffer", feature = "limit"))]
+/// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
+/// ServiceBuilder::new()
+///     .concurrency_limit(10)
+///     .buffer(100)
+///     .service(svc)
+/// # ;
+/// # }
+/// ```
+///
+/// The above example is similar, but the order of layers is reversed. Now,
+/// `concurrency_limit` applies first and only allows 10 requests to be in-flight
+/// total.
+///
+/// # Examples
+///
+/// A `Service` stack with a single layer:
+///
+/// ```
+/// # use tower::Service;
+/// # use tower::builder::ServiceBuilder;
+/// # #[cfg(feature = "limit")]
+/// # use tower::limit::concurrency::ConcurrencyLimitLayer;
+/// #[cfg(feature = "limit")]
+/// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
+/// ServiceBuilder::new()
+///     .concurrency_limit(5)
+///     .service(svc);
+/// # ;
+/// # }
+/// ```
+///
+/// A `Service` stack with _multiple_ layers that contain rate limiting,
+/// in-flight request limits, and a channel-backed, clonable `Service`:
+///
+/// ```
+/// # use tower::Service;
+/// # use tower::builder::ServiceBuilder;
+/// # use std::time::Duration;
+/// #[cfg(all(feature = "buffer", feature = "limit"))]
+/// # async fn wrap<S>(svc: S) where S: Service<(), Error = &'static str> + 'static + Send, S::Future: Send {
+/// ServiceBuilder::new()
+///     .buffer(5)
+///     .concurrency_limit(5)
+///     .rate_limit(5, Duration::from_secs(1))
+///     .service(svc);
+/// # ;
+/// # }
+/// ```
+#[derive(Clone)]
+pub struct ServiceBuilder<L> {
+    layer: L,
+}
+
+impl ServiceBuilder<Identity> {
+    /// Create a new `ServiceBuilder`.
+    pub fn new() -> Self {
+        ServiceBuilder {
+            layer: Identity::new(),
+        }
+    }
+}
+
+impl<L> ServiceBuilder<L> {
+    /// Add a new layer `T` into the `ServiceBuilder`.
+    pub fn layer<T>(self, layer: T) -> ServiceBuilder<Stack<T, L>> {
+        ServiceBuilder {
+            layer: Stack::new(layer, self.layer),
+        }
+    }
+
+    /// Buffer requests when when the next layer is out of capacity.
+    #[cfg(feature = "buffer")]
+    pub fn buffer<Request>(
+        self,
+        bound: usize,
+    ) -> ServiceBuilder<Stack<crate::buffer::BufferLayer<Request>, L>> {
+        self.layer(crate::buffer::BufferLayer::new(bound))
+    }
+
+    /// Limit the max number of in-flight requests.
+    ///
+    /// A request is in-flight from the time the request is received until the
+    /// response future completes. This includes the time spent in the next
+    /// layers.
+    #[cfg(feature = "limit")]
+    pub fn concurrency_limit(
+        self,
+        max: usize,
+    ) -> ServiceBuilder<Stack<crate::limit::ConcurrencyLimitLayer, L>> {
+        self.layer(crate::limit::ConcurrencyLimitLayer::new(max))
+    }
+
+    /// Drop requests when the next layer is unable to respond to requests.
+    ///
+    /// Usually, when a layer or service does not have capacity to process a
+    /// request (i.e., `poll_ready` returns `NotReady`), the caller waits until
+    /// capacity becomes available.
+    ///
+    /// `load_shed` immediately responds with an error when the next layer is
+    /// out of capacity.
+    #[cfg(feature = "load-shed")]
+    pub fn load_shed(self) -> ServiceBuilder<Stack<crate::load_shed::LoadShedLayer, L>> {
+        self.layer(crate::load_shed::LoadShedLayer::new())
+    }
+
+    /// Limit requests to at most `num` per the given duration
+    #[cfg(feature = "limit")]
+    pub fn rate_limit(
+        self,
+        num: u64,
+        per: std::time::Duration,
+    ) -> ServiceBuilder<Stack<crate::limit::RateLimitLayer, L>> {
+        self.layer(crate::limit::RateLimitLayer::new(num, per))
+    }
+
+    /// Retry failed requests.
+    ///
+    /// `policy` must implement [`Policy`].
+    ///
+    /// [`Policy`]: ../retry/trait.Policy.html
+    #[cfg(feature = "retry")]
+    pub fn retry<P>(self, policy: P) -> ServiceBuilder<Stack<crate::retry::RetryLayer<P>, L>> {
+        self.layer(crate::retry::RetryLayer::new(policy))
+    }
+
+    /// Fail requests that take longer than `timeout`.
+    ///
+    /// If the next layer takes more than `timeout` to respond to a request,
+    /// processing is terminated and an error is returned.
+    #[cfg(feature = "timeout")]
+    pub fn timeout(
+        self,
+        timeout: std::time::Duration,
+    ) -> ServiceBuilder<Stack<crate::timeout::TimeoutLayer, L>> {
+        self.layer(crate::timeout::TimeoutLayer::new(timeout))
+    }
+
+    /// Map one request type to another.
+    #[cfg(feature = "util")]
+    pub fn map_request<F, R1, R2>(
+        self,
+        f: F,
+    ) -> ServiceBuilder<Stack<crate::util::MapRequestLayer<F>, L>>
+    where
+        F: Fn(R1) -> R2,
+    {
+        self.layer(crate::util::MapRequestLayer::new(f))
+    }
+
+    /// Map one response type to another.
+    #[cfg(feature = "util")]
+    pub fn map_response<F>(
+        self,
+        f: F,
+    ) -> ServiceBuilder<Stack<crate::util::MapResponseLayer<F>, L>> {
+        self.layer(crate::util::MapResponseLayer::new(f))
+    }
+
+    /// Obtains the underlying `Layer` implementation.
+    pub fn into_inner(self) -> L {
+        self.layer
+    }
+
+    /// Wrap the service `S` with the layers.
+    pub fn service<S>(self, service: S) -> L::Service
+    where
+        L: Layer<S>,
+    {
+        self.layer.layer(service)
+    }
+}
+
+impl<L: fmt::Debug> fmt::Debug for ServiceBuilder<L> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_tuple("ServiceBuilder").field(&self.layer).finish()
+    }
+}
+
+
\ No newline at end of file diff --git a/src/tower/layer.rs.html b/src/tower/layer.rs.html new file mode 100644 index 0000000..609211a --- /dev/null +++ b/src/tower/layer.rs.html @@ -0,0 +1,19 @@ +layer.rs.html -- source
1
+2
+3
+4
+5
+6
+7
+8
+
+//! A collection of `Layer` based tower services
+
+pub use tower_layer::Layer;
+
+/// `util` exports an Identity Layer and Chain, a mechanism for chaining them.
+pub mod util {
+    pub use tower_layer::{Identity, Stack};
+}
+
+
\ No newline at end of file diff --git a/src/tower/lib.rs.html b/src/tower/lib.rs.html new file mode 100644 index 0000000..2b8f7b1 --- /dev/null +++ b/src/tower/lib.rs.html @@ -0,0 +1,175 @@ +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
+
+#![doc(html_root_url = "https://docs.rs/tower/0.3.1")]
+#![warn(
+    missing_debug_implementations,
+    missing_docs,
+    rust_2018_idioms,
+    unreachable_pub
+)]
+#![allow(elided_lifetimes_in_paths)]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+
+//! `fn(Request) -> Future<Response>`
+//!
+//! Tower is a library of modular and reusable components for building
+//! robust networking clients and servers.
+
+#[cfg(feature = "balance")]
+#[cfg_attr(docsrs, doc(cfg(feature = "balance")))]
+pub mod balance;
+#[cfg(feature = "buffer")]
+#[cfg_attr(docsrs, doc(cfg(feature = "buffer")))]
+pub mod buffer;
+#[cfg(feature = "discover")]
+#[cfg_attr(docsrs, doc(cfg(feature = "discover")))]
+pub mod discover;
+#[cfg(feature = "filter")]
+#[cfg_attr(docsrs, doc(cfg(feature = "filter")))]
+pub mod filter;
+#[cfg(feature = "hedge")]
+#[cfg_attr(docsrs, doc(cfg(feature = "hedge")))]
+pub mod hedge;
+#[cfg(feature = "limit")]
+#[cfg_attr(docsrs, doc(cfg(feature = "limit")))]
+pub mod limit;
+#[cfg(feature = "load")]
+#[cfg_attr(docsrs, doc(cfg(feature = "load")))]
+pub mod load;
+#[cfg(feature = "load-shed")]
+#[cfg_attr(docsrs, doc(cfg(feature = "load-shed")))]
+pub mod load_shed;
+#[cfg(feature = "make")]
+#[cfg_attr(docsrs, doc(cfg(feature = "make")))]
+pub mod make;
+#[cfg(feature = "ready-cache")]
+#[cfg_attr(docsrs, doc(cfg(feature = "ready-cache")))]
+pub mod ready_cache;
+#[cfg(feature = "reconnect")]
+#[cfg_attr(docsrs, doc(cfg(feature = "reconnect")))]
+pub mod reconnect;
+#[cfg(feature = "retry")]
+#[cfg_attr(docsrs, doc(cfg(feature = "retry")))]
+pub mod retry;
+#[cfg(feature = "spawn-ready")]
+#[cfg_attr(docsrs, doc(cfg(feature = "spawn-ready")))]
+pub mod spawn_ready;
+#[cfg(feature = "steer")]
+#[cfg_attr(docsrs, doc(cfg(feature = "steer")))]
+pub mod steer;
+#[cfg(feature = "timeout")]
+#[cfg_attr(docsrs, doc(cfg(feature = "timeout")))]
+pub mod timeout;
+#[cfg(feature = "util")]
+#[cfg_attr(docsrs, doc(cfg(feature = "util")))]
+pub mod util;
+
+pub mod builder;
+pub mod layer;
+
+#[cfg(feature = "util")]
+#[cfg_attr(docsrs, doc(cfg(feature = "util")))]
+#[doc(inline)]
+pub use self::util::{service_fn, ServiceExt};
+
+#[doc(inline)]
+pub use crate::builder::ServiceBuilder;
+#[doc(inline)]
+pub use tower_layer::Layer;
+#[doc(inline)]
+pub use tower_service::Service;
+
+#[allow(unreachable_pub)]
+mod sealed {
+    pub trait Sealed<T> {}
+}
+
+/// Alias for a type-erased error type.
+pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
+
+
\ No newline at end of file diff --git a/src/tower_layer/identity.rs.html b/src/tower_layer/identity.rs.html new file mode 100644 index 0000000..3d7e4e5 --- /dev/null +++ b/src/tower_layer/identity.rs.html @@ -0,0 +1,69 @@ +identity.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
+
+use super::Layer;
+use std::fmt;
+
+/// A no-op middleware.
+///
+/// When wrapping a `Service`, the `Identity` layer returns the provided
+/// service without modifying it.
+#[derive(Default, Clone)]
+pub struct Identity {
+    _p: (),
+}
+
+impl Identity {
+    /// Create a new `Identity` value
+    pub fn new() -> Identity {
+        Identity { _p: () }
+    }
+}
+
+/// Decorates a `Service`, transforming either the request or the response.
+impl<S> Layer<S> for Identity {
+    type Service = S;
+
+    fn layer(&self, inner: S) -> Self::Service {
+        inner
+    }
+}
+
+impl fmt::Debug for Identity {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Identity").finish()
+    }
+}
+
+
\ No newline at end of file diff --git a/src/tower_layer/lib.rs.html b/src/tower_layer/lib.rs.html new file mode 100644 index 0000000..5606f32 --- /dev/null +++ b/src/tower_layer/lib.rs.html @@ -0,0 +1,205 @@ +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
+
+#![doc(html_root_url = "https://docs.rs/tower-layer/0.3.0-alpha.2")]
+#![warn(
+    missing_debug_implementations,
+    missing_docs,
+    rust_2018_idioms,
+    unreachable_pub
+)]
+
+//! Layer traits and extensions.
+//!
+//! A layer decorates an service and provides additional functionality. It
+//! allows other services to be composed with the service that implements layer.
+//!
+//! A middleware implements the [`Layer`] and [`Service`] trait.
+
+mod identity;
+mod stack;
+
+pub use self::{identity::Identity, stack::Stack};
+
+/// Decorates a `Service`, transforming either the request or the response.
+///
+/// Often, many of the pieces needed for writing network applications can be
+/// reused across multiple services. The `Layer` trait can be used to write
+/// reusable components that can be applied to very different kinds of services;
+/// for example, it can be applied to services operating on different protocols,
+/// and to both the client and server side of a network transaction.
+///
+/// # Log
+///
+/// Take request logging as an example:
+///
+/// ```rust
+/// # use tower_service::Service;
+/// # use std::task::{Poll, Context};
+/// # use tower_layer::Layer;
+/// # use std::fmt;
+///
+/// pub struct LogLayer {
+///     target: &'static str,
+/// }
+///
+/// impl<S> Layer<S> for LogLayer {
+///     type Service = LogService<S>;
+///
+///     fn layer(&self, service: S) -> Self::Service {
+///         LogService {
+///             target: self.target,
+///             service
+///         }
+///     }
+/// }
+///
+/// // This service implements the Log behavior
+/// pub struct LogService<S> {
+///     target: &'static str,
+///     service: S,
+/// }
+///
+/// impl<S, Request> Service<Request> for LogService<S>
+/// where
+///     S: Service<Request>,
+///     Request: fmt::Debug,
+/// {
+///     type Response = S::Response;
+///     type Error = S::Error;
+///     type Future = S::Future;
+///
+///     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+///         self.service.poll_ready(cx)
+///     }
+///
+///     fn call(&mut self, request: Request) -> Self::Future {
+///         // Insert log statement here or other functionality
+///         println!("request = {:?}, target = {:?}", request, self.target);
+///         self.service.call(request)
+///     }
+/// }
+/// ```
+///
+/// The above log implementation is decoupled from the underlying protocol and
+/// is also decoupled from client or server concerns. In other words, the same
+/// log middleware could be used in either a client or a server.
+pub trait Layer<S> {
+    /// The wrapped service
+    type Service;
+    /// Wrap the given service with the middleware, returning a new service
+    /// that has been decorated with the middleware.
+    fn layer(&self, inner: S) -> Self::Service;
+}
+
+impl<'a, T, S> Layer<S> for &'a T
+where
+    T: ?Sized + Layer<S>,
+{
+    type Service = T::Service;
+
+    fn layer(&self, inner: S) -> Self::Service {
+        (**self).layer(inner)
+    }
+}
+
+
\ No newline at end of file diff --git a/src/tower_layer/stack.rs.html b/src/tower_layer/stack.rs.html new file mode 100644 index 0000000..dc26c9c --- /dev/null +++ b/src/tower_layer/stack.rs.html @@ -0,0 +1,127 @@ +stack.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
+
+use super::Layer;
+use std::fmt;
+
+/// Two middlewares chained together.
+#[derive(Clone)]
+pub struct Stack<Inner, Outer> {
+    inner: Inner,
+    outer: Outer,
+}
+
+impl<Inner, Outer> Stack<Inner, Outer> {
+    /// Create a new `Stack`.
+    pub fn new(inner: Inner, outer: Outer) -> Self {
+        Stack { inner, outer }
+    }
+}
+
+impl<S, Inner, Outer> Layer<S> for Stack<Inner, Outer>
+where
+    Inner: Layer<S>,
+    Outer: Layer<Inner::Service>,
+{
+    type Service = Outer::Service;
+
+    fn layer(&self, service: S) -> Self::Service {
+        let inner = self.inner.layer(service);
+
+        self.outer.layer(inner)
+    }
+}
+
+impl<Inner, Outer> fmt::Debug for Stack<Inner, Outer>
+where
+    Inner: fmt::Debug,
+    Outer: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // The generated output of nested `Stack`s is very noisy and makes
+        // it harder to understand what is in a `ServiceBuilder`.
+        //
+        // Instead, this output is designed assuming that a `Stack` is
+        // usually quite nested, and inside a `ServiceBuilder`. Therefore,
+        // this skips using `f.debug_struct()`, since each one would force
+        // a new layer of indentation.
+        //
+        // - In compact mode, a nested stack ends up just looking like a flat
+        //   list of layers.
+        //
+        // - In pretty mode, while a newline is inserted between each layer,
+        //   the `DebugStruct` used in the `ServiceBuilder` will inject padding
+        //   to that each line is at the same indentation level.
+        //
+        // Also, the order of [outer, inner] is important, since it reflects
+        // the order that the layers were added to the stack.
+        if f.alternate() {
+            // pretty
+            write!(f, "{:#?},\n{:#?}", self.outer, self.inner)
+        } else {
+            write!(f, "{:?}, {:?}", self.outer, self.inner)
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/src/tower_service/lib.rs.html b/src/tower_service/lib.rs.html new file mode 100644 index 0000000..3489c95 --- /dev/null +++ b/src/tower_service/lib.rs.html @@ -0,0 +1,545 @@ +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
+
+#![doc(html_root_url = "https://docs.rs/tower-service/0.3.0")]
+#![warn(
+    missing_debug_implementations,
+    missing_docs,
+    rust_2018_idioms,
+    unreachable_pub
+)]
+
+//! Definition of the core `Service` trait to Tower
+//!
+//! The [`Service`] trait provides the necessary abstractions for defining
+//! request / response clients and servers. It is simple but powerful and is
+//! used as the foundation for the rest of Tower.
+
+use std::future::Future;
+use std::task::{Context, Poll};
+
+/// An asynchronous function from a `Request` to a `Response`.
+///
+/// The `Service` trait is a simplified interface making it easy to write
+/// network applications in a modular and reusable way, decoupled from the
+/// underlying protocol. It is one of Tower's fundamental abstractions.
+///
+/// # Functional
+///
+/// A `Service` is a function of a `Request`. It immediately returns a
+/// `Future` representing the eventual completion of processing the
+/// request. The actual request processing may happen at any time in the
+/// future, on any thread or executor. The processing may depend on calling
+/// other services. At some point in the future, the processing will complete,
+/// and the `Future` will resolve to a response or error.
+///
+/// At a high level, the `Service::call` function represents an RPC request. The
+/// `Service` value can be a server or a client.
+///
+/// # Server
+///
+/// An RPC server *implements* the `Service` trait. Requests received by the
+/// server over the network are deserialized and then passed as an argument to the
+/// server value. The returned response is sent back over the network.
+///
+/// As an example, here is how an HTTP request is processed by a server:
+///
+/// ```rust
+/// # use std::pin::Pin;
+/// # use std::task::{Poll, Context};
+/// # use std::future::Future;
+/// # use tower_service::Service;
+///
+/// use http::{Request, Response, StatusCode};
+///
+/// struct HelloWorld;
+///
+/// impl Service<Request<Vec<u8>>> for HelloWorld {
+///     type Response = Response<Vec<u8>>;
+///     type Error = http::Error;
+///     type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
+///
+///     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+///         Poll::Ready(Ok(()))
+///     }
+///
+///     fn call(&mut self, req: Request<Vec<u8>>) -> Self::Future {
+///         // create the body
+///         let body: Vec<u8> = "hello, world!\n"
+///             .as_bytes()
+///             .to_owned();
+///         // Create the HTTP response
+///         let resp = Response::builder()
+///             .status(StatusCode::OK)
+///             .body(body)
+///             .expect("Unable to create `http::Response`");
+///         
+///         // create a response in a future.
+///         let fut = async {
+///             Ok(resp)
+///         };
+///
+///         // Return the response as an immediate future
+///         Box::pin(fut)
+///     }
+/// }
+/// ```
+///
+/// # Client
+///
+/// A client consumes a service by using a `Service` value. The client may
+/// issue requests by invoking `call` and passing the request as an argument.
+/// It then receives the response by waiting for the returned future.
+///
+/// As an example, here is how a Redis request would be issued:
+///
+/// ```rust,ignore
+/// let client = redis::Client::new()
+///     .connect("127.0.0.1:6379".parse().unwrap())
+///     .unwrap();
+///
+/// let resp = client.call(Cmd::set("foo", "this is the value of foo")).await?;
+///
+/// // Wait for the future to resolve
+/// println!("Redis response: {:?}", resp);
+/// ```
+///
+/// # Middleware / Layer
+///
+/// More often than not, all the pieces needed for writing robust, scalable
+/// network applications are the same no matter the underlying protocol. By
+/// unifying the API for both clients and servers in a protocol agnostic way,
+/// it is possible to write middleware that provide these pieces in a
+/// reusable way.
+///
+/// Take timeouts as an example:
+///
+/// ```rust,ignore
+/// use tower_service::Service;
+/// use tower_layer::Layer;
+/// use futures::FutureExt;
+/// use std::future::Future;
+/// use std::task::{Context, Poll};
+/// use std::time::Duration;
+/// use std::pin::Pin;
+///
+///
+/// pub struct Timeout<T> {
+///     inner: T,
+///     timeout: Duration,
+/// }
+///
+/// pub struct TimeoutLayer(Duration);
+///
+/// pub struct Expired;
+///
+/// impl<T> Timeout<T> {
+///     pub fn new(inner: T, timeout: Duration) -> Timeout<T> {
+///         Timeout {
+///             inner,
+///             timeout
+///         }
+///     }
+/// }
+///
+/// impl<T, Request> Service<Request> for Timeout<T>
+/// where
+///     T: Service<Request>,
+///     T::Future: 'static,
+///     T::Error: From<Expired> + 'static,
+///     T::Response: 'static
+/// {
+///     type Response = T::Response;
+///     type Error = T::Error;
+///     type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
+///
+///     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+///        self.inner.poll_ready(cx).map_err(Into::into)
+///     }
+///
+///     fn call(&mut self, req: Request) -> Self::Future {
+///         let timeout = tokio_timer::delay_for(self.timeout)
+///             .map(|_| Err(Self::Error::from(Expired)));
+///
+///         let fut = Box::pin(self.inner.call(req));
+///         let f = futures::select(fut, timeout)
+///             .map(|either| either.factor_first().0);
+///
+///         Box::pin(f)
+///     }
+/// }
+///
+/// impl TimeoutLayer {
+///     pub fn new(delay: Duration) -> Self {
+///         TimeoutLayer(delay)
+///     }
+/// }
+///
+/// impl<S> Layer<S> for TimeoutLayer
+/// {
+///     type Service = Timeout<S>;
+///
+///     fn layer(&self, service: S) -> Timeout<S> {
+///         Timeout::new(service, self.0)
+///     }
+/// }
+///
+/// ```
+///
+/// The above timeout implementation is decoupled from the underlying protocol
+/// and is also decoupled from client or server concerns. In other words, the
+/// same timeout middleware could be used in either a client or a server.
+///
+/// # Backpressure
+///
+/// Calling a `Service` which is at capacity (i.e., it is temporarily unable to process a
+/// request) should result in an error. The caller is responsible for ensuring
+/// that the service is ready to receive the request before calling it.
+///
+/// `Service` provides a mechanism by which the caller is able to coordinate
+/// readiness. `Service::poll_ready` returns `Ready` if the service expects that
+/// it is able to process a request.
+pub trait Service<Request> {
+    /// Responses given by the service.
+    type Response;
+
+    /// Errors produced by the service.
+    type Error;
+
+    /// The future response value.
+    type Future: Future<Output = Result<Self::Response, Self::Error>>;
+
+    /// Returns `Poll::Ready(Ok(()))` when the service is able to process requests.
+    ///
+    /// If the service is at capacity, then `Poll::Pending` is returned and the task
+    /// is notified when the service becomes ready again. This function is
+    /// expected to be called while on a task. Generally, this can be done with
+    /// a simple `futures::future::poll_fn` call.
+    ///
+    /// If `Poll::Ready(Err(_))` is returned, the service is no longer able to service requests
+    /// and the caller should discard the service instance.
+    ///
+    /// Once `poll_ready` returns `Poll::Ready(Ok(()))`, a request may be dispatched to the
+    /// service using `call`. Until a request is dispatched, repeated calls to
+    /// `poll_ready` must return either `Poll::Ready(Ok(()))` or `Poll::Ready(Err(_))`.
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
+
+    /// Process the request and return the response asynchronously.
+    ///
+    /// This function is expected to be callable off task. As such,
+    /// implementations should take care to not call `poll_ready`.
+    ///
+    /// Before dispatching a request, `poll_ready` must be called and return
+    /// `Poll::Ready(Ok(()))`.
+    ///
+    /// # Panics
+    ///
+    /// Implementations are permitted to panic if `call` is invoked without
+    /// obtaining `Poll::Ready(Ok(()))` from `poll_ready`.
+    fn call(&mut self, req: Request) -> Self::Future;
+}
+
+impl<'a, S, Request> Service<Request> for &'a mut S
+where
+    S: Service<Request> + 'a,
+{
+    type Response = S::Response;
+    type Error = S::Error;
+    type Future = S::Future;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), S::Error>> {
+        (**self).poll_ready(cx)
+    }
+
+    fn call(&mut self, request: Request) -> S::Future {
+        (**self).call(request)
+    }
+}
+
+impl<S, Request> Service<Request> for Box<S>
+where
+    S: Service<Request> + ?Sized,
+{
+    type Response = S::Response;
+    type Error = S::Error;
+    type Future = S::Future;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), S::Error>> {
+        (**self).poll_ready(cx)
+    }
+
+    fn call(&mut self, request: Request) -> S::Future {
+        (**self).call(request)
+    }
+}
+
+
\ No newline at end of file diff --git a/src/tower_test/lib.rs.html b/src/tower_test/lib.rs.html new file mode 100644 index 0000000..5b8bcf8 --- /dev/null +++ b/src/tower_test/lib.rs.html @@ -0,0 +1,29 @@ +lib.rs.html -- source
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+
+#![doc(html_root_url = "https://docs.rs/tower-test/0.3.0")]
+#![warn(
+    missing_debug_implementations,
+    missing_docs,
+    rust_2018_idioms,
+    unreachable_pub
+)]
+#![allow(elided_lifetimes_in_paths)]
+
+//! Mock `Service` that can be used in tests.
+
+mod macros;
+pub mod mock;
+
+
\ No newline at end of file diff --git a/src/tower_test/macros.rs.html b/src/tower_test/macros.rs.html new file mode 100644 index 0000000..8e8eba7 --- /dev/null +++ b/src/tower_test/macros.rs.html @@ -0,0 +1,83 @@ +macros.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
+
+/// Asserts that the mock handle receives a new request equal to the given
+/// value.
+///
+/// On success, the [`SendResponse`] handle for the matched request is returned,
+/// allowing the caller to respond to the request. On failure, the macro panics.
+///
+/// # Examples
+///
+/// ```rust
+/// use tower_service::Service;
+/// use tower_test::{mock, assert_request_eq};
+/// use tokio_test::assert_ready;
+///
+/// # async fn test() {
+/// let (mut service, mut handle) = mock::spawn();
+///
+/// assert_ready!(service.poll_ready());
+///
+/// let response = service.call("hello");
+///
+/// assert_request_eq!(handle, "hello").send_response("world");
+///
+/// assert_eq!(response.await.unwrap(), "world");
+/// # }
+/// ```
+#[macro_export]
+macro_rules! assert_request_eq {
+    ($mock_handle:expr, $expect:expr) => {
+        assert_request_eq!($mock_handle, $expect,)
+    };
+    ($mock_handle:expr, $expect:expr, $($arg:tt)*) => {{
+        let (actual, send_response) = match $mock_handle.next_request().await {
+            Some(r) => r,
+            None => panic!("expected a request but none was received."),
+        };
+
+        assert_eq!(actual, $expect, $($arg)*);
+        send_response
+    }};
+}
+
+
\ No newline at end of file diff --git a/src/tower_test/mock/error.rs.html b/src/tower_test/mock/error.rs.html new file mode 100644 index 0000000..e487eb8 --- /dev/null +++ b/src/tower_test/mock/error.rs.html @@ -0,0 +1,49 @@ +error.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
+
+//! Error types
+
+use std::{error, fmt};
+
+pub(crate) type Error = Box<dyn error::Error + Send + Sync>;
+
+/// Error yielded when a mocked service does not yet accept requests.
+#[derive(Debug)]
+pub struct Closed(());
+
+impl Closed {
+    pub(crate) fn new() -> Closed {
+        Closed(())
+    }
+}
+
+impl fmt::Display for Closed {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        write!(fmt, "service closed")
+    }
+}
+
+impl error::Error for Closed {}
+
+
\ No newline at end of file diff --git a/src/tower_test/mock/future.rs.html b/src/tower_test/mock/future.rs.html new file mode 100644 index 0000000..65dbde5 --- /dev/null +++ b/src/tower_test/mock/future.rs.html @@ -0,0 +1,95 @@ +future.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
+
+//! Future types
+
+use crate::mock::error::{self, Error};
+use futures_util::ready;
+use pin_project::pin_project;
+use tokio::sync::oneshot;
+
+use std::{
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+/// Future of the `Mock` response.
+#[pin_project]
+#[derive(Debug)]
+pub struct ResponseFuture<T> {
+    #[pin]
+    rx: Option<Rx<T>>,
+}
+
+type Rx<T> = oneshot::Receiver<Result<T, Error>>;
+
+impl<T> ResponseFuture<T> {
+    pub(crate) fn new(rx: Rx<T>) -> ResponseFuture<T> {
+        ResponseFuture { rx: Some(rx) }
+    }
+
+    pub(crate) fn closed() -> ResponseFuture<T> {
+        ResponseFuture { rx: None }
+    }
+}
+
+impl<T> Future for ResponseFuture<T> {
+    type Output = Result<T, Error>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
+        match self.project().rx.as_pin_mut() {
+            Some(rx) => match ready!(rx.poll(cx)) {
+                Ok(r) => Poll::Ready(r),
+                Err(_) => Poll::Ready(Err(error::Closed::new().into())),
+            },
+            None => Poll::Ready(Err(error::Closed::new().into())),
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/src/tower_test/mock/mod.rs.html b/src/tower_test/mock/mod.rs.html new file mode 100644 index 0000000..539a772 --- /dev/null +++ b/src/tower_test/mock/mod.rs.html @@ -0,0 +1,631 @@ +mod.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
+
+//! Mock `Service` that can be used in tests.
+
+pub mod error;
+pub mod future;
+pub mod spawn;
+
+pub use spawn::Spawn;
+
+use crate::mock::{error::Error, future::ResponseFuture};
+use core::task::Waker;
+
+use tokio::sync::{mpsc, oneshot};
+use tower_layer::Layer;
+use tower_service::Service;
+
+use std::{
+    collections::HashMap,
+    future::Future,
+    sync::{Arc, Mutex},
+    task::{Context, Poll},
+    u64,
+};
+
+/// Spawn a layer onto a mock service.
+pub fn spawn_layer<T, U, L>(layer: L) -> (Spawn<L::Service>, Handle<T, U>)
+where
+    L: Layer<Mock<T, U>>,
+{
+    let (inner, handle) = pair();
+    let svc = layer.layer(inner);
+
+    (Spawn::new(svc), handle)
+}
+
+/// Spawn a Service onto a mock task.
+pub fn spawn<T, U>() -> (Spawn<Mock<T, U>>, Handle<T, U>) {
+    let (svc, handle) = pair();
+
+    (Spawn::new(svc), handle)
+}
+
+/// Spawn a Service via the provided wrapper closure.
+pub fn spawn_with<T, U, F, S>(f: F) -> (Spawn<S>, Handle<T, U>)
+where
+    F: Fn(Mock<T, U>) -> S,
+{
+    let (svc, handle) = pair();
+
+    let svc = f(svc);
+
+    (Spawn::new(svc), handle)
+}
+
+/// A mock service
+#[derive(Debug)]
+pub struct Mock<T, U> {
+    id: u64,
+    tx: Mutex<Tx<T, U>>,
+    state: Arc<Mutex<State>>,
+    can_send: bool,
+}
+
+/// Handle to the `Mock`.
+#[derive(Debug)]
+pub struct Handle<T, U> {
+    rx: Rx<T, U>,
+    state: Arc<Mutex<State>>,
+}
+
+type Request<T, U> = (T, SendResponse<U>);
+
+/// Send a response in reply to a received request.
+#[derive(Debug)]
+pub struct SendResponse<T> {
+    tx: oneshot::Sender<Result<T, Error>>,
+}
+
+#[derive(Debug)]
+struct State {
+    /// Tracks the number of requests that can be sent through
+    rem: u64,
+
+    /// Tasks that are blocked
+    tasks: HashMap<u64, Waker>,
+
+    /// Tracks if the `Handle` dropped
+    is_closed: bool,
+
+    /// Tracks the ID for the next mock clone
+    next_clone_id: u64,
+
+    /// Tracks the next error to yield (if any)
+    err_with: Option<Error>,
+}
+
+type Tx<T, U> = mpsc::UnboundedSender<Request<T, U>>;
+type Rx<T, U> = mpsc::UnboundedReceiver<Request<T, U>>;
+
+/// Create a new `Mock` and `Handle` pair.
+pub fn pair<T, U>() -> (Mock<T, U>, Handle<T, U>) {
+    let (tx, rx) = mpsc::unbounded_channel();
+    let tx = Mutex::new(tx);
+
+    let state = Arc::new(Mutex::new(State::new()));
+
+    let mock = Mock {
+        id: 0,
+        tx,
+        state: state.clone(),
+        can_send: false,
+    };
+
+    let handle = Handle { rx, state };
+
+    (mock, handle)
+}
+
+impl<T, U> Service<T> for Mock<T, U> {
+    type Response = U;
+    type Error = Error;
+    type Future = ResponseFuture<U>;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        let mut state = self.state.lock().unwrap();
+
+        if state.is_closed {
+            return Poll::Ready(Err(error::Closed::new().into()));
+        }
+
+        if let Some(e) = state.err_with.take() {
+            return Poll::Ready(Err(e));
+        }
+
+        if self.can_send {
+            return Poll::Ready(Ok(()));
+        }
+
+        if state.rem > 0 {
+            assert!(!state.tasks.contains_key(&self.id));
+
+            // Returning `Ready` means the next call to `call` must succeed.
+            self.can_send = true;
+
+            Poll::Ready(Ok(()))
+        } else {
+            // Bit weird... but whatevz
+            *state
+                .tasks
+                .entry(self.id)
+                .or_insert_with(|| cx.waker().clone()) = cx.waker().clone();
+
+            Poll::Pending
+        }
+    }
+
+    fn call(&mut self, request: T) -> Self::Future {
+        // Make sure that the service has capacity
+        let mut state = self.state.lock().unwrap();
+
+        if state.is_closed {
+            return ResponseFuture::closed();
+        }
+
+        if !self.can_send {
+            panic!("service not ready; poll_ready must be called first");
+        }
+
+        self.can_send = false;
+
+        // Decrement the number of remaining requests that can be sent
+        if state.rem > 0 {
+            state.rem -= 1;
+        }
+
+        let (tx, rx) = oneshot::channel();
+        let send_response = SendResponse { tx };
+
+        match self.tx.lock().unwrap().send((request, send_response)) {
+            Ok(_) => {}
+            Err(_) => {
+                // TODO: Can this be reached
+                return ResponseFuture::closed();
+            }
+        }
+
+        ResponseFuture::new(rx)
+    }
+}
+
+impl<T, U> Clone for Mock<T, U> {
+    fn clone(&self) -> Self {
+        let id = {
+            let mut state = self.state.lock().unwrap();
+            let id = state.next_clone_id;
+
+            state.next_clone_id += 1;
+
+            id
+        };
+
+        let tx = Mutex::new(self.tx.lock().unwrap().clone());
+
+        Mock {
+            id,
+            tx,
+            state: self.state.clone(),
+            can_send: false,
+        }
+    }
+}
+
+impl<T, U> Drop for Mock<T, U> {
+    fn drop(&mut self) {
+        let mut state = match self.state.lock() {
+            Ok(v) => v,
+            Err(e) => {
+                if ::std::thread::panicking() {
+                    return;
+                }
+
+                panic!("{:?}", e);
+            }
+        };
+
+        state.tasks.remove(&self.id);
+    }
+}
+
+// ===== impl Handle =====
+
+impl<T, U> Handle<T, U> {
+    /// Asynchronously gets the next request
+    pub fn poll_request(&mut self) -> Poll<Option<Request<T, U>>> {
+        tokio_test::task::spawn(()).enter(|cx, _| Box::pin(self.rx.recv()).as_mut().poll(cx))
+    }
+
+    /// Gets the next request.
+    pub async fn next_request(&mut self) -> Option<Request<T, U>> {
+        self.rx.recv().await
+    }
+
+    /// Allow a certain number of requests
+    pub fn allow(&mut self, num: u64) {
+        let mut state = self.state.lock().unwrap();
+        state.rem = num;
+
+        if num > 0 {
+            for (_, task) in state.tasks.drain() {
+                task.wake();
+            }
+        }
+    }
+
+    /// Make the next poll_ method error with the given error.
+    pub fn send_error<E: Into<Error>>(&mut self, e: E) {
+        let mut state = self.state.lock().unwrap();
+        state.err_with = Some(e.into());
+
+        for (_, task) in state.tasks.drain() {
+            task.wake();
+        }
+    }
+}
+
+impl<T, U> Drop for Handle<T, U> {
+    fn drop(&mut self) {
+        let mut state = match self.state.lock() {
+            Ok(v) => v,
+            Err(e) => {
+                if ::std::thread::panicking() {
+                    return;
+                }
+
+                panic!("{:?}", e);
+            }
+        };
+
+        state.is_closed = true;
+
+        for (_, task) in state.tasks.drain() {
+            task.wake();
+        }
+    }
+}
+
+// ===== impl SendResponse =====
+
+impl<T> SendResponse<T> {
+    /// Resolve the pending request future for the linked request with the given response.
+    pub fn send_response(self, response: T) {
+        // TODO: Should the result be dropped?
+        let _ = self.tx.send(Ok(response));
+    }
+
+    /// Resolve the pending request future for the linked request with the given error.
+    pub fn send_error<E: Into<Error>>(self, err: E) {
+        // TODO: Should the result be dropped?
+        let _ = self.tx.send(Err(err.into()));
+    }
+}
+
+// ===== impl State =====
+
+impl State {
+    fn new() -> State {
+        State {
+            rem: u64::MAX,
+            tasks: HashMap::new(),
+            is_closed: false,
+            next_clone_id: 1,
+            err_with: None,
+        }
+    }
+}
+
+
\ No newline at end of file diff --git a/src/tower_test/mock/spawn.rs.html b/src/tower_test/mock/spawn.rs.html new file mode 100644 index 0000000..394e895 --- /dev/null +++ b/src/tower_test/mock/spawn.rs.html @@ -0,0 +1,147 @@ +spawn.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
+
+//! Spawn mock services onto a mock task.
+
+use std::task::Poll;
+use tokio_test::task;
+use tower_service::Service;
+
+/// Service spawned on a mock task
+#[derive(Debug)]
+pub struct Spawn<T> {
+    inner: T,
+    task: task::Spawn<()>,
+}
+
+impl<T> Spawn<T> {
+    /// Create a new spawn.
+    pub fn new(inner: T) -> Self {
+        Self {
+            inner,
+            task: task::spawn(()),
+        }
+    }
+
+    /// Check if this service has been woken up.
+    pub fn is_woken(&self) -> bool {
+        self.task.is_woken()
+    }
+
+    /// Get how many futurs are holding onto the waker.
+    pub fn waker_ref_count(&self) -> usize {
+        self.task.waker_ref_count()
+    }
+
+    /// Poll this service ready.
+    pub fn poll_ready<Request>(&mut self) -> Poll<Result<(), T::Error>>
+    where
+        T: Service<Request>,
+    {
+        let task = &mut self.task;
+        let inner = &mut self.inner;
+
+        task.enter(|cx, _| inner.poll_ready(cx))
+    }
+
+    /// Call the inner Service.
+    pub fn call<Request>(&mut self, req: Request) -> T::Future
+    where
+        T: Service<Request>,
+    {
+        self.inner.call(req)
+    }
+
+    /// Get the inner service.
+    pub fn into_inner(self) -> T {
+        self.inner
+    }
+
+    /// Get a reference to the inner service.
+    pub fn get_ref(&self) -> &T {
+        &self.inner
+    }
+
+    /// Get a mutable reference to the inner service.
+    pub fn get_mut(&mut self) -> &mut T {
+        &mut self.inner
+    }
+}
+
+impl<T: Clone> Clone for Spawn<T> {
+    fn clone(&self) -> Self {
+        Spawn::new(self.inner.clone())
+    }
+}
+
+
\ No newline at end of file diff --git a/storage.js b/storage.js new file mode 100644 index 0000000..fdc5f96 --- /dev/null +++ b/storage.js @@ -0,0 +1 @@ +var resourcesSuffix="";var currentTheme=document.getElementById("themeStyle");var mainTheme=document.getElementById("mainThemeStyle");var savedHref=[];function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(!elem||!elem.classList){return}elem.classList.add(className)}function removeClass(elem,className){if(!elem||!elem.classList){return}elem.classList.remove(className)}function onEach(arr,func,reversed){if(arr&&arr.length>0&&func){var length=arr.length;if(reversed!==true){for(var i=0;i=0;--i){if(func(arr[i])===true){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function usableLocalStorage(){if(typeof Storage==="undefined"){return false}try{return window.localStorage!==null&&window.localStorage!==undefined}catch(err){return false}}function updateLocalStorage(name,value){if(usableLocalStorage()){localStorage[name]=value}else{}}function getCurrentValue(name){if(usableLocalStorage()&&localStorage[name]!==undefined){return localStorage[name]}return null}function switchTheme(styleElem,mainStyleElem,newTheme,saveTheme){var fullBasicCss="rustdoc"+resourcesSuffix+".css";var fullNewTheme=newTheme+resourcesSuffix+".css";var newHref=mainStyleElem.href.replace(fullBasicCss,fullNewTheme);if(styleElem.href===newHref){return}var found=false;if(savedHref.length===0){onEachLazy(document.getElementsByTagName("link"),function(el){savedHref.push(el.href)})}onEach(savedHref,function(el){if(el===newHref){found=true;return true}});if(found===true){styleElem.href=newHref;if(saveTheme===true){updateLocalStorage("rustdoc-theme",newTheme)}}}function getSystemValue(){var property=getComputedStyle(document.documentElement).getPropertyValue('content');return property.replace(/[\"\']/g,"")}switchTheme(currentTheme,mainTheme,getCurrentValue("rustdoc-theme")||getSystemValue()||"light",false) \ No newline at end of file diff --git a/theme.js b/theme.js new file mode 100644 index 0000000..ebd1a87 --- /dev/null +++ b/theme.js @@ -0,0 +1 @@ +var themes=document.getElementById("theme-choices");var themePicker=document.getElementById("theme-picker");function showThemeButtonState(){themes.style.display="block";themePicker.style.borderBottomRightRadius="0";themePicker.style.borderBottomLeftRadius="0"}function hideThemeButtonState(){themes.style.display="none";themePicker.style.borderBottomRightRadius="3px";themePicker.style.borderBottomLeftRadius="3px"}function switchThemeButtonState(){if(themes.style.display==="block"){hideThemeButtonState()}else{showThemeButtonState()}};function handleThemeButtonsBlur(e){var active=document.activeElement;var related=e.relatedTarget;if(active.id!=="themePicker"&&(!active.parentNode||active.parentNode.id!=="theme-choices")&&(!related||(related.id!=="themePicker"&&(!related.parentNode||related.parentNode.id!=="theme-choices")))){hideThemeButtonState()}}themePicker.onclick=switchThemeButtonState;themePicker.onblur=handleThemeButtonsBlur;["dark","light"].forEach(function(item){var but=document.createElement('button');but.textContent=item;but.onclick=function(el){switchTheme(currentTheme,mainTheme,item,true)};but.onblur=handleThemeButtonsBlur;themes.appendChild(but)}) \ No newline at end of file diff --git a/tower/all.html b/tower/all.html new file mode 100644 index 0000000..e96c9a0 --- /dev/null +++ b/tower/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Traits

Typedefs

\ No newline at end of file diff --git a/tower/builder/index.html b/tower/builder/index.html new file mode 100644 index 0000000..d236c29 --- /dev/null +++ b/tower/builder/index.html @@ -0,0 +1,4 @@ +tower::builder - Rust

[][src]Module tower::builder

Builder types to compose layers and services

+

Structs

+
ServiceBuilder

Declaratively construct Service values.

+
\ No newline at end of file diff --git a/tower/builder/sidebar-items.js b/tower/builder/sidebar-items.js new file mode 100644 index 0000000..954cd50 --- /dev/null +++ b/tower/builder/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["ServiceBuilder","Declaratively construct Service values."]]}); \ No newline at end of file diff --git a/tower/builder/struct.ServiceBuilder.html b/tower/builder/struct.ServiceBuilder.html new file mode 100644 index 0000000..68a8899 --- /dev/null +++ b/tower/builder/struct.ServiceBuilder.html @@ -0,0 +1,74 @@ +tower::builder::ServiceBuilder - Rust

[][src]Struct tower::builder::ServiceBuilder

pub struct ServiceBuilder<L> { /* fields omitted */ }

Declaratively construct Service values.

+

ServiceBuilder provides a builder-like interface for composing +layers to be applied to a Service.

+

Service

+

A Service is a trait representing an +asynchronous function of a request to a response. It is similar to async fn(Request) -> Result<Response, Error>.

+

A Service is typically bound to a single transport, such as a TCP +connection. It defines how all inbound or outbound requests are handled +by that connection.

+

Order

+

The order in which layers are added impacts how requests are handled. Layers +that are added first will be called with the request first. The argument to +service will be last to see the request.

+ +
+#[cfg(all(feature = "buffer", feature = "limit"))]
+ServiceBuilder::new()
+    .buffer(100)
+    .concurrency_limit(10)
+    .service(svc)
+

In the above example, the buffer layer receives the request first followed +by concurrency_limit. buffer enables up to 100 request to be in-flight +on top of the requests that have already been forwarded to the next +layer. Combined with concurrency_limit, this allows up to 110 requests to be +in-flight.

+ +
+#[cfg(all(feature = "buffer", feature = "limit"))]
+ServiceBuilder::new()
+    .concurrency_limit(10)
+    .buffer(100)
+    .service(svc)
+

The above example is similar, but the order of layers is reversed. Now, +concurrency_limit applies first and only allows 10 requests to be in-flight +total.

+

Examples

+

A Service stack with a single layer:

+ +
+#[cfg(feature = "limit")]
+ServiceBuilder::new()
+    .concurrency_limit(5)
+    .service(svc);
+

A Service stack with multiple layers that contain rate limiting, +in-flight request limits, and a channel-backed, clonable Service:

+ +
+#[cfg(all(feature = "buffer", feature = "limit"))]
+ServiceBuilder::new()
+    .buffer(5)
+    .concurrency_limit(5)
+    .rate_limit(5, Duration::from_secs(1))
+    .service(svc);
+

Methods

impl ServiceBuilder<Identity>[src]

pub fn new() -> Self[src]

Create a new ServiceBuilder.

+

impl<L> ServiceBuilder<L>[src]

pub fn layer<T>(self, layer: T) -> ServiceBuilder<Stack<T, L>>[src]

Add a new layer T into the ServiceBuilder.

+

pub fn into_inner(self) -> L[src]

Obtains the underlying Layer implementation.

+

pub fn service<S>(self, service: S) -> L::Service where
    L: Layer<S>, 
[src]

Wrap the service S with the layers.

+

Trait Implementations

impl<L: Clone> Clone for ServiceBuilder<L>[src]

impl<L: Debug> Debug for ServiceBuilder<L>[src]

Auto Trait Implementations

impl<L> RefUnwindSafe for ServiceBuilder<L> where
    L: RefUnwindSafe

impl<L> Send for ServiceBuilder<L> where
    L: Send

impl<L> Sync for ServiceBuilder<L> where
    L: Sync

impl<L> Unpin for ServiceBuilder<L> where
    L: Unpin

impl<L> UnwindSafe for ServiceBuilder<L> where
    L: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower/index.html b/tower/index.html new file mode 100644 index 0000000..1f69fb5 --- /dev/null +++ b/tower/index.html @@ -0,0 +1,14 @@ +tower - Rust

[][src]Crate tower

fn(Request) -> Future<Response>

+

Tower is a library of modular and reusable components for building +robust networking clients and servers.

+

Modules

+
builder

Builder types to compose layers and services

+
layer

A collection of Layer based tower services

+

Structs

+
ServiceBuilder

Declaratively construct Service values.

+

Traits

+
Layer

Decorates a Service, transforming either the request or the response.

+
Service

An asynchronous function from a Request to a Response.

+

Type Definitions

+
BoxError

Alias for a type-erased error type.

+
\ No newline at end of file diff --git a/tower/layer/index.html b/tower/layer/index.html new file mode 100644 index 0000000..69f4b7d --- /dev/null +++ b/tower/layer/index.html @@ -0,0 +1,6 @@ +tower::layer - Rust

[][src]Module tower::layer

A collection of Layer based tower services

+

Modules

+
util

util exports an Identity Layer and Chain, a mechanism for chaining them.

+

Traits

+
Layer

Decorates a Service, transforming either the request or the response.

+
\ No newline at end of file diff --git a/tower/layer/sidebar-items.js b/tower/layer/sidebar-items.js new file mode 100644 index 0000000..12d0cb6 --- /dev/null +++ b/tower/layer/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"mod":[["util","`util` exports an Identity Layer and Chain, a mechanism for chaining them."]],"trait":[["Layer","Decorates a `Service`, transforming either the request or the response."]]}); \ No newline at end of file diff --git a/tower/layer/trait.Layer.html b/tower/layer/trait.Layer.html new file mode 100644 index 0000000..89ab3c0 --- /dev/null +++ b/tower/layer/trait.Layer.html @@ -0,0 +1,66 @@ +tower::layer::Layer - Rust

[][src]Trait tower::layer::Layer

pub trait Layer<S> {
+    type Service;
+    fn layer(&self, inner: S) -> Self::Service;
+}

Decorates a Service, transforming either the request or the response.

+

Often, many of the pieces needed for writing network applications can be +reused across multiple services. The Layer trait can be used to write +reusable components that can be applied to very different kinds of services; +for example, it can be applied to services operating on different protocols, +and to both the client and server side of a network transaction.

+

Log

+

Take request logging as an example:

+ +
+
+pub struct LogLayer {
+    target: &'static str,
+}
+
+impl<S> Layer<S> for LogLayer {
+    type Service = LogService<S>;
+
+    fn layer(&self, service: S) -> Self::Service {
+        LogService {
+            target: self.target,
+            service
+        }
+    }
+}
+
+// This service implements the Log behavior
+pub struct LogService<S> {
+    target: &'static str,
+    service: S,
+}
+
+impl<S, Request> Service<Request> for LogService<S>
+where
+    S: Service<Request>,
+    Request: fmt::Debug,
+{
+    type Response = S::Response;
+    type Error = S::Error;
+    type Future = S::Future;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        self.service.poll_ready(cx)
+    }
+
+    fn call(&mut self, request: Request) -> Self::Future {
+        // Insert log statement here or other functionality
+        println!("request = {:?}, target = {:?}", request, self.target);
+        self.service.call(request)
+    }
+}
+

The above log implementation is decoupled from the underlying protocol and +is also decoupled from client or server concerns. In other words, the same +log middleware could be used in either a client or a server.

+
+

Associated Types

type Service

The wrapped service

+
Loading content... +

Required methods

fn layer(&self, inner: S) -> Self::Service

Wrap the given service with the middleware, returning a new service +that has been decorated with the middleware.

+
Loading content... +

Implementations on Foreign Types

impl<'a, T, S> Layer<S> for &'a T where
    T: Layer<S> + ?Sized
[src]

type Service = <T as Layer<S>>::Service

Loading content... +

Implementors

impl<S> Layer<S> for Identity[src]

Decorates a Service, transforming either the request or the response.

+

type Service = S

impl<S, Inner, Outer> Layer<S> for Stack<Inner, Outer> where
    Inner: Layer<S>,
    Outer: Layer<<Inner as Layer<S>>::Service>, 
[src]

type Service = <Outer as Layer<<Inner as Layer<S>>::Service>>::Service

Loading content...
\ No newline at end of file diff --git a/tower/layer/util/index.html b/tower/layer/util/index.html new file mode 100644 index 0000000..9e1d705 --- /dev/null +++ b/tower/layer/util/index.html @@ -0,0 +1,5 @@ +tower::layer::util - Rust

[][src]Module tower::layer::util

util exports an Identity Layer and Chain, a mechanism for chaining them.

+

Structs

+
Identity

A no-op middleware.

+
Stack

Two middlewares chained together.

+
\ No newline at end of file diff --git a/tower/layer/util/sidebar-items.js b/tower/layer/util/sidebar-items.js new file mode 100644 index 0000000..722c6b7 --- /dev/null +++ b/tower/layer/util/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Identity","A no-op middleware."],["Stack","Two middlewares chained together."]]}); \ No newline at end of file diff --git a/tower/layer/util/struct.Identity.html b/tower/layer/util/struct.Identity.html new file mode 100644 index 0000000..e9c342b --- /dev/null +++ b/tower/layer/util/struct.Identity.html @@ -0,0 +1,25 @@ +tower::layer::util::Identity - Rust

[][src]Struct tower::layer::util::Identity

pub struct Identity { /* fields omitted */ }

A no-op middleware.

+

When wrapping a Service, the Identity layer returns the provided +service without modifying it.

+

Methods

impl Identity[src]

pub fn new() -> Identity[src]

Create a new Identity value

+

Trait Implementations

impl Clone for Identity[src]

impl Debug for Identity[src]

impl Default for Identity[src]

impl<S> Layer<S> for Identity[src]

Decorates a Service, transforming either the request or the response.

+

type Service = S

The wrapped service

+

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower/layer/util/struct.Stack.html b/tower/layer/util/struct.Stack.html new file mode 100644 index 0000000..3b3a957 --- /dev/null +++ b/tower/layer/util/struct.Stack.html @@ -0,0 +1,21 @@ +tower::layer::util::Stack - Rust

[][src]Struct tower::layer::util::Stack

pub struct Stack<Inner, Outer> { /* fields omitted */ }

Two middlewares chained together.

+

Methods

impl<Inner, Outer> Stack<Inner, Outer>[src]

pub fn new(inner: Inner, outer: Outer) -> Stack<Inner, Outer>[src]

Create a new Stack.

+

Trait Implementations

impl<Inner, Outer> Clone for Stack<Inner, Outer> where
    Inner: Clone,
    Outer: Clone
[src]

impl<Inner, Outer> Debug for Stack<Inner, Outer> where
    Inner: Debug,
    Outer: Debug
[src]

impl<S, Inner, Outer> Layer<S> for Stack<Inner, Outer> where
    Inner: Layer<S>,
    Outer: Layer<<Inner as Layer<S>>::Service>, 
[src]

type Service = <Outer as Layer<<Inner as Layer<S>>::Service>>::Service

The wrapped service

+

Auto Trait Implementations

impl<Inner, Outer> RefUnwindSafe for Stack<Inner, Outer> where
    Inner: RefUnwindSafe,
    Outer: RefUnwindSafe

impl<Inner, Outer> Send for Stack<Inner, Outer> where
    Inner: Send,
    Outer: Send

impl<Inner, Outer> Sync for Stack<Inner, Outer> where
    Inner: Sync,
    Outer: Sync

impl<Inner, Outer> Unpin for Stack<Inner, Outer> where
    Inner: Unpin,
    Outer: Unpin

impl<Inner, Outer> UnwindSafe for Stack<Inner, Outer> where
    Inner: UnwindSafe,
    Outer: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower/sidebar-items.js b/tower/sidebar-items.js new file mode 100644 index 0000000..bb38a66 --- /dev/null +++ b/tower/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"mod":[["builder","Builder types to compose layers and services"],["layer","A collection of `Layer` based tower services"]],"struct":[["ServiceBuilder","Declaratively construct Service values."]],"trait":[["Layer","Decorates a `Service`, transforming either the request or the response."],["Service","An asynchronous function from a `Request` to a `Response`."]],"type":[["BoxError","Alias for a type-erased error type."]]}); \ No newline at end of file diff --git a/tower/struct.ServiceBuilder.html b/tower/struct.ServiceBuilder.html new file mode 100644 index 0000000..b59281b --- /dev/null +++ b/tower/struct.ServiceBuilder.html @@ -0,0 +1,74 @@ +tower::ServiceBuilder - Rust

[][src]Struct tower::ServiceBuilder

pub struct ServiceBuilder<L> { /* fields omitted */ }

Declaratively construct Service values.

+

ServiceBuilder provides a builder-like interface for composing +layers to be applied to a Service.

+

Service

+

A Service is a trait representing an +asynchronous function of a request to a response. It is similar to async fn(Request) -> Result<Response, Error>.

+

A Service is typically bound to a single transport, such as a TCP +connection. It defines how all inbound or outbound requests are handled +by that connection.

+

Order

+

The order in which layers are added impacts how requests are handled. Layers +that are added first will be called with the request first. The argument to +service will be last to see the request.

+ +
+#[cfg(all(feature = "buffer", feature = "limit"))]
+ServiceBuilder::new()
+    .buffer(100)
+    .concurrency_limit(10)
+    .service(svc)
+

In the above example, the buffer layer receives the request first followed +by concurrency_limit. buffer enables up to 100 request to be in-flight +on top of the requests that have already been forwarded to the next +layer. Combined with concurrency_limit, this allows up to 110 requests to be +in-flight.

+ +
+#[cfg(all(feature = "buffer", feature = "limit"))]
+ServiceBuilder::new()
+    .concurrency_limit(10)
+    .buffer(100)
+    .service(svc)
+

The above example is similar, but the order of layers is reversed. Now, +concurrency_limit applies first and only allows 10 requests to be in-flight +total.

+

Examples

+

A Service stack with a single layer:

+ +
+#[cfg(feature = "limit")]
+ServiceBuilder::new()
+    .concurrency_limit(5)
+    .service(svc);
+

A Service stack with multiple layers that contain rate limiting, +in-flight request limits, and a channel-backed, clonable Service:

+ +
+#[cfg(all(feature = "buffer", feature = "limit"))]
+ServiceBuilder::new()
+    .buffer(5)
+    .concurrency_limit(5)
+    .rate_limit(5, Duration::from_secs(1))
+    .service(svc);
+

Methods

impl ServiceBuilder<Identity>[src]

pub fn new() -> Self[src]

Create a new ServiceBuilder.

+

impl<L> ServiceBuilder<L>[src]

pub fn layer<T>(self, layer: T) -> ServiceBuilder<Stack<T, L>>[src]

Add a new layer T into the ServiceBuilder.

+

pub fn into_inner(self) -> L[src]

Obtains the underlying Layer implementation.

+

pub fn service<S>(self, service: S) -> L::Service where
    L: Layer<S>, 
[src]

Wrap the service S with the layers.

+

Trait Implementations

impl<L: Clone> Clone for ServiceBuilder<L>[src]

impl<L: Debug> Debug for ServiceBuilder<L>[src]

Auto Trait Implementations

impl<L> RefUnwindSafe for ServiceBuilder<L> where
    L: RefUnwindSafe

impl<L> Send for ServiceBuilder<L> where
    L: Send

impl<L> Sync for ServiceBuilder<L> where
    L: Sync

impl<L> Unpin for ServiceBuilder<L> where
    L: Unpin

impl<L> UnwindSafe for ServiceBuilder<L> where
    L: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower/trait.Layer.html b/tower/trait.Layer.html new file mode 100644 index 0000000..08c0b23 --- /dev/null +++ b/tower/trait.Layer.html @@ -0,0 +1,66 @@ +tower::Layer - Rust

[][src]Trait tower::Layer

pub trait Layer<S> {
+    type Service;
+    fn layer(&self, inner: S) -> Self::Service;
+}

Decorates a Service, transforming either the request or the response.

+

Often, many of the pieces needed for writing network applications can be +reused across multiple services. The Layer trait can be used to write +reusable components that can be applied to very different kinds of services; +for example, it can be applied to services operating on different protocols, +and to both the client and server side of a network transaction.

+

Log

+

Take request logging as an example:

+ +
+
+pub struct LogLayer {
+    target: &'static str,
+}
+
+impl<S> Layer<S> for LogLayer {
+    type Service = LogService<S>;
+
+    fn layer(&self, service: S) -> Self::Service {
+        LogService {
+            target: self.target,
+            service
+        }
+    }
+}
+
+// This service implements the Log behavior
+pub struct LogService<S> {
+    target: &'static str,
+    service: S,
+}
+
+impl<S, Request> Service<Request> for LogService<S>
+where
+    S: Service<Request>,
+    Request: fmt::Debug,
+{
+    type Response = S::Response;
+    type Error = S::Error;
+    type Future = S::Future;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        self.service.poll_ready(cx)
+    }
+
+    fn call(&mut self, request: Request) -> Self::Future {
+        // Insert log statement here or other functionality
+        println!("request = {:?}, target = {:?}", request, self.target);
+        self.service.call(request)
+    }
+}
+

The above log implementation is decoupled from the underlying protocol and +is also decoupled from client or server concerns. In other words, the same +log middleware could be used in either a client or a server.

+
+

Associated Types

type Service

The wrapped service

+
Loading content... +

Required methods

fn layer(&self, inner: S) -> Self::Service

Wrap the given service with the middleware, returning a new service +that has been decorated with the middleware.

+
Loading content... +

Implementations on Foreign Types

impl<'a, T, S> Layer<S> for &'a T where
    T: Layer<S> + ?Sized
[src]

type Service = <T as Layer<S>>::Service

Loading content... +

Implementors

impl<S> Layer<S> for Identity[src]

Decorates a Service, transforming either the request or the response.

+

type Service = S

impl<S, Inner, Outer> Layer<S> for Stack<Inner, Outer> where
    Inner: Layer<S>,
    Outer: Layer<<Inner as Layer<S>>::Service>, 
[src]

type Service = <Outer as Layer<<Inner as Layer<S>>::Service>>::Service

Loading content...
\ No newline at end of file diff --git a/tower/trait.Service.html b/tower/trait.Service.html new file mode 100644 index 0000000..56bd037 --- /dev/null +++ b/tower/trait.Service.html @@ -0,0 +1,189 @@ +tower::Service - Rust

[][src]Trait tower::Service

pub trait Service<Request> where
    <Self::Future as Future>::Output == Result<Self::Response, Self::Error>, 
{ + type Response; + type Error; + type Future: Future; + fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>>; +
fn call(&mut self, req: Request) -> Self::Future; +}

An asynchronous function from a Request to a Response.

+

The Service trait is a simplified interface making it easy to write +network applications in a modular and reusable way, decoupled from the +underlying protocol. It is one of Tower's fundamental abstractions.

+

Functional

+

A Service is a function of a Request. It immediately returns a +Future representing the eventual completion of processing the +request. The actual request processing may happen at any time in the +future, on any thread or executor. The processing may depend on calling +other services. At some point in the future, the processing will complete, +and the Future will resolve to a response or error.

+

At a high level, the Service::call function represents an RPC request. The +Service value can be a server or a client.

+

Server

+

An RPC server implements the Service trait. Requests received by the +server over the network are deserialized and then passed as an argument to the +server value. The returned response is sent back over the network.

+

As an example, here is how an HTTP request is processed by a server:

+ +
+
+use http::{Request, Response, StatusCode};
+
+struct HelloWorld;
+
+impl Service<Request<Vec<u8>>> for HelloWorld {
+    type Response = Response<Vec<u8>>;
+    type Error = http::Error;
+    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        Poll::Ready(Ok(()))
+    }
+
+    fn call(&mut self, req: Request<Vec<u8>>) -> Self::Future {
+        // create the body
+        let body: Vec<u8> = "hello, world!\n"
+            .as_bytes()
+            .to_owned();
+        // Create the HTTP response
+        let resp = Response::builder()
+            .status(StatusCode::OK)
+            .body(body)
+            .expect("Unable to create `http::Response`");
+         
+        // create a response in a future.
+        let fut = async {
+            Ok(resp)
+        };
+
+        // Return the response as an immediate future
+        Box::pin(fut)
+    }
+}
+

Client

+

A client consumes a service by using a Service value. The client may +issue requests by invoking call and passing the request as an argument. +It then receives the response by waiting for the returned future.

+

As an example, here is how a Redis request would be issued:

+ +
This example is not tested
+let client = redis::Client::new()
+    .connect("127.0.0.1:6379".parse().unwrap())
+    .unwrap();
+
+let resp = client.call(Cmd::set("foo", "this is the value of foo")).await?;
+
+// Wait for the future to resolve
+println!("Redis response: {:?}", resp);
+

Middleware / Layer

+

More often than not, all the pieces needed for writing robust, scalable +network applications are the same no matter the underlying protocol. By +unifying the API for both clients and servers in a protocol agnostic way, +it is possible to write middleware that provide these pieces in a +reusable way.

+

Take timeouts as an example:

+ +
This example is not tested
+use tower_service::Service;
+use tower_layer::Layer;
+use futures::FutureExt;
+use std::future::Future;
+use std::task::{Context, Poll};
+use std::time::Duration;
+use std::pin::Pin;
+
+
+pub struct Timeout<T> {
+    inner: T,
+    timeout: Duration,
+}
+
+pub struct TimeoutLayer(Duration);
+
+pub struct Expired;
+
+impl<T> Timeout<T> {
+    pub fn new(inner: T, timeout: Duration) -> Timeout<T> {
+        Timeout {
+            inner,
+            timeout
+        }
+    }
+}
+
+impl<T, Request> Service<Request> for Timeout<T>
+where
+    T: Service<Request>,
+    T::Future: 'static,
+    T::Error: From<Expired> + 'static,
+    T::Response: 'static
+{
+    type Response = T::Response;
+    type Error = T::Error;
+    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+       self.inner.poll_ready(cx).map_err(Into::into)
+    }
+
+    fn call(&mut self, req: Request) -> Self::Future {
+        let timeout = tokio_timer::delay_for(self.timeout)
+            .map(|_| Err(Self::Error::from(Expired)));
+
+        let fut = Box::pin(self.inner.call(req));
+        let f = futures::select(fut, timeout)
+            .map(|either| either.factor_first().0);
+
+        Box::pin(f)
+    }
+}
+
+impl TimeoutLayer {
+    pub fn new(delay: Duration) -> Self {
+        TimeoutLayer(delay)
+    }
+}
+
+impl<S> Layer<S> for TimeoutLayer
+{
+    type Service = Timeout<S>;
+
+    fn layer(&self, service: S) -> Timeout<S> {
+        Timeout::new(service, self.0)
+    }
+}
+
+

The above timeout implementation is decoupled from the underlying protocol +and is also decoupled from client or server concerns. In other words, the +same timeout middleware could be used in either a client or a server.

+

Backpressure

+

Calling a Service which is at capacity (i.e., it is temporarily unable to process a +request) should result in an error. The caller is responsible for ensuring +that the service is ready to receive the request before calling it.

+

Service provides a mechanism by which the caller is able to coordinate +readiness. Service::poll_ready returns Ready if the service expects that +it is able to process a request.

+
+

Associated Types

type Response

Responses given by the service.

+

type Error

Errors produced by the service.

+

type Future: Future

The future response value.

+
Loading content... +

Required methods

fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>>

Returns Poll::Ready(Ok(())) when the service is able to process requests.

+

If the service is at capacity, then Poll::Pending is returned and the task +is notified when the service becomes ready again. This function is +expected to be called while on a task. Generally, this can be done with +a simple futures::future::poll_fn call.

+

If Poll::Ready(Err(_)) is returned, the service is no longer able to service requests +and the caller should discard the service instance.

+

Once poll_ready returns Poll::Ready(Ok(())), a request may be dispatched to the +service using call. Until a request is dispatched, repeated calls to +poll_ready must return either Poll::Ready(Ok(())) or Poll::Ready(Err(_)).

+

fn call(&mut self, req: Request) -> Self::Future

Process the request and return the response asynchronously.

+

This function is expected to be callable off task. As such, +implementations should take care to not call poll_ready.

+

Before dispatching a request, poll_ready must be called and return +Poll::Ready(Ok(())).

+

Panics

+

Implementations are permitted to panic if call is invoked without +obtaining Poll::Ready(Ok(())) from poll_ready.

+
Loading content... +

Implementations on Foreign Types

impl<'a, S, Request> Service<Request> for &'a mut S where
    S: Service<Request> + 'a, 
[src]

type Response = <S as Service<Request>>::Response

type Error = <S as Service<Request>>::Error

type Future = <S as Service<Request>>::Future

impl<S, Request> Service<Request> for Box<S> where
    S: Service<Request> + ?Sized
[src]

type Response = <S as Service<Request>>::Response

type Error = <S as Service<Request>>::Error

type Future = <S as Service<Request>>::Future

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/tower/type.BoxError.html b/tower/type.BoxError.html new file mode 100644 index 0000000..4c14730 --- /dev/null +++ b/tower/type.BoxError.html @@ -0,0 +1,2 @@ +tower::BoxError - Rust

[][src]Type Definition tower::BoxError

type BoxError = Box<dyn Error + Send + Sync>;

Alias for a type-erased error type.

+
\ No newline at end of file diff --git a/tower_layer/all.html b/tower_layer/all.html new file mode 100644 index 0000000..39e5c89 --- /dev/null +++ b/tower_layer/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Traits

\ No newline at end of file diff --git a/tower_layer/identity/struct.Identity.html b/tower_layer/identity/struct.Identity.html new file mode 100644 index 0000000..f1d9e90 --- /dev/null +++ b/tower_layer/identity/struct.Identity.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../tower_layer/struct.Identity.html...

+ + + \ No newline at end of file diff --git a/tower_layer/index.html b/tower_layer/index.html new file mode 100644 index 0000000..066008e --- /dev/null +++ b/tower_layer/index.html @@ -0,0 +1,10 @@ +tower_layer - Rust

[][src]Crate tower_layer

Layer traits and extensions.

+

A layer decorates an service and provides additional functionality. It +allows other services to be composed with the service that implements layer.

+

A middleware implements the [Layer] and [Service] trait.

+

Structs

+
Identity

A no-op middleware.

+
Stack

Two middlewares chained together.

+

Traits

+
Layer

Decorates a Service, transforming either the request or the response.

+
\ No newline at end of file diff --git a/tower_layer/sidebar-items.js b/tower_layer/sidebar-items.js new file mode 100644 index 0000000..c1f5d5c --- /dev/null +++ b/tower_layer/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Identity","A no-op middleware."],["Stack","Two middlewares chained together."]],"trait":[["Layer","Decorates a `Service`, transforming either the request or the response."]]}); \ No newline at end of file diff --git a/tower_layer/stack/struct.Stack.html b/tower_layer/stack/struct.Stack.html new file mode 100644 index 0000000..586ef24 --- /dev/null +++ b/tower_layer/stack/struct.Stack.html @@ -0,0 +1,10 @@ + + + + + + +

Redirecting to ../../tower_layer/struct.Stack.html...

+ + + \ No newline at end of file diff --git a/tower_layer/struct.Identity.html b/tower_layer/struct.Identity.html new file mode 100644 index 0000000..70d9d5c --- /dev/null +++ b/tower_layer/struct.Identity.html @@ -0,0 +1,25 @@ +tower_layer::Identity - Rust

[][src]Struct tower_layer::Identity

pub struct Identity { /* fields omitted */ }

A no-op middleware.

+

When wrapping a Service, the Identity layer returns the provided +service without modifying it.

+

Methods

impl Identity[src]

pub fn new() -> Identity[src]

Create a new Identity value

+

Trait Implementations

impl Clone for Identity[src]

impl Debug for Identity[src]

impl Default for Identity[src]

impl<S> Layer<S> for Identity[src]

Decorates a Service, transforming either the request or the response.

+

type Service = S

The wrapped service

+

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower_layer/struct.Stack.html b/tower_layer/struct.Stack.html new file mode 100644 index 0000000..ed7969c --- /dev/null +++ b/tower_layer/struct.Stack.html @@ -0,0 +1,21 @@ +tower_layer::Stack - Rust

[][src]Struct tower_layer::Stack

pub struct Stack<Inner, Outer> { /* fields omitted */ }

Two middlewares chained together.

+

Methods

impl<Inner, Outer> Stack<Inner, Outer>[src]

pub fn new(inner: Inner, outer: Outer) -> Self[src]

Create a new Stack.

+

Trait Implementations

impl<Inner: Clone, Outer: Clone> Clone for Stack<Inner, Outer>[src]

impl<Inner, Outer> Debug for Stack<Inner, Outer> where
    Inner: Debug,
    Outer: Debug
[src]

impl<S, Inner, Outer> Layer<S> for Stack<Inner, Outer> where
    Inner: Layer<S>,
    Outer: Layer<Inner::Service>, 
[src]

type Service = Outer::Service

The wrapped service

+

Auto Trait Implementations

impl<Inner, Outer> RefUnwindSafe for Stack<Inner, Outer> where
    Inner: RefUnwindSafe,
    Outer: RefUnwindSafe

impl<Inner, Outer> Send for Stack<Inner, Outer> where
    Inner: Send,
    Outer: Send

impl<Inner, Outer> Sync for Stack<Inner, Outer> where
    Inner: Sync,
    Outer: Sync

impl<Inner, Outer> Unpin for Stack<Inner, Outer> where
    Inner: Unpin,
    Outer: Unpin

impl<Inner, Outer> UnwindSafe for Stack<Inner, Outer> where
    Inner: UnwindSafe,
    Outer: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower_layer/trait.Layer.html b/tower_layer/trait.Layer.html new file mode 100644 index 0000000..a13ca35 --- /dev/null +++ b/tower_layer/trait.Layer.html @@ -0,0 +1,66 @@ +tower_layer::Layer - Rust

[][src]Trait tower_layer::Layer

pub trait Layer<S> {
+    type Service;
+    fn layer(&self, inner: S) -> Self::Service;
+}

Decorates a Service, transforming either the request or the response.

+

Often, many of the pieces needed for writing network applications can be +reused across multiple services. The Layer trait can be used to write +reusable components that can be applied to very different kinds of services; +for example, it can be applied to services operating on different protocols, +and to both the client and server side of a network transaction.

+

Log

+

Take request logging as an example:

+ +
+
+pub struct LogLayer {
+    target: &'static str,
+}
+
+impl<S> Layer<S> for LogLayer {
+    type Service = LogService<S>;
+
+    fn layer(&self, service: S) -> Self::Service {
+        LogService {
+            target: self.target,
+            service
+        }
+    }
+}
+
+// This service implements the Log behavior
+pub struct LogService<S> {
+    target: &'static str,
+    service: S,
+}
+
+impl<S, Request> Service<Request> for LogService<S>
+where
+    S: Service<Request>,
+    Request: fmt::Debug,
+{
+    type Response = S::Response;
+    type Error = S::Error;
+    type Future = S::Future;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        self.service.poll_ready(cx)
+    }
+
+    fn call(&mut self, request: Request) -> Self::Future {
+        // Insert log statement here or other functionality
+        println!("request = {:?}, target = {:?}", request, self.target);
+        self.service.call(request)
+    }
+}
+

The above log implementation is decoupled from the underlying protocol and +is also decoupled from client or server concerns. In other words, the same +log middleware could be used in either a client or a server.

+
+

Associated Types

type Service

The wrapped service

+
Loading content... +

Required methods

fn layer(&self, inner: S) -> Self::Service

Wrap the given service with the middleware, returning a new service +that has been decorated with the middleware.

+
Loading content... +

Implementations on Foreign Types

impl<'a, T: ?Sized, S> Layer<S> for &'a T where
    T: Layer<S>, 
[src]

type Service = T::Service

Loading content... +

Implementors

impl<S> Layer<S> for Identity[src]

Decorates a Service, transforming either the request or the response.

+

type Service = S

impl<S, Inner, Outer> Layer<S> for Stack<Inner, Outer> where
    Inner: Layer<S>,
    Outer: Layer<Inner::Service>, 
[src]

type Service = Outer::Service

Loading content...
\ No newline at end of file diff --git a/tower_service/all.html b/tower_service/all.html new file mode 100644 index 0000000..f49d05e --- /dev/null +++ b/tower_service/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Traits

\ No newline at end of file diff --git a/tower_service/index.html b/tower_service/index.html new file mode 100644 index 0000000..dade563 --- /dev/null +++ b/tower_service/index.html @@ -0,0 +1,7 @@ +tower_service - Rust

[][src]Crate tower_service

Definition of the core Service trait to Tower

+

The [Service] trait provides the necessary abstractions for defining +request / response clients and servers. It is simple but powerful and is +used as the foundation for the rest of Tower.

+

Traits

+
Service

An asynchronous function from a Request to a Response.

+
\ No newline at end of file diff --git a/tower_service/sidebar-items.js b/tower_service/sidebar-items.js new file mode 100644 index 0000000..f214dad --- /dev/null +++ b/tower_service/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"trait":[["Service","An asynchronous function from a `Request` to a `Response`."]]}); \ No newline at end of file diff --git a/tower_service/trait.Service.html b/tower_service/trait.Service.html new file mode 100644 index 0000000..498f70c --- /dev/null +++ b/tower_service/trait.Service.html @@ -0,0 +1,189 @@ +tower_service::Service - Rust

[][src]Trait tower_service::Service

pub trait Service<Request> {
+    type Response;
+    type Error;
+    type Future: Future<Output = Result<Self::Response, Self::Error>>;
+    fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>>;
+
fn call(&mut self, req: Request) -> Self::Future; +}

An asynchronous function from a Request to a Response.

+

The Service trait is a simplified interface making it easy to write +network applications in a modular and reusable way, decoupled from the +underlying protocol. It is one of Tower's fundamental abstractions.

+

Functional

+

A Service is a function of a Request. It immediately returns a +Future representing the eventual completion of processing the +request. The actual request processing may happen at any time in the +future, on any thread or executor. The processing may depend on calling +other services. At some point in the future, the processing will complete, +and the Future will resolve to a response or error.

+

At a high level, the Service::call function represents an RPC request. The +Service value can be a server or a client.

+

Server

+

An RPC server implements the Service trait. Requests received by the +server over the network are deserialized and then passed as an argument to the +server value. The returned response is sent back over the network.

+

As an example, here is how an HTTP request is processed by a server:

+ +
+
+use http::{Request, Response, StatusCode};
+
+struct HelloWorld;
+
+impl Service<Request<Vec<u8>>> for HelloWorld {
+    type Response = Response<Vec<u8>>;
+    type Error = http::Error;
+    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        Poll::Ready(Ok(()))
+    }
+
+    fn call(&mut self, req: Request<Vec<u8>>) -> Self::Future {
+        // create the body
+        let body: Vec<u8> = "hello, world!\n"
+            .as_bytes()
+            .to_owned();
+        // Create the HTTP response
+        let resp = Response::builder()
+            .status(StatusCode::OK)
+            .body(body)
+            .expect("Unable to create `http::Response`");
+         
+        // create a response in a future.
+        let fut = async {
+            Ok(resp)
+        };
+
+        // Return the response as an immediate future
+        Box::pin(fut)
+    }
+}
+

Client

+

A client consumes a service by using a Service value. The client may +issue requests by invoking call and passing the request as an argument. +It then receives the response by waiting for the returned future.

+

As an example, here is how a Redis request would be issued:

+ +
This example is not tested
+let client = redis::Client::new()
+    .connect("127.0.0.1:6379".parse().unwrap())
+    .unwrap();
+
+let resp = client.call(Cmd::set("foo", "this is the value of foo")).await?;
+
+// Wait for the future to resolve
+println!("Redis response: {:?}", resp);
+

Middleware / Layer

+

More often than not, all the pieces needed for writing robust, scalable +network applications are the same no matter the underlying protocol. By +unifying the API for both clients and servers in a protocol agnostic way, +it is possible to write middleware that provide these pieces in a +reusable way.

+

Take timeouts as an example:

+ +
This example is not tested
+use tower_service::Service;
+use tower_layer::Layer;
+use futures::FutureExt;
+use std::future::Future;
+use std::task::{Context, Poll};
+use std::time::Duration;
+use std::pin::Pin;
+
+
+pub struct Timeout<T> {
+    inner: T,
+    timeout: Duration,
+}
+
+pub struct TimeoutLayer(Duration);
+
+pub struct Expired;
+
+impl<T> Timeout<T> {
+    pub fn new(inner: T, timeout: Duration) -> Timeout<T> {
+        Timeout {
+            inner,
+            timeout
+        }
+    }
+}
+
+impl<T, Request> Service<Request> for Timeout<T>
+where
+    T: Service<Request>,
+    T::Future: 'static,
+    T::Error: From<Expired> + 'static,
+    T::Response: 'static
+{
+    type Response = T::Response;
+    type Error = T::Error;
+    type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
+
+    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+       self.inner.poll_ready(cx).map_err(Into::into)
+    }
+
+    fn call(&mut self, req: Request) -> Self::Future {
+        let timeout = tokio_timer::delay_for(self.timeout)
+            .map(|_| Err(Self::Error::from(Expired)));
+
+        let fut = Box::pin(self.inner.call(req));
+        let f = futures::select(fut, timeout)
+            .map(|either| either.factor_first().0);
+
+        Box::pin(f)
+    }
+}
+
+impl TimeoutLayer {
+    pub fn new(delay: Duration) -> Self {
+        TimeoutLayer(delay)
+    }
+}
+
+impl<S> Layer<S> for TimeoutLayer
+{
+    type Service = Timeout<S>;
+
+    fn layer(&self, service: S) -> Timeout<S> {
+        Timeout::new(service, self.0)
+    }
+}
+
+

The above timeout implementation is decoupled from the underlying protocol +and is also decoupled from client or server concerns. In other words, the +same timeout middleware could be used in either a client or a server.

+

Backpressure

+

Calling a Service which is at capacity (i.e., it is temporarily unable to process a +request) should result in an error. The caller is responsible for ensuring +that the service is ready to receive the request before calling it.

+

Service provides a mechanism by which the caller is able to coordinate +readiness. Service::poll_ready returns Ready if the service expects that +it is able to process a request.

+
+

Associated Types

type Response

Responses given by the service.

+

type Error

Errors produced by the service.

+

type Future: Future<Output = Result<Self::Response, Self::Error>>

The future response value.

+
Loading content... +

Required methods

fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>>

Returns Poll::Ready(Ok(())) when the service is able to process requests.

+

If the service is at capacity, then Poll::Pending is returned and the task +is notified when the service becomes ready again. This function is +expected to be called while on a task. Generally, this can be done with +a simple futures::future::poll_fn call.

+

If Poll::Ready(Err(_)) is returned, the service is no longer able to service requests +and the caller should discard the service instance.

+

Once poll_ready returns Poll::Ready(Ok(())), a request may be dispatched to the +service using call. Until a request is dispatched, repeated calls to +poll_ready must return either Poll::Ready(Ok(())) or Poll::Ready(Err(_)).

+

fn call(&mut self, req: Request) -> Self::Future

Process the request and return the response asynchronously.

+

This function is expected to be callable off task. As such, +implementations should take care to not call poll_ready.

+

Before dispatching a request, poll_ready must be called and return +Poll::Ready(Ok(())).

+

Panics

+

Implementations are permitted to panic if call is invoked without +obtaining Poll::Ready(Ok(())) from poll_ready.

+
Loading content... +

Implementations on Foreign Types

impl<'a, S, Request> Service<Request> for &'a mut S where
    S: Service<Request> + 'a, 
[src]

type Response = S::Response

type Error = S::Error

type Future = S::Future

impl<S: ?Sized, Request> Service<Request> for Box<S> where
    S: Service<Request>, 
[src]

type Response = S::Response

type Error = S::Error

type Future = S::Future

Loading content... +

Implementors

Loading content...
\ No newline at end of file diff --git a/tower_test/all.html b/tower_test/all.html new file mode 100644 index 0000000..2d7560b --- /dev/null +++ b/tower_test/all.html @@ -0,0 +1,3 @@ +List of all items in this crate

[] + + List of all items

Structs

Macros

Functions

\ No newline at end of file diff --git a/tower_test/index.html b/tower_test/index.html new file mode 100644 index 0000000..53f4822 --- /dev/null +++ b/tower_test/index.html @@ -0,0 +1,7 @@ +tower_test - Rust

[][src]Crate tower_test

Mock Service that can be used in tests.

+

Modules

+
mock

Mock Service that can be used in tests.

+

Macros

+
assert_request_eq

Asserts that the mock handle receives a new request equal to the given +value.

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

Redirecting to macro.assert_request_eq.html...

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

[][src]Macro tower_test::assert_request_eq

+macro_rules! assert_request_eq {
+    ($mock_handle:expr, $expect:expr) => { ... };
+    ($mock_handle:expr, $expect:expr, $($arg:tt)*) => { ... };
+}
+

Asserts that the mock handle receives a new request equal to the given +value.

+

On success, the [SendResponse] handle for the matched request is returned, +allowing the caller to respond to the request. On failure, the macro panics.

+

Examples

+
+use tower_service::Service;
+use tower_test::{mock, assert_request_eq};
+use tokio_test::assert_ready;
+
+let (mut service, mut handle) = mock::spawn();
+
+assert_ready!(service.poll_ready());
+
+let response = service.call("hello");
+
+assert_request_eq!(handle, "hello").send_response("world");
+
+assert_eq!(response.await.unwrap(), "world");
+
\ No newline at end of file diff --git a/tower_test/mock/error/index.html b/tower_test/mock/error/index.html new file mode 100644 index 0000000..aab0b57 --- /dev/null +++ b/tower_test/mock/error/index.html @@ -0,0 +1,4 @@ +tower_test::mock::error - Rust

[][src]Module tower_test::mock::error

Error types

+

Structs

+
Closed

Error yielded when a mocked service does not yet accept requests.

+
\ No newline at end of file diff --git a/tower_test/mock/error/sidebar-items.js b/tower_test/mock/error/sidebar-items.js new file mode 100644 index 0000000..7635a79 --- /dev/null +++ b/tower_test/mock/error/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Closed","Error yielded when a mocked service does not yet accept requests."]]}); \ No newline at end of file diff --git a/tower_test/mock/error/struct.Closed.html b/tower_test/mock/error/struct.Closed.html new file mode 100644 index 0000000..9250dab --- /dev/null +++ b/tower_test/mock/error/struct.Closed.html @@ -0,0 +1,19 @@ +tower_test::mock::error::Closed - Rust

[][src]Struct tower_test::mock::error::Closed

pub struct Closed(_);

Error yielded when a mocked service does not yet accept requests.

+

Trait Implementations

impl Debug for Closed[src]

impl Display for Closed[src]

impl Error for Closed[src]

Auto Trait Implementations

impl RefUnwindSafe for Closed

impl Send for Closed

impl Sync for Closed

impl Unpin for Closed

impl UnwindSafe for Closed

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToString for T where
    T: Display + ?Sized
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower_test/mock/fn.pair.html b/tower_test/mock/fn.pair.html new file mode 100644 index 0000000..80e174d --- /dev/null +++ b/tower_test/mock/fn.pair.html @@ -0,0 +1,2 @@ +tower_test::mock::pair - Rust

[][src]Function tower_test::mock::pair

pub fn pair<T, U>() -> (Mock<T, U>, Handle<T, U>)

Create a new Mock and Handle pair.

+
\ No newline at end of file diff --git a/tower_test/mock/fn.spawn.html b/tower_test/mock/fn.spawn.html new file mode 100644 index 0000000..d7a3b24 --- /dev/null +++ b/tower_test/mock/fn.spawn.html @@ -0,0 +1,2 @@ +tower_test::mock::spawn - Rust

[][src]Function tower_test::mock::spawn

pub fn spawn<T, U>() -> (Spawn<Mock<T, U>>, Handle<T, U>)

Spawn a Service onto a mock task.

+
\ No newline at end of file diff --git a/tower_test/mock/fn.spawn_layer.html b/tower_test/mock/fn.spawn_layer.html new file mode 100644 index 0000000..c13feba --- /dev/null +++ b/tower_test/mock/fn.spawn_layer.html @@ -0,0 +1,2 @@ +tower_test::mock::spawn_layer - Rust

[][src]Function tower_test::mock::spawn_layer

pub fn spawn_layer<T, U, L>(layer: L) -> (Spawn<L::Service>, Handle<T, U>) where
    L: Layer<Mock<T, U>>, 

Spawn a layer onto a mock service.

+
\ No newline at end of file diff --git a/tower_test/mock/fn.spawn_with.html b/tower_test/mock/fn.spawn_with.html new file mode 100644 index 0000000..506e84a --- /dev/null +++ b/tower_test/mock/fn.spawn_with.html @@ -0,0 +1,2 @@ +tower_test::mock::spawn_with - Rust

[][src]Function tower_test::mock::spawn_with

pub fn spawn_with<T, U, F, S>(f: F) -> (Spawn<S>, Handle<T, U>) where
    F: Fn(Mock<T, U>) -> S, 

Spawn a Service via the provided wrapper closure.

+
\ No newline at end of file diff --git a/tower_test/mock/future/index.html b/tower_test/mock/future/index.html new file mode 100644 index 0000000..2544bc9 --- /dev/null +++ b/tower_test/mock/future/index.html @@ -0,0 +1,4 @@ +tower_test::mock::future - Rust

[][src]Module tower_test::mock::future

Future types

+

Structs

+
ResponseFuture

Future of the Mock response.

+
\ No newline at end of file diff --git a/tower_test/mock/future/sidebar-items.js b/tower_test/mock/future/sidebar-items.js new file mode 100644 index 0000000..98d3ed8 --- /dev/null +++ b/tower_test/mock/future/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["ResponseFuture","Future of the `Mock` response."]]}); \ No newline at end of file diff --git a/tower_test/mock/future/struct.ResponseFuture.html b/tower_test/mock/future/struct.ResponseFuture.html new file mode 100644 index 0000000..ddb2f50 --- /dev/null +++ b/tower_test/mock/future/struct.ResponseFuture.html @@ -0,0 +1,47 @@ +tower_test::mock::future::ResponseFuture - Rust

[][src]Struct tower_test::mock::future::ResponseFuture

pub struct ResponseFuture<T> { /* fields omitted */ }

Future of the Mock response.

+

Trait Implementations

impl<T: Debug> Debug for ResponseFuture<T>[src]

impl<T> Future for ResponseFuture<T>[src]

type Output = Result<T, Box<dyn Error + Send + Sync>>

The type of value produced on completion.

+

impl<T> PinnedDrop for ResponseFuture<T>[src]

impl<'pin, T> Unpin for ResponseFuture<T> where
    __ResponseFuture<'pin, T>: Unpin
[src]

impl<T> UnsafeUnpin for ResponseFuture<T>[src]

Auto Trait Implementations

impl<T> !RefUnwindSafe for ResponseFuture<T>

impl<T> Send for ResponseFuture<T> where
    T: Send

impl<T> Sync for ResponseFuture<T> where
    T: Send

impl<T> !UnwindSafe for ResponseFuture<T>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T> FutureExt for T where
    T: Future + ?Sized
[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<F, T, E> TryFuture for F where
    F: Future<Output = Result<T, E>> + ?Sized
[src]

type Ok = T

The type of successful values yielded by this future

+

type Error = E

The type of failures yielded by this future

+

impl<Fut> TryFutureExt for Fut where
    Fut: TryFuture + ?Sized
[src]

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower_test/mock/index.html b/tower_test/mock/index.html new file mode 100644 index 0000000..90eb4c7 --- /dev/null +++ b/tower_test/mock/index.html @@ -0,0 +1,16 @@ +tower_test::mock - Rust

[][src]Module tower_test::mock

Mock Service that can be used in tests.

+

Re-exports

+
pub use spawn::Spawn;

Modules

+
error

Error types

+
future

Future types

+
spawn

Spawn mock services onto a mock task.

+

Structs

+
Handle

Handle to the Mock.

+
Mock

A mock service

+
SendResponse

Send a response in reply to a received request.

+

Functions

+
pair

Create a new Mock and Handle pair.

+
spawn

Spawn a Service onto a mock task.

+
spawn_layer

Spawn a layer onto a mock service.

+
spawn_with

Spawn a Service via the provided wrapper closure.

+
\ No newline at end of file diff --git a/tower_test/mock/sidebar-items.js b/tower_test/mock/sidebar-items.js new file mode 100644 index 0000000..122b09e --- /dev/null +++ b/tower_test/mock/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"fn":[["pair","Create a new `Mock` and `Handle` pair."],["spawn","Spawn a Service onto a mock task."],["spawn_layer","Spawn a layer onto a mock service."],["spawn_with","Spawn a Service via the provided wrapper closure."]],"mod":[["error","Error types"],["future","Future types"],["spawn","Spawn mock services onto a mock task."]],"struct":[["Handle","Handle to the `Mock`."],["Mock","A mock service"],["SendResponse","Send a response in reply to a received request."]]}); \ No newline at end of file diff --git a/tower_test/mock/spawn/index.html b/tower_test/mock/spawn/index.html new file mode 100644 index 0000000..d1ef357 --- /dev/null +++ b/tower_test/mock/spawn/index.html @@ -0,0 +1,4 @@ +tower_test::mock::spawn - Rust

[][src]Module tower_test::mock::spawn

Spawn mock services onto a mock task.

+

Structs

+
Spawn

Service spawned on a mock task

+
\ No newline at end of file diff --git a/tower_test/mock/spawn/sidebar-items.js b/tower_test/mock/spawn/sidebar-items.js new file mode 100644 index 0000000..f7c3c1c --- /dev/null +++ b/tower_test/mock/spawn/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"struct":[["Spawn","Service spawned on a mock task"]]}); \ No newline at end of file diff --git a/tower_test/mock/spawn/struct.Spawn.html b/tower_test/mock/spawn/struct.Spawn.html new file mode 100644 index 0000000..03c4a2f --- /dev/null +++ b/tower_test/mock/spawn/struct.Spawn.html @@ -0,0 +1,26 @@ +tower_test::mock::spawn::Spawn - Rust

[][src]Struct tower_test::mock::spawn::Spawn

pub struct Spawn<T> { /* fields omitted */ }

Service spawned on a mock task

+

Methods

impl<T> Spawn<T>[src]

pub fn new(inner: T) -> Self[src]

Create a new spawn.

+

pub fn is_woken(&self) -> bool[src]

Check if this service has been woken up.

+

pub fn waker_ref_count(&self) -> usize[src]

Get how many futurs are holding onto the waker.

+

pub fn poll_ready<Request>(&mut self) -> Poll<Result<(), T::Error>> where
    T: Service<Request>, 
[src]

Poll this service ready.

+

pub fn call<Request>(&mut self, req: Request) -> T::Future where
    T: Service<Request>, 
[src]

Call the inner Service.

+

pub fn into_inner(self) -> T[src]

Get the inner service.

+

pub fn get_ref(&self) -> &T[src]

Get a reference to the inner service.

+

pub fn get_mut(&mut self) -> &mut T[src]

Get a mutable reference to the inner service.

+

Trait Implementations

impl<T: Clone> Clone for Spawn<T>[src]

impl<T: Debug> Debug for Spawn<T>[src]

Auto Trait Implementations

impl<T> !RefUnwindSafe for Spawn<T>

impl<T> Send for Spawn<T> where
    T: Send

impl<T> Sync for Spawn<T> where
    T: Sync

impl<T> Unpin for Spawn<T> where
    T: Unpin

impl<T> !UnwindSafe for Spawn<T>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower_test/mock/struct.Handle.html b/tower_test/mock/struct.Handle.html new file mode 100644 index 0000000..c02e542 --- /dev/null +++ b/tower_test/mock/struct.Handle.html @@ -0,0 +1,17 @@ +tower_test::mock::Handle - Rust

[][src]Struct tower_test::mock::Handle

pub struct Handle<T, U> { /* fields omitted */ }

Handle to the Mock.

+

Methods

impl<T, U> Handle<T, U>[src]

pub fn poll_request(&mut self) -> Poll<Option<(T, SendResponse<U>)>>[src]

Asynchronously gets the next request

+

pub async fn next_request<'_>(&'_ mut self) -> Option<(T, SendResponse<U>)>[src]

Gets the next request.

+

pub fn allow(&mut self, num: u64)[src]

Allow a certain number of requests

+

pub fn send_error<E: Into<Box<dyn Error + Send + Sync>>>(&mut self, e: E)[src]

Make the next poll_ method error with the given error.

+

Trait Implementations

impl<T: Debug, U: Debug> Debug for Handle<T, U>[src]

impl<T, U> Drop for Handle<T, U>[src]

Auto Trait Implementations

impl<T, U> !RefUnwindSafe for Handle<T, U>

impl<T, U> Send for Handle<T, U> where
    T: Send,
    U: Send

impl<T, U> Sync for Handle<T, U> where
    T: Send,
    U: Send

impl<T, U> Unpin for Handle<T, U>

impl<T, U> !UnwindSafe for Handle<T, U>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower_test/mock/struct.Mock.html b/tower_test/mock/struct.Mock.html new file mode 100644 index 0000000..d0e04fe --- /dev/null +++ b/tower_test/mock/struct.Mock.html @@ -0,0 +1,24 @@ +tower_test::mock::Mock - Rust

[][src]Struct tower_test::mock::Mock

pub struct Mock<T, U> { /* fields omitted */ }

A mock service

+

Trait Implementations

impl<T, U> Clone for Mock<T, U>[src]

impl<T: Debug, U: Debug> Debug for Mock<T, U>[src]

impl<T, U> Drop for Mock<T, U>[src]

impl<T, U> Service<T> for Mock<T, U>[src]

type Response = U

Responses given by the service.

+

type Error = Box<dyn Error + Send + Sync>

Errors produced by the service.

+

type Future = ResponseFuture<U>

The future response value.

+

Auto Trait Implementations

impl<T, U> RefUnwindSafe for Mock<T, U>

impl<T, U> Send for Mock<T, U> where
    T: Send,
    U: Send

impl<T, U> Sync for Mock<T, U> where
    T: Send,
    U: Send

impl<T, U> Unpin for Mock<T, U>

impl<T, U> UnwindSafe for Mock<T, U>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

+

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower_test/mock/struct.SendResponse.html b/tower_test/mock/struct.SendResponse.html new file mode 100644 index 0000000..eaf485e --- /dev/null +++ b/tower_test/mock/struct.SendResponse.html @@ -0,0 +1,14 @@ +tower_test::mock::SendResponse - Rust

[][src]Struct tower_test::mock::SendResponse

pub struct SendResponse<T> { /* fields omitted */ }

Send a response in reply to a received request.

+

Methods

impl<T> SendResponse<T>[src]

pub fn send_response(self, response: T)[src]

Resolve the pending request future for the linked request with the given response.

+

pub fn send_error<E: Into<Box<dyn Error + Send + Sync>>>(self, err: E)[src]

Resolve the pending request future for the linked request with the given error.

+

Trait Implementations

impl<T: Debug> Debug for SendResponse<T>[src]

Auto Trait Implementations

impl<T> !RefUnwindSafe for SendResponse<T>

impl<T> Send for SendResponse<T> where
    T: Send

impl<T> Sync for SendResponse<T> where
    T: Send

impl<T> Unpin for SendResponse<T>

impl<T> !UnwindSafe for SendResponse<T>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

+

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

+
\ No newline at end of file diff --git a/tower_test/sidebar-items.js b/tower_test/sidebar-items.js new file mode 100644 index 0000000..35c15ed --- /dev/null +++ b/tower_test/sidebar-items.js @@ -0,0 +1 @@ +initSidebarItems({"macro":[["assert_request_eq","Asserts that the mock handle receives a new request equal to the given value."]],"mod":[["mock","Mock `Service` that can be used in tests."]]}); \ No newline at end of file diff --git a/wheel.svg b/wheel.svg new file mode 100644 index 0000000..01da3b2 --- /dev/null +++ b/wheel.svg @@ -0,0 +1 @@ + \ No newline at end of file