Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

1
vendor/arrayvec/.cargo-checksum.json vendored Normal file
View File

@@ -0,0 +1 @@
{"files":{"CHANGELOG.md":"b6cd865fb2685cf241e61f216686c87fd78e7d4b8ba4faf03857c8a2b920eee6","Cargo.toml":"ed90cef00235d8e2b9a3027e11baed38b66a2cf6003bccd805c056c1ec70c722","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"4da95ec4ecb65b738d470b7d762894ad9c97da93e6cbfb18b570fc2c96f4b871","README.md":"2264c34c62ea4c617d72047b00749b4786dfb9dff2fac24e0320170ee0cd19c8","benches/arraystring.rs":"fad1cecef71c290375befc77c75a868988b8d74135e8f8732bc5b58c85a8ab46","benches/extend.rs":"c38ecedbc88217a7e9fe1a73f916b168a96e48010a7ccd3dba5c3f8dea030d5d","src/array_string.rs":"9840c5b95af997584374467dfc365e4ab747175db8e0574be4f148454514fc8f","src/arrayvec.rs":"42923c20659346e48fd551529cb58b8e646c404637818ba466455665cb037dc4","src/arrayvec_impl.rs":"e2642ae566c83ef37ad9aec6af7e3c50af310ba304553f38b2a787666b507580","src/char.rs":"1de50e1d6045af2b3496426492315ba774986f9bc8301ffa391de861a08cc9cb","src/errors.rs":"7fa2ff2350f811d52a210a7346c526d6715cacefd38a46e2d3b57ab7dc62b1ab","src/lib.rs":"8919a7e0c20890b1f094996147a1486d20578579aef03692315cd509e1745222","src/utils.rs":"d1cdc508dfca385e63f1f57bc8b53ed4a7f515e4ac1ebaa97b1d543fc8369432","tests/borsh.rs":"4ea4d21cc311d68d8f234cd77699a88158af26cbc3a69ae1f25c0052663f861d","tests/serde.rs":"117eb2961b5954d13c577edf60bbb07cb7481685cc9d6c49760a981d71465849","tests/tests.rs":"19a9bce4b55506be9ffb7584f47dbfb1d59c66dbfaab55b7a28d827cc0411e78"},"package":"7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"}

328
vendor/arrayvec/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,328 @@
Recent Changes (arrayvec)
=========================
## 0.7.6
- Fix no-std build [#274](https://github.com/bluss/arrayvec/pull/274)
## 0.7.5
- Add `as_ptr` and `as_mut_ptr` to `ArrayString` [@YuhanLiin](https://github.com/YuhanLiin) [#260](https://github.com/bluss/arrayvec/pull/260)
- Add borsh serialization support by @honzasp and @Fuuzetsu [#259](https://github.com/bluss/arrayvec/pull/259)
- Move length field before before data in ArrayVec and ArrayString by @JakkuSakura [#255](https://github.com/bluss/arrayvec/pull/255)
- Fix miri error for ZST case in extend by @bluss
- implement AsRef<Path> for ArrayString by [@Zoybean](https://github.com/Zoybean) [#218](https://github.com/bluss/arrayvec/pull/218)
- Fix typos in changelog by [@striezel](https://github.com/striezel) [#241](https://github.com/bluss/arrayvec/pull/241)
- Add `as_slice`, `as_mut_slice` methods to `IntoIter` by [@clarfonthey](https://github.com/clarfonthey) [#224](https://github.com/bluss/arrayvec/pull/224)
## 0.7.4
- Add feature zeroize to support the `Zeroize` trait by @elichai
## 0.7.3
- Use track_caller on multiple methods like push and similar, for capacity
overflows by @kornelski
- impl BorrowMut for ArrayString by @msrd0
- Fix stacked borrows violations by @clubby789
- Update Miri CI by @RalfJung
## 0.7.2
- Add `.as_mut_str()` to `ArrayString` by @clarfonthey
- Add `remaining_capacity` to `ArrayString` by @bhgomes
- Add `zero_filled` constructor by @c410-f3r
- Optimize `retain` by @TennyZhuang and @niklasf
- Make the following methods `const` by @bhgomes:
- len
- is_empty
- capacity
- is_full
- remaining_capacity
- CapacityError::new
## 0.7.1
- Add new ArrayVec methods `.take()` and `.into_inner_unchecked()` by @conradludgate
- `clone_from` now uses `truncate` when needed by @a1phyr
## 0.7.0
- `fn new_const` is now the way to const-construct arrayvec and arraystring,
and `fn new` has been reverted to a regular "non-const" function.
This works around performance issue #182, where the const fn version did not
optimize well. Change by @bluss with thanks to @rodrimati1992 and @niklasf
for analyzing the problem.
- The deprecated feature flag `unstable-const-fn` was removed, since it's not needed
- Optimize `.retain()` by using the same algorithm as in std, change by @niklasf,
issue #174. Original optimization in Rust std by @oxalica in rust-lang/rust/pull/81126
## 0.6.1
- The ``ArrayVec::new`` and ``ArrayString::new`` constructors are properly
const fns on stable and the feature flag ``unstable-const-fn`` is now deprecated.
by @rodrimati1992
- Small fix to the capacity check macro by @Xaeroxe
- Typo fix in documentation by @cuviper
- Small code cleanup by @bluss
## 0.6.0
- The **const generics** release 🎉. Arrayvec finally implements what it
wanted to implement, since its first version: a vector backed by an array,
with generic parameters for the arbitrary element type *and* backing array
capacity.
The New type syntax is `ArrayVec<T, CAP>` where `CAP` is the arrayvec capacity.
For arraystring the syntax is `ArrayString<CAP>`.
Length is stored internally as u32; this limits the maximum capacity. The size
of the `ArrayVec` or `ArrayString` structs for the same capacity may grow
slightly compared with the previous version (depending on padding requirements
for the element type). Change by @bluss.
- Arrayvec's `.extend()` and `FromIterator`/`.collect()` to arrayvec now
**panic** if the capacity of the arrayvec is exceeded. Change by @bluss.
- Arraystring now implements `TryFrom<&str>` and `TryFrom<fmt::Arguments>` by
@c410-f3r
- Minimum supported rust version is Rust 1.51
## 0.5.2
- Add `is_empty` methods for ArrayVec and ArrayString by @nicbn
- Implement `TryFrom<Slice>` for ArrayVec by @paulkernfeld
- Add `unstable-const-fn` to make `new` methods const by @m-ou-se
- Run miri in CI and a few related fixes by @RalfJung
- Fix outdated comment by @Phlosioneer
- Move changelog to a separate file by @Luro02
- Remove deprecated `Error::description` by @AnderEnder
- Use pointer method `add` by @hbina
## 0.5.1
- Add `as_ptr`, `as_mut_ptr` accessors directly on the `ArrayVec` by @tbu-
(matches the same addition to `Vec` which happened in Rust 1.37).
- Add method `ArrayString::len` (now available directly, not just through deref to str).
- Use raw pointers instead of `&mut [u8]` for encoding chars into `ArrayString`
(uninit best practice fix).
- Use raw pointers instead of `get_unchecked_mut` where the target may be
uninitialized everywhere relevant in the ArrayVec implementation
(uninit best practice fix).
- Changed inline hints on many methods, mainly removing inline hints
- `ArrayVec::dispose` is now deprecated (it has no purpose anymore)
## 0.4.12
- Use raw pointers instead of `get_unchecked_mut` where the target may be
uninitialized everywhere relevant in the ArrayVec implementation.
## 0.5.0
- Use `MaybeUninit` (now unconditionally) in the implementation of
`ArrayVec`
- Use `MaybeUninit` (now unconditionally) in the implementation of
`ArrayString`
- The crate feature for serde serialization is now named `serde`.
- Updated the `Array` trait interface, and it is now easier to use for
users outside the crate.
- Add `FromStr` impl for `ArrayString` by @despawnerer
- Add method `try_extend_from_slice` to `ArrayVec`, which is always
efficient by @Thomasdezeeuw.
- Add method `remaining_capacity` by @Thomasdezeeuw
- Improve performance of the `extend` method.
- The index type of zero capacity vectors is now itself zero size, by
@clarfon
- Use `drop_in_place` for truncate and clear methods. This affects drop order
and resume from panic during drop.
- Use Rust 2018 edition for the implementation
- Require Rust 1.36 or later, for the unconditional `MaybeUninit`
improvements.
## Older releases
- 0.4.11
- In Rust 1.36 or later, use newly stable `MaybeUninit`. This extends the
soundness work introduced in 0.4.9, we are finally able to use this in
stable. We use feature detection (build script) to enable this at build
time.
- 0.4.10
- Use `repr(C)` in the `union` version that was introduced in 0.4.9, to
allay some soundness concerns.
- 0.4.9
- Use `union` in the implementation on when this is detected to be supported
(nightly only for now). This is a better solution for treating uninitialized
regions correctly, and we'll use it in stable Rust as soon as we are able.
When this is enabled, the `ArrayVec` has no space overhead in its memory
layout, although the size of the vec should not be relied upon. (See [#114](https://github.com/bluss/arrayvec/pull/114))
- `ArrayString` updated to not use uninitialized memory, it instead zeros its
backing array. This will be refined in the next version, since we
need to make changes to the user visible API.
- The `use_union` feature now does nothing (like its documentation foretold).
- 0.4.8
- Implement Clone and Debug for `IntoIter` by @clarcharr
- Add more array sizes under crate features. These cover all in the range
up to 128 and 129 to 255 respectively (we have a few of those by default):
- `array-size-33-128`
- `array-size-129-255`
- 0.4.7
- Fix future compat warning about raw pointer casts
- Use `drop_in_place` when dropping the arrayvec by-value iterator
- Decrease minimum Rust version (see docs) by @jeehoonkang
- 0.3.25
- Fix future compat warning about raw pointer casts
- 0.4.6
- Fix compilation on 16-bit targets. This means, the 65536 array size is not
included on these targets.
- 0.3.24
- Fix compilation on 16-bit targets. This means, the 65536 array size is not
included on these targets.
- Fix license files so that they are both included (was fixed in 0.4 before)
- 0.4.5
- Add methods to `ArrayString` by @DenialAdams:
- `.pop() -> Option<char>`
- `.truncate(new_len)`
- `.remove(index) -> char`
- Remove dependency on crate odds
- Document debug assertions in unsafe methods better
- 0.4.4
- Add method `ArrayVec::truncate()` by @niklasf
- 0.4.3
- Improve performance for `ArrayVec::extend` with a lower level
implementation (#74)
- Small cleanup in dependencies (use no std for crates where we don't need more)
- 0.4.2
- Add constructor method `new` to `CapacityError`.
- 0.4.1
- Add `Default` impl to `ArrayString` by @tbu-
- 0.4.0
- Reformed signatures and error handling by @bluss and @tbu-:
- `ArrayVec`'s `push, insert, remove, swap_remove` now match `Vec`'s
corresponding signature and panic on capacity errors where applicable.
- Add fallible methods `try_push, insert` and checked methods
`pop_at, swap_pop`.
- Similar changes to `ArrayString`'s push methods.
- Use a local version of the `RangeArgument` trait
- Add array sizes 50, 150, 200 by @daboross
- Support serde 1.0 by @daboross
- New method `.push_unchecked()` by @niklasf
- `ArrayString` implements `PartialOrd, Ord` by @tbu-
- Require Rust 1.14
- crate feature `use_generic_array` was dropped.
- 0.3.23
- Implement `PartialOrd, Ord` as well as `PartialOrd<str>` for
`ArrayString`.
- 0.3.22
- Implement `Array` for the 65536 size
- 0.3.21
- Use `encode_utf8` from crate odds
- Add constructor `ArrayString::from_byte_string`
- 0.3.20
- Simplify and speed up `ArrayString`s `.push(char)`-
- 0.3.19
- Add new crate feature `use_generic_array` which allows using their
`GenericArray` just like a regular fixed size array for the storage
of an `ArrayVec`.
- 0.3.18
- Fix bounds check in `ArrayVec::insert`!
It would be buggy if `self.len() < index < self.capacity()`. Take note of
the push out behavior specified in the docs.
- 0.3.17
- Added crate feature `use_union` which forwards to the nodrop crate feature
- Added methods `.is_full()` to `ArrayVec` and `ArrayString`.
- 0.3.16
- Added method `.retain()` to `ArrayVec`.
- Added methods `.as_slice(), .as_mut_slice()` to `ArrayVec` and `.as_str()`
to `ArrayString`.
- 0.3.15
- Add feature std, which you can opt out of to use `no_std` (requires Rust 1.6
to opt out).
- Implement `Clone::clone_from` for ArrayVec and ArrayString
- 0.3.14
- Add `ArrayString::from(&str)`
- 0.3.13
- Added `DerefMut` impl for `ArrayString`.
- Added method `.simplify()` to drop the element for `CapacityError`.
- Added method `.dispose()` to `ArrayVec`
- 0.3.12
- Added ArrayString, a fixed capacity analogy of String
- 0.3.11
- Added trait impls Default, PartialOrd, Ord, Write for ArrayVec
- 0.3.10
- Go back to using external NoDrop, fixing a panic safety bug (issue #3)
- 0.3.8
- Inline the non-dropping logic to remove one drop flag in the
ArrayVec representation.
- 0.3.7
- Added method .into_inner()
- Added unsafe method .set_len()

111
vendor/arrayvec/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,111 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
rust-version = "1.51"
name = "arrayvec"
version = "0.7.6"
authors = ["bluss"]
build = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "A vector with fixed capacity, backed by an array (it can be stored on the stack too). Implements fixed capacity ArrayVec and ArrayString."
documentation = "https://docs.rs/arrayvec/"
readme = "README.md"
keywords = [
"stack",
"vector",
"array",
"data-structure",
"no_std",
]
categories = [
"data-structures",
"no-std",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/bluss/arrayvec"
[package.metadata.docs.rs]
features = [
"borsh",
"serde",
"zeroize",
]
[package.metadata.release]
no-dev-version = true
tag-name = "{{version}}"
[profile.bench]
debug = 2
[profile.release]
debug = 2
[lib]
name = "arrayvec"
path = "src/lib.rs"
[[test]]
name = "borsh"
path = "tests/borsh.rs"
[[test]]
name = "serde"
path = "tests/serde.rs"
[[test]]
name = "tests"
path = "tests/tests.rs"
[[bench]]
name = "arraystring"
path = "benches/arraystring.rs"
harness = false
[[bench]]
name = "extend"
path = "benches/extend.rs"
harness = false
[dependencies.borsh]
version = "1.2.0"
optional = true
default-features = false
[dependencies.serde]
version = "1.0"
optional = true
default-features = false
[dependencies.zeroize]
version = "1.4"
optional = true
default-features = false
[dev-dependencies.bencher]
version = "0.1.4"
[dev-dependencies.matches]
version = "0.1"
[dev-dependencies.serde_test]
version = "1.0"
[build-dependencies]
[features]
default = ["std"]
std = []

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

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

25
vendor/arrayvec/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,25 @@
Copyright (c) Ulrik Sverdrup "bluss" 2015-2023
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.

27
vendor/arrayvec/README.md vendored Normal file
View File

@@ -0,0 +1,27 @@
arrayvec
========
[![Crates.io: arrayvec](https://img.shields.io/crates/v/arrayvec.svg)](https://crates.io/crates/arrayvec)
[![Documentation](https://docs.rs/arrayvec/badge.svg)](https://docs.rs/arrayvec)
[![Build Status](https://github.com/bluss/arrayvec/workflows/Continuous%20integration/badge.svg?branch=master)](https://github.com/bluss/arrayvec/actions)
[![License: Apache](https://img.shields.io/badge/License-Apache%202.0-red.svg)](LICENSE-APACHE)
OR
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
A vector with fixed capacity.
Please read the [`API documentation here`](https://docs.rs/arrayvec)
# License
Dual-licensed to be compatible with the Rust project.
Licensed under the Apache License, Version 2.0
http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
http://opensource.org/licenses/MIT, at your
option. This file may not be copied, modified, or distributed
except according to those terms.

90
vendor/arrayvec/benches/arraystring.rs vendored Normal file
View File

@@ -0,0 +1,90 @@
extern crate arrayvec;
#[macro_use] extern crate bencher;
use arrayvec::ArrayString;
use bencher::Bencher;
fn try_push_c(b: &mut Bencher) {
let mut v = ArrayString::<512>::new();
b.iter(|| {
v.clear();
while v.try_push('c').is_ok() {
}
v.len()
});
b.bytes = v.capacity() as u64;
}
fn try_push_alpha(b: &mut Bencher) {
let mut v = ArrayString::<512>::new();
b.iter(|| {
v.clear();
while v.try_push('α').is_ok() {
}
v.len()
});
b.bytes = v.capacity() as u64;
}
// Yes, pushing a string char-by-char is slow. Use .push_str.
fn try_push_string(b: &mut Bencher) {
let mut v = ArrayString::<512>::new();
let input = "abcαβγ“”";
b.iter(|| {
v.clear();
for ch in input.chars().cycle() {
if !v.try_push(ch).is_ok() {
break;
}
}
v.len()
});
b.bytes = v.capacity() as u64;
}
fn push_c(b: &mut Bencher) {
let mut v = ArrayString::<512>::new();
b.iter(|| {
v.clear();
while !v.is_full() {
v.push('c');
}
v.len()
});
b.bytes = v.capacity() as u64;
}
fn push_alpha(b: &mut Bencher) {
let mut v = ArrayString::<512>::new();
b.iter(|| {
v.clear();
while !v.is_full() {
v.push('α');
}
v.len()
});
b.bytes = v.capacity() as u64;
}
fn push_string(b: &mut Bencher) {
let mut v = ArrayString::<512>::new();
let input = "abcαβγ“”";
b.iter(|| {
v.clear();
for ch in input.chars().cycle() {
if !v.is_full() {
v.push(ch);
} else {
break;
}
}
v.len()
});
b.bytes = v.capacity() as u64;
}
benchmark_group!(benches, try_push_c, try_push_alpha, try_push_string, push_c,
push_alpha, push_string);
benchmark_main!(benches);

78
vendor/arrayvec/benches/extend.rs vendored Normal file
View File

@@ -0,0 +1,78 @@
extern crate arrayvec;
#[macro_use] extern crate bencher;
use std::io::Write;
use arrayvec::ArrayVec;
use bencher::Bencher;
use bencher::black_box;
fn extend_with_constant(b: &mut Bencher) {
let mut v = ArrayVec::<u8, 512>::new();
let cap = v.capacity();
b.iter(|| {
v.clear();
let constant = black_box(1);
v.extend((0..cap).map(move |_| constant));
v[511]
});
b.bytes = v.capacity() as u64;
}
fn extend_with_range(b: &mut Bencher) {
let mut v = ArrayVec::<u8, 512>::new();
let cap = v.capacity();
b.iter(|| {
v.clear();
let range = 0..cap;
v.extend(range.map(|x| black_box(x as _)));
v[511]
});
b.bytes = v.capacity() as u64;
}
fn extend_with_slice(b: &mut Bencher) {
let mut v = ArrayVec::<u8, 512>::new();
let data = [1; 512];
b.iter(|| {
v.clear();
let iter = data.iter().map(|&x| x);
v.extend(iter);
v[511]
});
b.bytes = v.capacity() as u64;
}
fn extend_with_write(b: &mut Bencher) {
let mut v = ArrayVec::<u8, 512>::new();
let data = [1; 512];
b.iter(|| {
v.clear();
v.write(&data[..]).ok();
v[511]
});
b.bytes = v.capacity() as u64;
}
fn extend_from_slice(b: &mut Bencher) {
let mut v = ArrayVec::<u8, 512>::new();
let data = [1; 512];
b.iter(|| {
v.clear();
v.try_extend_from_slice(&data).ok();
v[511]
});
b.bytes = v.capacity() as u64;
}
benchmark_group!(benches,
extend_with_constant,
extend_with_range,
extend_with_slice,
extend_with_write,
extend_from_slice
);
benchmark_main!(benches);

716
vendor/arrayvec/src/array_string.rs vendored Normal file
View File

@@ -0,0 +1,716 @@
use std::borrow::{Borrow, BorrowMut};
use std::cmp;
use std::convert::TryFrom;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem::MaybeUninit;
use std::ops::{Deref, DerefMut};
#[cfg(feature="std")]
use std::path::Path;
use std::ptr;
use std::slice;
use std::str;
use std::str::FromStr;
use std::str::Utf8Error;
use crate::CapacityError;
use crate::LenUint;
use crate::char::encode_utf8;
use crate::utils::MakeMaybeUninit;
#[cfg(feature="serde")]
use serde::{Serialize, Deserialize, Serializer, Deserializer};
/// A string with a fixed capacity.
///
/// The `ArrayString` is a string backed by a fixed size array. It keeps track
/// of its length, and is parameterized by `CAP` for the maximum capacity.
///
/// `CAP` is of type `usize` but is range limited to `u32::MAX`; attempting to create larger
/// arrayvecs with larger capacity will panic.
///
/// The string is a contiguous value that you can store directly on the stack
/// if needed.
#[derive(Copy)]
#[repr(C)]
pub struct ArrayString<const CAP: usize> {
// the `len` first elements of the array are initialized
len: LenUint,
xs: [MaybeUninit<u8>; CAP],
}
impl<const CAP: usize> Default for ArrayString<CAP>
{
/// Return an empty `ArrayString`
fn default() -> ArrayString<CAP> {
ArrayString::new()
}
}
impl<const CAP: usize> ArrayString<CAP>
{
/// Create a new empty `ArrayString`.
///
/// Capacity is inferred from the type parameter.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<16>::new();
/// string.push_str("foo");
/// assert_eq!(&string[..], "foo");
/// assert_eq!(string.capacity(), 16);
/// ```
pub fn new() -> ArrayString<CAP> {
assert_capacity_limit!(CAP);
unsafe {
ArrayString { xs: MaybeUninit::uninit().assume_init(), len: 0 }
}
}
/// Create a new empty `ArrayString` (const fn).
///
/// Capacity is inferred from the type parameter.
///
/// ```
/// use arrayvec::ArrayString;
///
/// static ARRAY: ArrayString<1024> = ArrayString::new_const();
/// ```
pub const fn new_const() -> ArrayString<CAP> {
assert_capacity_limit_const!(CAP);
ArrayString { xs: MakeMaybeUninit::ARRAY, len: 0 }
}
/// Return the length of the string.
#[inline]
pub const fn len(&self) -> usize { self.len as usize }
/// Returns whether the string is empty.
#[inline]
pub const fn is_empty(&self) -> bool { self.len() == 0 }
/// Create a new `ArrayString` from a `str`.
///
/// Capacity is inferred from the type parameter.
///
/// **Errors** if the backing array is not large enough to fit the string.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<3>::from("foo").unwrap();
/// assert_eq!(&string[..], "foo");
/// assert_eq!(string.len(), 3);
/// assert_eq!(string.capacity(), 3);
/// ```
pub fn from(s: &str) -> Result<Self, CapacityError<&str>> {
let mut arraystr = Self::new();
arraystr.try_push_str(s)?;
Ok(arraystr)
}
/// Create a new `ArrayString` from a byte string literal.
///
/// **Errors** if the byte string literal is not valid UTF-8.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let string = ArrayString::from_byte_string(b"hello world").unwrap();
/// ```
pub fn from_byte_string(b: &[u8; CAP]) -> Result<Self, Utf8Error> {
let len = str::from_utf8(b)?.len();
debug_assert_eq!(len, CAP);
let mut vec = Self::new();
unsafe {
(b as *const [u8; CAP] as *const [MaybeUninit<u8>; CAP])
.copy_to_nonoverlapping(&mut vec.xs as *mut [MaybeUninit<u8>; CAP], 1);
vec.set_len(CAP);
}
Ok(vec)
}
/// Create a new `ArrayString` value fully filled with ASCII NULL characters (`\0`). Useful
/// to be used as a buffer to collect external data or as a buffer for intermediate processing.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let string = ArrayString::<16>::zero_filled();
/// assert_eq!(string.len(), 16);
/// ```
#[inline]
pub fn zero_filled() -> Self {
assert_capacity_limit!(CAP);
// SAFETY: `assert_capacity_limit` asserts that `len` won't overflow and
// `zeroed` fully fills the array with nulls.
unsafe {
ArrayString {
xs: MaybeUninit::zeroed().assume_init(),
len: CAP as _
}
}
}
/// Return the capacity of the `ArrayString`.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let string = ArrayString::<3>::new();
/// assert_eq!(string.capacity(), 3);
/// ```
#[inline(always)]
pub const fn capacity(&self) -> usize { CAP }
/// Return if the `ArrayString` is completely filled.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<1>::new();
/// assert!(!string.is_full());
/// string.push_str("A");
/// assert!(string.is_full());
/// ```
pub const fn is_full(&self) -> bool { self.len() == self.capacity() }
/// Returns the capacity left in the `ArrayString`.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<3>::from("abc").unwrap();
/// string.pop();
/// assert_eq!(string.remaining_capacity(), 1);
/// ```
pub const fn remaining_capacity(&self) -> usize {
self.capacity() - self.len()
}
/// Adds the given char to the end of the string.
///
/// ***Panics*** if the backing array is not large enough to fit the additional char.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<2>::new();
///
/// string.push('a');
/// string.push('b');
///
/// assert_eq!(&string[..], "ab");
/// ```
#[track_caller]
pub fn push(&mut self, c: char) {
self.try_push(c).unwrap();
}
/// Adds the given char to the end of the string.
///
/// Returns `Ok` if the push succeeds.
///
/// **Errors** if the backing array is not large enough to fit the additional char.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<2>::new();
///
/// string.try_push('a').unwrap();
/// string.try_push('b').unwrap();
/// let overflow = string.try_push('c');
///
/// assert_eq!(&string[..], "ab");
/// assert_eq!(overflow.unwrap_err().element(), 'c');
/// ```
pub fn try_push(&mut self, c: char) -> Result<(), CapacityError<char>> {
let len = self.len();
unsafe {
let ptr = self.as_mut_ptr().add(len);
let remaining_cap = self.capacity() - len;
match encode_utf8(c, ptr, remaining_cap) {
Ok(n) => {
self.set_len(len + n);
Ok(())
}
Err(_) => Err(CapacityError::new(c)),
}
}
}
/// Adds the given string slice to the end of the string.
///
/// ***Panics*** if the backing array is not large enough to fit the string.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<2>::new();
///
/// string.push_str("a");
/// string.push_str("d");
///
/// assert_eq!(&string[..], "ad");
/// ```
#[track_caller]
pub fn push_str(&mut self, s: &str) {
self.try_push_str(s).unwrap()
}
/// Adds the given string slice to the end of the string.
///
/// Returns `Ok` if the push succeeds.
///
/// **Errors** if the backing array is not large enough to fit the string.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<2>::new();
///
/// string.try_push_str("a").unwrap();
/// let overflow1 = string.try_push_str("bc");
/// string.try_push_str("d").unwrap();
/// let overflow2 = string.try_push_str("ef");
///
/// assert_eq!(&string[..], "ad");
/// assert_eq!(overflow1.unwrap_err().element(), "bc");
/// assert_eq!(overflow2.unwrap_err().element(), "ef");
/// ```
pub fn try_push_str<'a>(&mut self, s: &'a str) -> Result<(), CapacityError<&'a str>> {
if s.len() > self.capacity() - self.len() {
return Err(CapacityError::new(s));
}
unsafe {
let dst = self.as_mut_ptr().add(self.len());
let src = s.as_ptr();
ptr::copy_nonoverlapping(src, dst, s.len());
let newl = self.len() + s.len();
self.set_len(newl);
}
Ok(())
}
/// Removes the last character from the string and returns it.
///
/// Returns `None` if this `ArrayString` is empty.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut s = ArrayString::<3>::from("foo").unwrap();
///
/// assert_eq!(s.pop(), Some('o'));
/// assert_eq!(s.pop(), Some('o'));
/// assert_eq!(s.pop(), Some('f'));
///
/// assert_eq!(s.pop(), None);
/// ```
pub fn pop(&mut self) -> Option<char> {
let ch = match self.chars().rev().next() {
Some(ch) => ch,
None => return None,
};
let new_len = self.len() - ch.len_utf8();
unsafe {
self.set_len(new_len);
}
Some(ch)
}
/// Shortens this `ArrayString` to the specified length.
///
/// If `new_len` is greater than the strings current length, this has no
/// effect.
///
/// ***Panics*** if `new_len` does not lie on a `char` boundary.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut string = ArrayString::<6>::from("foobar").unwrap();
/// string.truncate(3);
/// assert_eq!(&string[..], "foo");
/// string.truncate(4);
/// assert_eq!(&string[..], "foo");
/// ```
pub fn truncate(&mut self, new_len: usize) {
if new_len <= self.len() {
assert!(self.is_char_boundary(new_len));
unsafe {
// In libstd truncate is called on the underlying vector,
// which in turns drops each element.
// As we know we don't have to worry about Drop,
// we can just set the length (a la clear.)
self.set_len(new_len);
}
}
}
/// Removes a `char` from this `ArrayString` at a byte position and returns it.
///
/// This is an `O(n)` operation, as it requires copying every element in the
/// array.
///
/// ***Panics*** if `idx` is larger than or equal to the `ArrayString`s length,
/// or if it does not lie on a `char` boundary.
///
/// ```
/// use arrayvec::ArrayString;
///
/// let mut s = ArrayString::<3>::from("foo").unwrap();
///
/// assert_eq!(s.remove(0), 'f');
/// assert_eq!(s.remove(1), 'o');
/// assert_eq!(s.remove(0), 'o');
/// ```
pub fn remove(&mut self, idx: usize) -> char {
let ch = match self[idx..].chars().next() {
Some(ch) => ch,
None => panic!("cannot remove a char from the end of a string"),
};
let next = idx + ch.len_utf8();
let len = self.len();
let ptr = self.as_mut_ptr();
unsafe {
ptr::copy(
ptr.add(next),
ptr.add(idx),
len - next);
self.set_len(len - (next - idx));
}
ch
}
/// Make the string empty.
pub fn clear(&mut self) {
unsafe {
self.set_len(0);
}
}
/// Set the stringss length.
///
/// This function is `unsafe` because it changes the notion of the
/// number of “valid” bytes in the string. Use with care.
///
/// This method uses *debug assertions* to check the validity of `length`
/// and may use other debug assertions.
pub unsafe fn set_len(&mut self, length: usize) {
// type invariant that capacity always fits in LenUint
debug_assert!(length <= self.capacity());
self.len = length as LenUint;
}
/// Return a string slice of the whole `ArrayString`.
pub fn as_str(&self) -> &str {
self
}
/// Return a mutable string slice of the whole `ArrayString`.
pub fn as_mut_str(&mut self) -> &mut str {
self
}
/// Return a raw pointer to the string's buffer.
pub fn as_ptr(&self) -> *const u8 {
self.xs.as_ptr() as *const u8
}
/// Return a raw mutable pointer to the string's buffer.
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self.xs.as_mut_ptr() as *mut u8
}
}
impl<const CAP: usize> Deref for ArrayString<CAP>
{
type Target = str;
#[inline]
fn deref(&self) -> &str {
unsafe {
let sl = slice::from_raw_parts(self.as_ptr(), self.len());
str::from_utf8_unchecked(sl)
}
}
}
impl<const CAP: usize> DerefMut for ArrayString<CAP>
{
#[inline]
fn deref_mut(&mut self) -> &mut str {
unsafe {
let len = self.len();
let sl = slice::from_raw_parts_mut(self.as_mut_ptr(), len);
str::from_utf8_unchecked_mut(sl)
}
}
}
impl<const CAP: usize> PartialEq for ArrayString<CAP>
{
fn eq(&self, rhs: &Self) -> bool {
**self == **rhs
}
}
impl<const CAP: usize> PartialEq<str> for ArrayString<CAP>
{
fn eq(&self, rhs: &str) -> bool {
&**self == rhs
}
}
impl<const CAP: usize> PartialEq<ArrayString<CAP>> for str
{
fn eq(&self, rhs: &ArrayString<CAP>) -> bool {
self == &**rhs
}
}
impl<const CAP: usize> Eq for ArrayString<CAP>
{ }
impl<const CAP: usize> Hash for ArrayString<CAP>
{
fn hash<H: Hasher>(&self, h: &mut H) {
(**self).hash(h)
}
}
impl<const CAP: usize> Borrow<str> for ArrayString<CAP>
{
fn borrow(&self) -> &str { self }
}
impl<const CAP: usize> BorrowMut<str> for ArrayString<CAP>
{
fn borrow_mut(&mut self) -> &mut str { self }
}
impl<const CAP: usize> AsRef<str> for ArrayString<CAP>
{
fn as_ref(&self) -> &str { self }
}
impl<const CAP: usize> fmt::Debug for ArrayString<CAP>
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
}
#[cfg(feature="std")]
impl<const CAP: usize> AsRef<Path> for ArrayString<CAP> {
fn as_ref(&self) -> &Path {
self.as_str().as_ref()
}
}
impl<const CAP: usize> fmt::Display for ArrayString<CAP>
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { (**self).fmt(f) }
}
/// `Write` appends written data to the end of the string.
impl<const CAP: usize> fmt::Write for ArrayString<CAP>
{
fn write_char(&mut self, c: char) -> fmt::Result {
self.try_push(c).map_err(|_| fmt::Error)
}
fn write_str(&mut self, s: &str) -> fmt::Result {
self.try_push_str(s).map_err(|_| fmt::Error)
}
}
impl<const CAP: usize> Clone for ArrayString<CAP>
{
fn clone(&self) -> ArrayString<CAP> {
*self
}
fn clone_from(&mut self, rhs: &Self) {
// guaranteed to fit due to types matching.
self.clear();
self.try_push_str(rhs).ok();
}
}
impl<const CAP: usize> PartialOrd for ArrayString<CAP>
{
fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> {
(**self).partial_cmp(&**rhs)
}
fn lt(&self, rhs: &Self) -> bool { **self < **rhs }
fn le(&self, rhs: &Self) -> bool { **self <= **rhs }
fn gt(&self, rhs: &Self) -> bool { **self > **rhs }
fn ge(&self, rhs: &Self) -> bool { **self >= **rhs }
}
impl<const CAP: usize> PartialOrd<str> for ArrayString<CAP>
{
fn partial_cmp(&self, rhs: &str) -> Option<cmp::Ordering> {
(**self).partial_cmp(rhs)
}
fn lt(&self, rhs: &str) -> bool { &**self < rhs }
fn le(&self, rhs: &str) -> bool { &**self <= rhs }
fn gt(&self, rhs: &str) -> bool { &**self > rhs }
fn ge(&self, rhs: &str) -> bool { &**self >= rhs }
}
impl<const CAP: usize> PartialOrd<ArrayString<CAP>> for str
{
fn partial_cmp(&self, rhs: &ArrayString<CAP>) -> Option<cmp::Ordering> {
self.partial_cmp(&**rhs)
}
fn lt(&self, rhs: &ArrayString<CAP>) -> bool { self < &**rhs }
fn le(&self, rhs: &ArrayString<CAP>) -> bool { self <= &**rhs }
fn gt(&self, rhs: &ArrayString<CAP>) -> bool { self > &**rhs }
fn ge(&self, rhs: &ArrayString<CAP>) -> bool { self >= &**rhs }
}
impl<const CAP: usize> Ord for ArrayString<CAP>
{
fn cmp(&self, rhs: &Self) -> cmp::Ordering {
(**self).cmp(&**rhs)
}
}
impl<const CAP: usize> FromStr for ArrayString<CAP>
{
type Err = CapacityError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::from(s).map_err(CapacityError::simplify)
}
}
#[cfg(feature="serde")]
/// Requires crate feature `"serde"`
impl<const CAP: usize> Serialize for ArrayString<CAP>
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
serializer.serialize_str(&*self)
}
}
#[cfg(feature="serde")]
/// Requires crate feature `"serde"`
impl<'de, const CAP: usize> Deserialize<'de> for ArrayString<CAP>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
use serde::de::{self, Visitor};
use std::marker::PhantomData;
struct ArrayStringVisitor<const CAP: usize>(PhantomData<[u8; CAP]>);
impl<'de, const CAP: usize> Visitor<'de> for ArrayStringVisitor<CAP> {
type Value = ArrayString<CAP>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a string no more than {} bytes long", CAP)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where E: de::Error,
{
ArrayString::from(v).map_err(|_| E::invalid_length(v.len(), &self))
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where E: de::Error,
{
let s = str::from_utf8(v).map_err(|_| E::invalid_value(de::Unexpected::Bytes(v), &self))?;
ArrayString::from(s).map_err(|_| E::invalid_length(s.len(), &self))
}
}
deserializer.deserialize_str(ArrayStringVisitor(PhantomData))
}
}
#[cfg(feature = "borsh")]
/// Requires crate feature `"borsh"`
impl<const CAP: usize> borsh::BorshSerialize for ArrayString<CAP> {
fn serialize<W: borsh::io::Write>(&self, writer: &mut W) -> borsh::io::Result<()> {
<str as borsh::BorshSerialize>::serialize(&*self, writer)
}
}
#[cfg(feature = "borsh")]
/// Requires crate feature `"borsh"`
impl<const CAP: usize> borsh::BorshDeserialize for ArrayString<CAP> {
fn deserialize_reader<R: borsh::io::Read>(reader: &mut R) -> borsh::io::Result<Self> {
let len = <u32 as borsh::BorshDeserialize>::deserialize_reader(reader)? as usize;
if len > CAP {
return Err(borsh::io::Error::new(
borsh::io::ErrorKind::InvalidData,
format!("Expected a string no more than {} bytes long", CAP),
))
}
let mut buf = [0u8; CAP];
let buf = &mut buf[..len];
reader.read_exact(buf)?;
let s = str::from_utf8(&buf).map_err(|err| {
borsh::io::Error::new(borsh::io::ErrorKind::InvalidData, err.to_string())
})?;
Ok(Self::from(s).unwrap())
}
}
impl<'a, const CAP: usize> TryFrom<&'a str> for ArrayString<CAP>
{
type Error = CapacityError<&'a str>;
fn try_from(f: &'a str) -> Result<Self, Self::Error> {
let mut v = Self::new();
v.try_push_str(f)?;
Ok(v)
}
}
impl<'a, const CAP: usize> TryFrom<fmt::Arguments<'a>> for ArrayString<CAP>
{
type Error = CapacityError<fmt::Error>;
fn try_from(f: fmt::Arguments<'a>) -> Result<Self, Self::Error> {
use fmt::Write;
let mut v = Self::new();
v.write_fmt(f).map_err(|e| CapacityError::new(e))?;
Ok(v)
}
}
#[cfg(feature = "zeroize")]
/// "Best efforts" zeroing of the `ArrayString`'s buffer when the `zeroize` feature is enabled.
///
/// The length is set to 0, and the buffer is dropped and zeroized.
/// Cannot ensure that previous moves of the `ArrayString` did not leave values on the stack.
///
/// ```
/// use arrayvec::ArrayString;
/// use zeroize::Zeroize;
/// let mut string = ArrayString::<6>::from("foobar").unwrap();
/// string.zeroize();
/// assert_eq!(string.len(), 0);
/// unsafe { string.set_len(string.capacity()) };
/// assert_eq!(&*string, "\0\0\0\0\0\0");
/// ```
impl<const CAP: usize> zeroize::Zeroize for ArrayString<CAP> {
fn zeroize(&mut self) {
// There are no elements to drop
self.clear();
// Zeroize the backing array.
self.xs.zeroize();
}
}

1348
vendor/arrayvec/src/arrayvec.rs vendored Normal file

File diff suppressed because it is too large Load Diff

87
vendor/arrayvec/src/arrayvec_impl.rs vendored Normal file
View File

@@ -0,0 +1,87 @@
use std::ptr;
use std::slice;
use crate::CapacityError;
/// Implements basic arrayvec methods - based on a few required methods
/// for length and element access.
pub(crate) trait ArrayVecImpl {
type Item;
const CAPACITY: usize;
fn len(&self) -> usize;
unsafe fn set_len(&mut self, new_len: usize);
/// Return a slice containing all elements of the vector.
fn as_slice(&self) -> &[Self::Item] {
let len = self.len();
unsafe {
slice::from_raw_parts(self.as_ptr(), len)
}
}
/// Return a mutable slice containing all elements of the vector.
fn as_mut_slice(&mut self) -> &mut [Self::Item] {
let len = self.len();
unsafe {
std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
}
}
/// Return a raw pointer to the vector's buffer.
fn as_ptr(&self) -> *const Self::Item;
/// Return a raw mutable pointer to the vector's buffer.
fn as_mut_ptr(&mut self) -> *mut Self::Item;
#[track_caller]
fn push(&mut self, element: Self::Item) {
self.try_push(element).unwrap()
}
fn try_push(&mut self, element: Self::Item) -> Result<(), CapacityError<Self::Item>> {
if self.len() < Self::CAPACITY {
unsafe {
self.push_unchecked(element);
}
Ok(())
} else {
Err(CapacityError::new(element))
}
}
unsafe fn push_unchecked(&mut self, element: Self::Item) {
let len = self.len();
debug_assert!(len < Self::CAPACITY);
ptr::write(self.as_mut_ptr().add(len), element);
self.set_len(len + 1);
}
fn pop(&mut self) -> Option<Self::Item> {
if self.len() == 0 {
return None;
}
unsafe {
let new_len = self.len() - 1;
self.set_len(new_len);
Some(ptr::read(self.as_ptr().add(new_len)))
}
}
fn clear(&mut self) {
self.truncate(0)
}
fn truncate(&mut self, new_len: usize) {
unsafe {
let len = self.len();
if new_len < len {
self.set_len(new_len);
let tail = slice::from_raw_parts_mut(self.as_mut_ptr().add(new_len), len - new_len);
ptr::drop_in_place(tail);
}
}
}
}

92
vendor/arrayvec/src/char.rs vendored Normal file
View File

@@ -0,0 +1,92 @@
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// Original authors: alexchrichton, bluss
// UTF-8 ranges and tags for encoding characters
const TAG_CONT: u8 = 0b1000_0000;
const TAG_TWO_B: u8 = 0b1100_0000;
const TAG_THREE_B: u8 = 0b1110_0000;
const TAG_FOUR_B: u8 = 0b1111_0000;
const MAX_ONE_B: u32 = 0x80;
const MAX_TWO_B: u32 = 0x800;
const MAX_THREE_B: u32 = 0x10000;
/// Placeholder
pub struct EncodeUtf8Error;
/// Encode a char into buf using UTF-8.
///
/// On success, return the byte length of the encoding (1, 2, 3 or 4).<br>
/// On error, return `EncodeUtf8Error` if the buffer was too short for the char.
///
/// Safety: `ptr` must be writable for `len` bytes.
#[inline]
pub unsafe fn encode_utf8(ch: char, ptr: *mut u8, len: usize) -> Result<usize, EncodeUtf8Error>
{
let code = ch as u32;
if code < MAX_ONE_B && len >= 1 {
ptr.add(0).write(code as u8);
return Ok(1);
} else if code < MAX_TWO_B && len >= 2 {
ptr.add(0).write((code >> 6 & 0x1F) as u8 | TAG_TWO_B);
ptr.add(1).write((code & 0x3F) as u8 | TAG_CONT);
return Ok(2);
} else if code < MAX_THREE_B && len >= 3 {
ptr.add(0).write((code >> 12 & 0x0F) as u8 | TAG_THREE_B);
ptr.add(1).write((code >> 6 & 0x3F) as u8 | TAG_CONT);
ptr.add(2).write((code & 0x3F) as u8 | TAG_CONT);
return Ok(3);
} else if len >= 4 {
ptr.add(0).write((code >> 18 & 0x07) as u8 | TAG_FOUR_B);
ptr.add(1).write((code >> 12 & 0x3F) as u8 | TAG_CONT);
ptr.add(2).write((code >> 6 & 0x3F) as u8 | TAG_CONT);
ptr.add(3).write((code & 0x3F) as u8 | TAG_CONT);
return Ok(4);
};
Err(EncodeUtf8Error)
}
#[test]
#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_encode_utf8() {
// Test that all codepoints are encoded correctly
let mut data = [0u8; 16];
for codepoint in 0..=(std::char::MAX as u32) {
if let Some(ch) = std::char::from_u32(codepoint) {
for elt in &mut data { *elt = 0; }
let ptr = data.as_mut_ptr();
let len = data.len();
unsafe {
let res = encode_utf8(ch, ptr, len).ok().unwrap();
assert_eq!(res, ch.len_utf8());
}
let string = std::str::from_utf8(&data).unwrap();
assert_eq!(string.chars().next(), Some(ch));
}
}
}
#[test]
fn test_encode_utf8_oob() {
// test that we report oob if the buffer is too short
let mut data = [0u8; 16];
let chars = ['a', 'α', '<27>', '𐍈'];
for (len, &ch) in (1..=4).zip(&chars) {
assert_eq!(len, ch.len_utf8(), "Len of ch={}", ch);
let ptr = data.as_mut_ptr();
unsafe {
assert!(matches::matches!(encode_utf8(ch, ptr, len - 1), Err(_)));
assert!(matches::matches!(encode_utf8(ch, ptr, len), Ok(_)));
}
}
}

49
vendor/arrayvec/src/errors.rs vendored Normal file
View File

@@ -0,0 +1,49 @@
use std::fmt;
#[cfg(feature="std")]
use std::any::Any;
#[cfg(feature="std")]
use std::error::Error;
/// Error value indicating insufficient capacity
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
pub struct CapacityError<T = ()> {
element: T,
}
impl<T> CapacityError<T> {
/// Create a new `CapacityError` from `element`.
pub const fn new(element: T) -> CapacityError<T> {
CapacityError {
element: element,
}
}
/// Extract the overflowing element
pub fn element(self) -> T {
self.element
}
/// Convert into a `CapacityError` that does not carry an element.
pub fn simplify(self) -> CapacityError {
CapacityError { element: () }
}
}
const CAPERROR: &'static str = "insufficient capacity";
#[cfg(feature="std")]
/// Requires `features="std"`.
impl<T: Any> Error for CapacityError<T> {}
impl<T> fmt::Display for CapacityError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", CAPERROR)
}
}
impl<T> fmt::Debug for CapacityError<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}: {}", "CapacityError", CAPERROR)
}
}

63
vendor/arrayvec/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,63 @@
//! **arrayvec** provides the types [`ArrayVec`] and [`ArrayString`]:
//! array-backed vector and string types, which store their contents inline.
//!
//! The arrayvec package has the following cargo features:
//!
//! - `std`
//! - Optional, enabled by default
//! - Use libstd; disable to use `no_std` instead.
//!
//! - `serde`
//! - Optional
//! - Enable serialization for ArrayVec and ArrayString using serde 1.x
//!
//! - `zeroize`
//! - Optional
//! - Implement `Zeroize` for ArrayVec and ArrayString
//!
//! ## Rust Version
//!
//! This version of arrayvec requires Rust 1.51 or later.
//!
#![doc(html_root_url="https://docs.rs/arrayvec/0.7/")]
#![cfg_attr(not(feature="std"), no_std)]
#[cfg(feature="serde")]
extern crate serde;
#[cfg(not(feature="std"))]
extern crate core as std;
pub(crate) type LenUint = u32;
macro_rules! assert_capacity_limit {
($cap:expr) => {
if std::mem::size_of::<usize>() > std::mem::size_of::<LenUint>() {
if $cap > LenUint::MAX as usize {
panic!("ArrayVec: largest supported capacity is u32::MAX")
}
}
}
}
macro_rules! assert_capacity_limit_const {
($cap:expr) => {
if std::mem::size_of::<usize>() > std::mem::size_of::<LenUint>() {
if $cap > LenUint::MAX as usize {
[/*ArrayVec: largest supported capacity is u32::MAX*/][$cap]
}
}
}
}
mod arrayvec_impl;
mod arrayvec;
mod array_string;
mod char;
mod errors;
mod utils;
pub use crate::array_string::ArrayString;
pub use crate::errors::CapacityError;
pub use crate::arrayvec::{ArrayVec, IntoIter, Drain};

11
vendor/arrayvec/src/utils.rs vendored Normal file
View File

@@ -0,0 +1,11 @@
use std::marker::PhantomData;
use std::mem::MaybeUninit;
pub(crate) struct MakeMaybeUninit<T, const N: usize>(PhantomData<fn() -> T>);
impl<T, const N: usize> MakeMaybeUninit<T, N> {
pub(crate) const VALUE: MaybeUninit<T> = MaybeUninit::uninit();
pub(crate) const ARRAY: [MaybeUninit<T>; N] = [Self::VALUE; N];
}

73
vendor/arrayvec/tests/borsh.rs vendored Normal file
View File

@@ -0,0 +1,73 @@
#![cfg(feature = "borsh")]
use std::fmt;
extern crate arrayvec;
extern crate borsh;
fn assert_ser<T: borsh::BorshSerialize>(v: &T, expected_bytes: &[u8]) {
let mut actual_bytes = Vec::new();
v.serialize(&mut actual_bytes).unwrap();
assert_eq!(actual_bytes, expected_bytes);
}
fn assert_roundtrip<T: borsh::BorshSerialize + borsh::BorshDeserialize + PartialEq + fmt::Debug>(v: &T) {
let mut bytes = Vec::new();
v.serialize(&mut bytes).unwrap();
let v_de = T::try_from_slice(&bytes).unwrap();
assert_eq!(*v, v_de);
}
mod array_vec {
use arrayvec::ArrayVec;
use super::{assert_ser, assert_roundtrip};
#[test]
fn test_empty() {
let vec = ArrayVec::<u32, 0>::new();
assert_ser(&vec, b"\0\0\0\0");
assert_roundtrip(&vec);
}
#[test]
fn test_full() {
let mut vec = ArrayVec::<u32, 3>::new();
vec.push(0xdeadbeef);
vec.push(0x123);
vec.push(0x456);
assert_ser(&vec, b"\x03\0\0\0\xef\xbe\xad\xde\x23\x01\0\0\x56\x04\0\0");
assert_roundtrip(&vec);
}
#[test]
fn test_with_free_capacity() {
let mut vec = ArrayVec::<u32, 3>::new();
vec.push(0xdeadbeef);
assert_ser(&vec, b"\x01\0\0\0\xef\xbe\xad\xde");
assert_roundtrip(&vec);
}
}
mod array_string {
use arrayvec::ArrayString;
use super::{assert_ser, assert_roundtrip};
#[test]
fn test_empty() {
let string = ArrayString::<0>::new();
assert_ser(&string, b"\0\0\0\0");
assert_roundtrip(&string);
}
#[test]
fn test_full() {
let string = ArrayString::from_byte_string(b"hello world").unwrap();
assert_ser(&string, b"\x0b\0\0\0hello world");
assert_roundtrip(&string);
}
#[test]
fn test_with_free_capacity() {
let string = ArrayString::<16>::from("hello world").unwrap();
assert_ser(&string, b"\x0b\0\0\0hello world");
assert_roundtrip(&string);
}
}

79
vendor/arrayvec/tests/serde.rs vendored Normal file
View File

@@ -0,0 +1,79 @@
#![cfg(feature = "serde")]
extern crate arrayvec;
extern crate serde_test;
mod array_vec {
use arrayvec::ArrayVec;
use serde_test::{Token, assert_tokens, assert_de_tokens_error};
#[test]
fn test_ser_de_empty() {
let vec = ArrayVec::<u32, 0>::new();
assert_tokens(&vec, &[
Token::Seq { len: Some(0) },
Token::SeqEnd,
]);
}
#[test]
fn test_ser_de() {
let mut vec = ArrayVec::<u32, 3>::new();
vec.push(20);
vec.push(55);
vec.push(123);
assert_tokens(&vec, &[
Token::Seq { len: Some(3) },
Token::U32(20),
Token::U32(55),
Token::U32(123),
Token::SeqEnd,
]);
}
#[test]
fn test_de_too_large() {
assert_de_tokens_error::<ArrayVec<u32, 2>>(&[
Token::Seq { len: Some(3) },
Token::U32(13),
Token::U32(42),
Token::U32(68),
], "invalid length 3, expected an array with no more than 2 items");
}
}
mod array_string {
use arrayvec::ArrayString;
use serde_test::{Token, assert_tokens, assert_de_tokens_error};
#[test]
fn test_ser_de_empty() {
let string = ArrayString::<0>::new();
assert_tokens(&string, &[
Token::Str(""),
]);
}
#[test]
fn test_ser_de() {
let string = ArrayString::<9>::from("1234 abcd")
.expect("expected exact specified capacity to be enough");
assert_tokens(&string, &[
Token::Str("1234 abcd"),
]);
}
#[test]
fn test_de_too_large() {
assert_de_tokens_error::<ArrayString<2>>(&[
Token::Str("afd")
], "invalid length 3, expected a string no more than 2 bytes long");
}
}

779
vendor/arrayvec/tests/tests.rs vendored Normal file
View File

@@ -0,0 +1,779 @@
extern crate arrayvec;
#[macro_use] extern crate matches;
use arrayvec::ArrayVec;
use arrayvec::ArrayString;
use std::mem;
use arrayvec::CapacityError;
use std::collections::HashMap;
#[test]
fn test_simple() {
use std::ops::Add;
let mut vec: ArrayVec<Vec<i32>, 3> = ArrayVec::new();
vec.push(vec![1, 2, 3, 4]);
vec.push(vec![10]);
vec.push(vec![-1, 13, -2]);
for elt in &vec {
assert_eq!(elt.iter().fold(0, Add::add), 10);
}
let sum_len = vec.into_iter().map(|x| x.len()).fold(0, Add::add);
assert_eq!(sum_len, 8);
}
#[test]
fn test_capacity_left() {
let mut vec: ArrayVec<usize, 4> = ArrayVec::new();
assert_eq!(vec.remaining_capacity(), 4);
vec.push(1);
assert_eq!(vec.remaining_capacity(), 3);
vec.push(2);
assert_eq!(vec.remaining_capacity(), 2);
vec.push(3);
assert_eq!(vec.remaining_capacity(), 1);
vec.push(4);
assert_eq!(vec.remaining_capacity(), 0);
}
#[test]
fn test_extend_from_slice() {
let mut vec: ArrayVec<usize, 10> = ArrayVec::new();
vec.try_extend_from_slice(&[1, 2, 3]).unwrap();
assert_eq!(vec.len(), 3);
assert_eq!(&vec[..], &[1, 2, 3]);
assert_eq!(vec.pop(), Some(3));
assert_eq!(&vec[..], &[1, 2]);
}
#[test]
fn test_extend_from_slice_error() {
let mut vec: ArrayVec<usize, 10> = ArrayVec::new();
vec.try_extend_from_slice(&[1, 2, 3]).unwrap();
let res = vec.try_extend_from_slice(&[0; 8]);
assert_matches!(res, Err(_));
let mut vec: ArrayVec<usize, 0> = ArrayVec::new();
let res = vec.try_extend_from_slice(&[0; 1]);
assert_matches!(res, Err(_));
}
#[test]
fn test_try_from_slice_error() {
use arrayvec::ArrayVec;
use std::convert::TryInto as _;
let res: Result<ArrayVec<_, 2>, _> = (&[1, 2, 3] as &[_]).try_into();
assert_matches!(res, Err(_));
}
#[test]
fn test_u16_index() {
const N: usize = 4096;
let mut vec: ArrayVec<_, N> = ArrayVec::new();
for _ in 0..N {
assert!(vec.try_push(1u8).is_ok());
}
assert!(vec.try_push(0).is_err());
assert_eq!(vec.len(), N);
}
#[test]
fn test_iter() {
let mut iter = ArrayVec::from([1, 2, 3]).into_iter();
assert_eq!(iter.size_hint(), (3, Some(3)));
assert_eq!(iter.next_back(), Some(3));
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next_back(), Some(2));
assert_eq!(iter.size_hint(), (0, Some(0)));
assert_eq!(iter.next_back(), None);
}
#[test]
fn test_drop() {
use std::cell::Cell;
let flag = &Cell::new(0);
#[derive(Clone)]
struct Bump<'a>(&'a Cell<i32>);
impl<'a> Drop for Bump<'a> {
fn drop(&mut self) {
let n = self.0.get();
self.0.set(n + 1);
}
}
{
let mut array = ArrayVec::<Bump, 128>::new();
array.push(Bump(flag));
array.push(Bump(flag));
}
assert_eq!(flag.get(), 2);
// test something with the nullable pointer optimization
flag.set(0);
{
let mut array = ArrayVec::<_, 3>::new();
array.push(vec![Bump(flag)]);
array.push(vec![Bump(flag), Bump(flag)]);
array.push(vec![]);
let push4 = array.try_push(vec![Bump(flag)]);
assert_eq!(flag.get(), 0);
drop(push4);
assert_eq!(flag.get(), 1);
drop(array.pop());
assert_eq!(flag.get(), 1);
drop(array.pop());
assert_eq!(flag.get(), 3);
}
assert_eq!(flag.get(), 4);
// test into_inner
flag.set(0);
{
let mut array = ArrayVec::<_, 3>::new();
array.push(Bump(flag));
array.push(Bump(flag));
array.push(Bump(flag));
let inner = array.into_inner();
assert!(inner.is_ok());
assert_eq!(flag.get(), 0);
drop(inner);
assert_eq!(flag.get(), 3);
}
// test take
flag.set(0);
{
let mut array1 = ArrayVec::<_, 3>::new();
array1.push(Bump(flag));
array1.push(Bump(flag));
array1.push(Bump(flag));
let array2 = array1.take();
assert_eq!(flag.get(), 0);
drop(array1);
assert_eq!(flag.get(), 0);
drop(array2);
assert_eq!(flag.get(), 3);
}
// test cloning into_iter
flag.set(0);
{
let mut array = ArrayVec::<_, 3>::new();
array.push(Bump(flag));
array.push(Bump(flag));
array.push(Bump(flag));
let mut iter = array.into_iter();
assert_eq!(flag.get(), 0);
iter.next();
assert_eq!(flag.get(), 1);
let clone = iter.clone();
assert_eq!(flag.get(), 1);
drop(clone);
assert_eq!(flag.get(), 3);
drop(iter);
assert_eq!(flag.get(), 5);
}
}
#[test]
fn test_drop_panics() {
use std::cell::Cell;
use std::panic::catch_unwind;
use std::panic::AssertUnwindSafe;
let flag = &Cell::new(0);
struct Bump<'a>(&'a Cell<i32>);
// Panic in the first drop
impl<'a> Drop for Bump<'a> {
fn drop(&mut self) {
let n = self.0.get();
self.0.set(n + 1);
if n == 0 {
panic!("Panic in Bump's drop");
}
}
}
// check if rust is new enough
flag.set(0);
{
let array = vec![Bump(flag), Bump(flag)];
let res = catch_unwind(AssertUnwindSafe(|| {
drop(array);
}));
assert!(res.is_err());
}
if flag.get() != 2 {
println!("test_drop_panics: skip, this version of Rust doesn't continue in drop_in_place");
return;
}
flag.set(0);
{
let mut array = ArrayVec::<Bump, 128>::new();
array.push(Bump(flag));
array.push(Bump(flag));
array.push(Bump(flag));
let res = catch_unwind(AssertUnwindSafe(|| {
drop(array);
}));
assert!(res.is_err());
}
// Check that all the elements drop, even if the first drop panics.
assert_eq!(flag.get(), 3);
flag.set(0);
{
let mut array = ArrayVec::<Bump, 16>::new();
array.push(Bump(flag));
array.push(Bump(flag));
array.push(Bump(flag));
array.push(Bump(flag));
array.push(Bump(flag));
let i = 2;
let tail_len = array.len() - i;
let res = catch_unwind(AssertUnwindSafe(|| {
array.truncate(i);
}));
assert!(res.is_err());
// Check that all the tail elements drop, even if the first drop panics.
assert_eq!(flag.get(), tail_len as i32);
}
}
#[test]
fn test_extend() {
let mut range = 0..10;
let mut array: ArrayVec<_, 5> = range.by_ref().take(5).collect();
assert_eq!(&array[..], &[0, 1, 2, 3, 4]);
assert_eq!(range.next(), Some(5));
array.extend(range.by_ref().take(0));
assert_eq!(range.next(), Some(6));
let mut array: ArrayVec<_, 10> = (0..3).collect();
assert_eq!(&array[..], &[0, 1, 2]);
array.extend(3..5);
assert_eq!(&array[..], &[0, 1, 2, 3, 4]);
}
#[should_panic]
#[test]
fn test_extend_capacity_panic_1() {
let mut range = 0..10;
let _: ArrayVec<_, 5> = range.by_ref().collect();
}
#[should_panic]
#[test]
fn test_extend_capacity_panic_2() {
let mut range = 0..10;
let mut array: ArrayVec<_, 5> = range.by_ref().take(5).collect();
assert_eq!(&array[..], &[0, 1, 2, 3, 4]);
assert_eq!(range.next(), Some(5));
array.extend(range.by_ref().take(1));
}
#[test]
fn test_is_send_sync() {
let data = ArrayVec::<Vec<i32>, 5>::new();
&data as &dyn Send;
&data as &dyn Sync;
}
#[test]
fn test_compact_size() {
// 4 bytes + padding + length
type ByteArray = ArrayVec<u8, 4>;
println!("{}", mem::size_of::<ByteArray>());
assert!(mem::size_of::<ByteArray>() <= 2 * mem::size_of::<u32>());
// just length
type EmptyArray = ArrayVec<u8, 0>;
println!("{}", mem::size_of::<EmptyArray>());
assert!(mem::size_of::<EmptyArray>() <= mem::size_of::<u32>());
// 3 elements + padding + length
type QuadArray = ArrayVec<u32, 3>;
println!("{}", mem::size_of::<QuadArray>());
assert!(mem::size_of::<QuadArray>() <= 4 * 4 + mem::size_of::<u32>());
}
#[test]
fn test_still_works_with_option_arrayvec() {
type RefArray = ArrayVec<&'static i32, 2>;
let array = Some(RefArray::new());
assert!(array.is_some());
println!("{:?}", array);
}
#[test]
fn test_drain() {
let mut v = ArrayVec::from([0; 8]);
v.pop();
v.drain(0..7);
assert_eq!(&v[..], &[]);
v.extend(0..8);
v.drain(1..4);
assert_eq!(&v[..], &[0, 4, 5, 6, 7]);
let u: ArrayVec<_, 3> = v.drain(1..4).rev().collect();
assert_eq!(&u[..], &[6, 5, 4]);
assert_eq!(&v[..], &[0, 7]);
v.drain(..);
assert_eq!(&v[..], &[]);
}
#[test]
fn test_drain_range_inclusive() {
let mut v = ArrayVec::from([0; 8]);
v.drain(0..=7);
assert_eq!(&v[..], &[]);
v.extend(0..8);
v.drain(1..=4);
assert_eq!(&v[..], &[0, 5, 6, 7]);
let u: ArrayVec<_, 3> = v.drain(1..=2).rev().collect();
assert_eq!(&u[..], &[6, 5]);
assert_eq!(&v[..], &[0, 7]);
v.drain(..);
assert_eq!(&v[..], &[]);
}
#[test]
#[should_panic]
fn test_drain_range_inclusive_oob() {
let mut v = ArrayVec::from([0; 0]);
v.drain(0..=0);
}
#[test]
fn test_retain() {
let mut v = ArrayVec::from([0; 8]);
for (i, elt) in v.iter_mut().enumerate() {
*elt = i;
}
v.retain(|_| true);
assert_eq!(&v[..], &[0, 1, 2, 3, 4, 5, 6, 7]);
v.retain(|elt| {
*elt /= 2;
*elt % 2 == 0
});
assert_eq!(&v[..], &[0, 0, 2, 2]);
v.retain(|_| false);
assert_eq!(&v[..], &[]);
}
#[test]
#[should_panic]
fn test_drain_oob() {
let mut v = ArrayVec::from([0; 8]);
v.pop();
v.drain(0..8);
}
#[test]
#[should_panic]
fn test_drop_panic() {
struct DropPanic;
impl Drop for DropPanic {
fn drop(&mut self) {
panic!("drop");
}
}
let mut array = ArrayVec::<DropPanic, 1>::new();
array.push(DropPanic);
}
#[test]
#[should_panic]
fn test_drop_panic_into_iter() {
struct DropPanic;
impl Drop for DropPanic {
fn drop(&mut self) {
panic!("drop");
}
}
let mut array = ArrayVec::<DropPanic, 1>::new();
array.push(DropPanic);
array.into_iter();
}
#[test]
fn test_insert() {
let mut v = ArrayVec::from([]);
assert_matches!(v.try_push(1), Err(_));
let mut v = ArrayVec::<_, 3>::new();
v.insert(0, 0);
v.insert(1, 1);
//let ret1 = v.try_insert(3, 3);
//assert_matches!(ret1, Err(InsertError::OutOfBounds(_)));
assert_eq!(&v[..], &[0, 1]);
v.insert(2, 2);
assert_eq!(&v[..], &[0, 1, 2]);
let ret2 = v.try_insert(1, 9);
assert_eq!(&v[..], &[0, 1, 2]);
assert_matches!(ret2, Err(_));
let mut v = ArrayVec::from([2]);
assert_matches!(v.try_insert(0, 1), Err(CapacityError { .. }));
assert_matches!(v.try_insert(1, 1), Err(CapacityError { .. }));
//assert_matches!(v.try_insert(2, 1), Err(CapacityError { .. }));
}
#[test]
fn test_into_inner_1() {
let mut v = ArrayVec::from([1, 2]);
v.pop();
let u = v.clone();
assert_eq!(v.into_inner(), Err(u));
}
#[test]
fn test_into_inner_2() {
let mut v = ArrayVec::<String, 4>::new();
v.push("a".into());
v.push("b".into());
v.push("c".into());
v.push("d".into());
assert_eq!(v.into_inner().unwrap(), ["a", "b", "c", "d"]);
}
#[test]
fn test_into_inner_3() {
let mut v = ArrayVec::<i32, 4>::new();
v.extend(1..=4);
assert_eq!(v.into_inner().unwrap(), [1, 2, 3, 4]);
}
#[test]
fn test_take() {
let mut v1 = ArrayVec::<i32, 4>::new();
v1.extend(1..=4);
let v2 = v1.take();
assert!(v1.into_inner().is_err());
assert_eq!(v2.into_inner().unwrap(), [1, 2, 3, 4]);
}
#[cfg(feature="std")]
#[test]
fn test_write() {
use std::io::Write;
let mut v = ArrayVec::<_, 8>::new();
write!(&mut v, "\x01\x02\x03").unwrap();
assert_eq!(&v[..], &[1, 2, 3]);
let r = v.write(&[9; 16]).unwrap();
assert_eq!(r, 5);
assert_eq!(&v[..], &[1, 2, 3, 9, 9, 9, 9, 9]);
}
#[test]
fn array_clone_from() {
let mut v = ArrayVec::<_, 4>::new();
v.push(vec![1, 2]);
v.push(vec![3, 4, 5]);
v.push(vec![6]);
let reference = v.to_vec();
let mut u = ArrayVec::<_, 4>::new();
u.clone_from(&v);
assert_eq!(&u, &reference[..]);
let mut t = ArrayVec::<_, 4>::new();
t.push(vec![97]);
t.push(vec![]);
t.push(vec![5, 6, 2]);
t.push(vec![2]);
t.clone_from(&v);
assert_eq!(&t, &reference[..]);
t.clear();
t.clone_from(&v);
assert_eq!(&t, &reference[..]);
}
#[cfg(feature="std")]
#[test]
fn test_string() {
use std::error::Error;
let text = "hello world";
let mut s = ArrayString::<16>::new();
s.try_push_str(text).unwrap();
assert_eq!(&s, text);
assert_eq!(text, &s);
// Make sure Hash / Eq / Borrow match up so we can use HashMap
let mut map = HashMap::new();
map.insert(s, 1);
assert_eq!(map[text], 1);
let mut t = ArrayString::<2>::new();
assert!(t.try_push_str(text).is_err());
assert_eq!(&t, "");
t.push_str("ab");
// DerefMut
let tmut: &mut str = &mut t;
assert_eq!(tmut, "ab");
// Test Error trait / try
let t = || -> Result<(), Box<dyn Error>> {
let mut t = ArrayString::<2>::new();
t.try_push_str(text)?;
Ok(())
}();
assert!(t.is_err());
}
#[test]
fn test_string_from() {
let text = "hello world";
// Test `from` constructor
let u = ArrayString::<11>::from(text).unwrap();
assert_eq!(&u, text);
assert_eq!(u.len(), text.len());
}
#[test]
fn test_string_parse_from_str() {
let text = "hello world";
let u: ArrayString<11> = text.parse().unwrap();
assert_eq!(&u, text);
assert_eq!(u.len(), text.len());
}
#[test]
fn test_string_from_bytes() {
let text = "hello world";
let u = ArrayString::from_byte_string(b"hello world").unwrap();
assert_eq!(&u, text);
assert_eq!(u.len(), text.len());
}
#[test]
fn test_string_clone() {
let text = "hi";
let mut s = ArrayString::<4>::new();
s.push_str("abcd");
let t = ArrayString::<4>::from(text).unwrap();
s.clone_from(&t);
assert_eq!(&t, &s);
}
#[test]
fn test_string_push() {
let text = "abcαβγ";
let mut s = ArrayString::<8>::new();
for c in text.chars() {
if let Err(_) = s.try_push(c) {
break;
}
}
assert_eq!("abcαβ", &s[..]);
s.push('x');
assert_eq!("abcαβx", &s[..]);
assert!(s.try_push('x').is_err());
}
#[test]
fn test_insert_at_length() {
let mut v = ArrayVec::<_, 8>::new();
let result1 = v.try_insert(0, "a");
let result2 = v.try_insert(1, "b");
assert!(result1.is_ok() && result2.is_ok());
assert_eq!(&v[..], &["a", "b"]);
}
#[should_panic]
#[test]
fn test_insert_out_of_bounds() {
let mut v = ArrayVec::<_, 8>::new();
let _ = v.try_insert(1, "test");
}
/*
* insert that pushes out the last
let mut u = ArrayVec::from([1, 2, 3, 4]);
let ret = u.try_insert(3, 99);
assert_eq!(&u[..], &[1, 2, 3, 99]);
assert_matches!(ret, Err(_));
let ret = u.try_insert(4, 77);
assert_eq!(&u[..], &[1, 2, 3, 99]);
assert_matches!(ret, Err(_));
*/
#[test]
fn test_drop_in_insert() {
use std::cell::Cell;
let flag = &Cell::new(0);
struct Bump<'a>(&'a Cell<i32>);
impl<'a> Drop for Bump<'a> {
fn drop(&mut self) {
let n = self.0.get();
self.0.set(n + 1);
}
}
flag.set(0);
{
let mut array = ArrayVec::<_, 2>::new();
array.push(Bump(flag));
array.insert(0, Bump(flag));
assert_eq!(flag.get(), 0);
let ret = array.try_insert(1, Bump(flag));
assert_eq!(flag.get(), 0);
assert_matches!(ret, Err(_));
drop(ret);
assert_eq!(flag.get(), 1);
}
assert_eq!(flag.get(), 3);
}
#[test]
fn test_pop_at() {
let mut v = ArrayVec::<String, 4>::new();
let s = String::from;
v.push(s("a"));
v.push(s("b"));
v.push(s("c"));
v.push(s("d"));
assert_eq!(v.pop_at(4), None);
assert_eq!(v.pop_at(1), Some(s("b")));
assert_eq!(v.pop_at(1), Some(s("c")));
assert_eq!(v.pop_at(2), None);
assert_eq!(&v[..], &["a", "d"]);
}
#[test]
fn test_sizes() {
let v = ArrayVec::from([0u8; 1 << 16]);
assert_eq!(vec![0u8; v.len()], &v[..]);
}
#[test]
fn test_default() {
use std::net;
let s: ArrayString<4> = Default::default();
// Something without `Default` implementation.
let v: ArrayVec<net::TcpStream, 4> = Default::default();
assert_eq!(s.len(), 0);
assert_eq!(v.len(), 0);
}
#[test]
fn test_extend_zst() {
let mut range = 0..10;
#[derive(Copy, Clone, PartialEq, Debug)]
struct Z; // Zero sized type
let mut array: ArrayVec<_, 5> = range.by_ref().take(5).map(|_| Z).collect();
assert_eq!(&array[..], &[Z; 5]);
assert_eq!(range.next(), Some(5));
array.extend(range.by_ref().take(0).map(|_| Z));
assert_eq!(range.next(), Some(6));
let mut array: ArrayVec<_, 10> = (0..3).map(|_| Z).collect();
assert_eq!(&array[..], &[Z; 3]);
array.extend((3..5).map(|_| Z));
assert_eq!(&array[..], &[Z; 5]);
assert_eq!(array.len(), 5);
}
#[test]
fn test_try_from_argument() {
use core::convert::TryFrom;
let v = ArrayString::<16>::try_from(format_args!("Hello {}", 123)).unwrap();
assert_eq!(&v, "Hello 123");
}
#[test]
fn allow_max_capacity_arrayvec_type() {
// this type is allowed to be used (but can't be constructed)
let _v: ArrayVec<(), {usize::MAX}>;
}
#[should_panic(expected="largest supported capacity")]
#[test]
fn deny_max_capacity_arrayvec_value() {
if mem::size_of::<usize>() <= mem::size_of::<u32>() {
panic!("This test does not work on this platform. 'largest supported capacity'");
}
// this type is allowed to be used (but can't be constructed)
let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new();
}
#[should_panic(expected="index out of bounds")]
#[test]
fn deny_max_capacity_arrayvec_value_const() {
if mem::size_of::<usize>() <= mem::size_of::<u32>() {
panic!("This test does not work on this platform. 'index out of bounds'");
}
// this type is allowed to be used (but can't be constructed)
let _v: ArrayVec<(), {usize::MAX}> = ArrayVec::new_const();
}
#[test]
fn test_arrayvec_const_constructible() {
const OF_U8: ArrayVec<Vec<u8>, 10> = ArrayVec::new_const();
let mut var = OF_U8;
assert!(var.is_empty());
assert_eq!(var, ArrayVec::new());
var.push(vec![3, 5, 8]);
assert_eq!(var[..], [vec![3, 5, 8]]);
}
#[test]
fn test_arraystring_const_constructible() {
const AS: ArrayString<10> = ArrayString::new_const();
let mut var = AS;
assert!(var.is_empty());
assert_eq!(var, ArrayString::new());
var.push_str("hello");
assert_eq!(var, *"hello");
}
#[test]
fn test_arraystring_zero_filled_has_some_sanity_checks() {
let string = ArrayString::<4>::zero_filled();
assert_eq!(string.as_str(), "\0\0\0\0");
assert_eq!(string.len(), 4);
}