summaryrefslogtreecommitdiff
path: root/vendor/beef
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
committermo khan <mo@mokhan.ca>2025-07-02 18:36:06 -0600
commit8cdfa445d6629ffef4cb84967ff7017654045bc2 (patch)
tree22f0b0907c024c78d26a731e2e1f5219407d8102 /vendor/beef
parent4351c74c7c5f97156bc94d3a8549b9940ac80e3f (diff)
chore: add vendor directory
Diffstat (limited to 'vendor/beef')
-rw-r--r--vendor/beef/.cargo-checksum.json1
-rw-r--r--vendor/beef/Cargo.toml55
-rw-r--r--vendor/beef/LICENSE-APACHE201
-rw-r--r--vendor/beef/LICENSE-MIT21
-rw-r--r--vendor/beef/README.md121
-rw-r--r--vendor/beef/benches/bench.rs181
-rwxr-xr-xvendor/beef/ci/miri.sh12
-rw-r--r--vendor/beef/src/generic.rs553
-rw-r--r--vendor/beef/src/lean.rs69
-rw-r--r--vendor/beef/src/lib.rs285
-rw-r--r--vendor/beef/src/serde.rs149
-rw-r--r--vendor/beef/src/traits.rs175
-rw-r--r--vendor/beef/src/wide.rs42
13 files changed, 1865 insertions, 0 deletions
diff --git a/vendor/beef/.cargo-checksum.json b/vendor/beef/.cargo-checksum.json
new file mode 100644
index 00000000..3a0a466a
--- /dev/null
+++ b/vendor/beef/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"b36bcc93cd331f932df3088f291f66a98387c4bf09638795379d1ab22f38bbcc","LICENSE-APACHE":"fe99bc314b2672132fe8b986fdcdf5a4ffb29edfdf6bf79ec88ccc6cbe092b13","LICENSE-MIT":"809a5649163758f9182c72fa09fd50a426b5966dd1b4720915ba024c6b910356","README.md":"01dfa5646b2baba36179b7fe48275eac40b5f5f3cd60f9b4ba3e2903249ed52f","benches/bench.rs":"3ac89c15af14b72e32db96889dbee521f8c3a45de06f7a4febbba55db58a77d8","ci/miri.sh":"8db4f5b506fee85897d4000a51026d09e63447fe0b82cdf2510dbcfb33612297","src/generic.rs":"4036c6f3fd409658083b9cfaa9b52d31f13b7899b687b4aa5eff669d14d12206","src/lean.rs":"c0399c722b61c024783db2b5554b4de004a329f6cf9796ffa92d4dc966d63cc2","src/lib.rs":"f0bb153f21d7259be0d688fcc10489e2f444a0fb352b8ad884bed45234718a95","src/serde.rs":"e8f3bd3f23068b6c3ad7b7557f24bac5b4c503f1dba63eb8e3744ee93315ae90","src/traits.rs":"7f3e37e70c9fd0507a33031587f88ff1672575e6b77891846970bd084797a91c","src/wide.rs":"91b2abbc5a39e9897668cfff4c0bf7ac1b2dd9b1076da0a329f60f174efec065"},"package":"3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"} \ No newline at end of file
diff --git a/vendor/beef/Cargo.toml b/vendor/beef/Cargo.toml
new file mode 100644
index 00000000..0e5a1ab8
--- /dev/null
+++ b/vendor/beef/Cargo.toml
@@ -0,0 +1,55 @@
+# 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"
+name = "beef"
+version = "0.5.2"
+authors = ["Maciej Hirsz <hello@maciej.codes>"]
+description = "More compact Cow"
+documentation = "https://docs.rs/beef/"
+readme = "./README.md"
+keywords = [
+ "cow",
+ "borrow",
+ "str",
+ "slice",
+]
+categories = [
+ "no-std",
+ "memory-management",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/maciejhirsz/beef"
+
+[profile.bench]
+opt-level = 3
+lto = "fat"
+codegen-units = 1
+debug = false
+debug-assertions = false
+
+[dependencies.serde]
+version = "1.0.105"
+features = ["alloc"]
+optional = true
+default-features = false
+
+[dev-dependencies.serde_derive]
+version = "1.0.105"
+
+[dev-dependencies.serde_json]
+version = "1.0"
+
+[features]
+const_fn = []
+default = []
+impl_serde = ["serde"]
diff --git a/vendor/beef/LICENSE-APACHE b/vendor/beef/LICENSE-APACHE
new file mode 100644
index 00000000..efd038e5
--- /dev/null
+++ b/vendor/beef/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright 2020 Maciej Hirsz <hello@maciej.codes>
+
+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/vendor/beef/LICENSE-MIT b/vendor/beef/LICENSE-MIT
new file mode 100644
index 00000000..8c02fab0
--- /dev/null
+++ b/vendor/beef/LICENSE-MIT
@@ -0,0 +1,21 @@
+Copyright (c) 2020 Maciej Hirsz <hello@maciej.codes>
+
+The MIT License (MIT)
+
+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/vendor/beef/README.md b/vendor/beef/README.md
new file mode 100644
index 00000000..73aed63a
--- /dev/null
+++ b/vendor/beef/README.md
@@ -0,0 +1,121 @@
+# beef
+
+[![Travis shield](https://travis-ci.org/maciejhirsz/beef.svg)](https://travis-ci.org/maciejhirsz/beef)
+[![Crates.io version shield](https://img.shields.io/crates/v/beef.svg)](https://crates.io/crates/beef)
+[![Crates.io license shield](https://img.shields.io/crates/l/beef.svg)](https://crates.io/crates/beef)
+
+Faster, more compact implementation of `Cow`.
+
+**[Changelog](https://github.com/maciejhirsz/beef/releases) -**
+**[Documentation](https://docs.rs/beef/) -**
+**[Cargo](https://crates.io/crates/beef) -**
+**[Repository](https://github.com/maciejhirsz/beef)**
+
+```rust
+use beef::Cow;
+
+let borrowed: Cow<str> = Cow::borrowed("Hello");
+let owned: Cow<str> = Cow::owned(String::from("World"));
+
+assert_eq!(
+ format!("{} {}!", borrowed, owned),
+ "Hello World!",
+);
+```
+
+There are two versions of `Cow` exposed by this crate:
+
++ `beef::Cow` is 3 words wide: pointer, length, and capacity. It stores the ownership tag in capacity.
++ `beef::lean::Cow` is 2 words wide, storing length, capacity, and the ownership tag all in one word.
+
+Both versions are leaner than the `std::borrow::Cow`:
+
+```rust
+use std::mem::size_of;
+
+const WORD: usize = size_of::<usize>();
+
+assert_eq!(size_of::<std::borrow::Cow<str>>(), 4 * WORD);
+assert_eq!(size_of::<beef::Cow<str>>(), 3 * WORD);
+assert_eq!(size_of::<beef::lean::Cow<str>>(), 2 * WORD);
+```
+
+## How does it work?
+
+The standard library `Cow` is an enum with two variants:
+
+```rust
+pub enum Cow<'a, B> where
+ B: 'a + ToOwned + ?Sized,
+{
+ Borrowed(&'a B),
+ Owned(<B as ToOwned>::Owned),
+}
+```
+
+For the most common pairs of values - `&str` and `String`, or `&[u8]` and `Vec<u8>` - this
+means that the entire enum is 4 words wide:
+
+```text
+ Padding
+ |
+ v
+ +-----------+-----------+-----------+-----------+
+Borrowed: | Tag | Pointer | Length | XXXXXXXXX |
+ +-----------+-----------+-----------+-----------+
+
+ +-----------+-----------+-----------+-----------+
+Owned: | Tag | Pointer | Length | Capacity |
+ +-----------+-----------+-----------+-----------+
+```
+
+Instead of being an enum with a tag, `beef::Cow` uses capacity to determine whether the
+value it's holding is owned (capacity is greater than 0), or borrowed (capacity is 0).
+
+`beef::lean::Cow` goes even further and puts length and capacity on a single 64 word.
+
+```text
+ +-----------+-----------+-----------+
+beef::Cow | Pointer | Length | Capacity? |
+ +-----------+-----------+-----------+
+
+ +-----------+-----------+
+beef::lean::Cow | Pointer | Cap | Len |
+ +-----------+-----------+
+```
+
+Any owned `Vec` or `String` that has 0 capacity is effectively treated as a borrowed
+value. Since having no capacity means there is no actual allocation behind the pointer,
+this is safe.
+
+## Benchmarks
+
+```
+cargo +nightly bench
+```
+
+Microbenchmarking obtaining a `&str` reference is rather flaky and you can have widely different results. In general the following seems to hold true:
+
++ `beef::Cow` and `beef::lean::Cow` are faster than `std::borrow::Cow` at obtaining a reference `&T`. This makes sense since we avoid the enum tag branching.
++ The 3-word `beef::Cow` is faster at creating borrowed variants, but slower at creating owned variants than `std::borrow::Cow`.
++ The 2-word `beef::lean::Cow` is faster at both.
+
+```
+running 9 tests
+test beef_as_ref ... bench: 57 ns/iter (+/- 15)
+test beef_create ... bench: 135 ns/iter (+/- 5)
+test beef_create_mixed ... bench: 659 ns/iter (+/- 52)
+test lean_beef_as_ref ... bench: 50 ns/iter (+/- 2)
+test lean_beef_create ... bench: 77 ns/iter (+/- 3)
+test lean_beef_create_mixed ... bench: 594 ns/iter (+/- 52)
+test std_as_ref ... bench: 70 ns/iter (+/- 6)
+test std_create ... bench: 142 ns/iter (+/- 7)
+test std_create_mixed ... bench: 663 ns/iter (+/- 32)
+```
+
+## License
+
+This crate is distributed under the terms of both the MIT license
+and the Apache License (Version 2.0). Choose whichever one works best for you.
+
+See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details.
diff --git a/vendor/beef/benches/bench.rs b/vendor/beef/benches/bench.rs
new file mode 100644
index 00000000..0bf12dd9
--- /dev/null
+++ b/vendor/beef/benches/bench.rs
@@ -0,0 +1,181 @@
+#![feature(test)]
+
+extern crate beef;
+extern crate test;
+
+use std::borrow::{Cow as StdCow, ToOwned};
+use test::{black_box, Bencher};
+
+const NTH_WORD: usize = 4;
+static TEXT: &str = "In less than a half-hour, Joe had distributed ninety-two paper cups of tomato juice containing AUM, the drug that promised to turn neophobes into neophiles. He stood in Pioneer Court, just north of the Michigan Avenue Bridge, at a table from which hung a poster reading FREE TOMATO JUICE. Each person who took a cupful was invited to fill out a short questionnaire and leave it in a box on Joe's table. However, Joe explained, the questionnaire was optional, and anyone who wanted to drink the tomato juice and run was welcome to do so.";
+
+#[bench]
+fn beef_create(b: &mut Bencher) {
+ use beef::Cow;
+
+ let words: Vec<_> = TEXT.split_whitespace().collect();
+
+ b.iter(|| {
+ let cow_words: Vec<Cow<str>> = words.iter().copied().map(Cow::borrowed).collect();
+
+ black_box(cow_words)
+ });
+}
+
+#[bench]
+fn beef_create_mixed(b: &mut Bencher) {
+ use beef::Cow;
+
+ let words: Vec<_> = TEXT.split_whitespace().collect();
+
+ b.iter(|| {
+ let cow_words: Vec<Cow<str>> = words
+ .iter()
+ .copied()
+ .map(|word| {
+ if word.len() % NTH_WORD == 0 {
+ Cow::owned(word.to_owned())
+ } else {
+ Cow::borrowed(word)
+ }
+ })
+ .collect();
+
+ black_box(cow_words)
+ });
+}
+
+#[bench]
+fn beef_as_ref(b: &mut Bencher) {
+ use beef::Cow;
+
+ let cow_words: Vec<_> = TEXT
+ .split_whitespace()
+ .map(|word| {
+ if word.len() % NTH_WORD == 0 {
+ Cow::owned(word.to_owned())
+ } else {
+ Cow::borrowed(word)
+ }
+ })
+ .collect();
+
+ b.iter(|| {
+ for word in cow_words.iter() {
+ let word: &str = word.as_ref();
+ black_box(word);
+ }
+ });
+}
+
+#[bench]
+fn lean_beef_create(b: &mut Bencher) {
+ use beef::lean::Cow;
+
+ let words: Vec<_> = TEXT.split_whitespace().collect();
+
+ b.iter(|| {
+ let cow_words: Vec<Cow<str>> = words.iter().copied().map(Cow::borrowed).collect();
+
+ black_box(cow_words)
+ });
+}
+
+#[bench]
+fn lean_beef_create_mixed(b: &mut Bencher) {
+ use beef::lean::Cow;
+
+ let words: Vec<_> = TEXT.split_whitespace().collect();
+
+ b.iter(|| {
+ let cow_words: Vec<Cow<str>> = words
+ .iter()
+ .copied()
+ .map(|word| {
+ if word.len() % NTH_WORD == 0 {
+ Cow::owned(word.to_owned())
+ } else {
+ Cow::borrowed(word)
+ }
+ })
+ .collect();
+
+ black_box(cow_words)
+ });
+}
+
+#[bench]
+fn lean_beef_as_ref(b: &mut Bencher) {
+ use beef::lean::Cow;
+
+ let cow_words: Vec<_> = TEXT
+ .split_whitespace()
+ .map(|word| {
+ if word.len() % NTH_WORD == 0 {
+ Cow::owned(word.to_owned())
+ } else {
+ Cow::borrowed(word)
+ }
+ })
+ .collect();
+
+ b.iter(|| {
+ for word in cow_words.iter() {
+ let word: &str = word.as_ref();
+ black_box(word);
+ }
+ });
+}
+
+#[bench]
+fn std_create(b: &mut Bencher) {
+ let words: Vec<_> = TEXT.split_whitespace().collect();
+
+ b.iter(|| {
+ let stdcow_words: Vec<StdCow<str>> = words.iter().copied().map(StdCow::Borrowed).collect();
+
+ black_box(stdcow_words)
+ });
+}
+
+#[bench]
+fn std_create_mixed(b: &mut Bencher) {
+ let words: Vec<_> = TEXT.split_whitespace().collect();
+
+ b.iter(|| {
+ let stdcow_words: Vec<StdCow<str>> = words
+ .iter()
+ .copied()
+ .map(|word| {
+ if word.len() % NTH_WORD == 0 {
+ StdCow::Owned(word.to_owned())
+ } else {
+ StdCow::Borrowed(word)
+ }
+ })
+ .collect();
+
+ black_box(stdcow_words)
+ });
+}
+
+#[bench]
+fn std_as_ref(b: &mut Bencher) {
+ let stdcow_words: Vec<_> = TEXT
+ .split_whitespace()
+ .map(|word| {
+ if word.len() % NTH_WORD == 0 {
+ StdCow::Owned(word.to_owned())
+ } else {
+ StdCow::Borrowed(word)
+ }
+ })
+ .collect();
+
+ b.iter(|| {
+ for word in stdcow_words.iter() {
+ let word: &str = word.as_ref();
+ black_box(word);
+ }
+ });
+}
diff --git a/vendor/beef/ci/miri.sh b/vendor/beef/ci/miri.sh
new file mode 100755
index 00000000..0ffbe96f
--- /dev/null
+++ b/vendor/beef/ci/miri.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+set -e
+
+MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)
+echo "Installing latest nightly with Miri: $MIRI_NIGHTLY"
+rustup set profile minimal
+rustup default "$MIRI_NIGHTLY"
+
+rustup component add miri
+cargo miri setup
+
+MIRIFLAGS='-Zmiri-strict-provenance' cargo miri test --all-features
diff --git a/vendor/beef/src/generic.rs b/vendor/beef/src/generic.rs
new file mode 100644
index 00000000..1d7fa2da
--- /dev/null
+++ b/vendor/beef/src/generic.rs
@@ -0,0 +1,553 @@
+//! This module contains the actual, albeit generic, implementaiton of the `Cow`,
+//! and the traits that are available to it.
+
+use alloc::borrow::{Borrow, Cow as StdCow};
+use alloc::string::String;
+use alloc::vec::Vec;
+use core::cmp::Ordering;
+use core::fmt;
+use core::hash::{Hash, Hasher};
+use core::marker::PhantomData;
+use core::mem::ManuallyDrop;
+use core::ptr::NonNull;
+
+#[cfg(target_pointer_width = "64")]
+use crate::lean::internal::Lean;
+use crate::traits::{Beef, Capacity};
+use crate::wide::internal::Wide;
+
+/// A clone-on-write smart pointer, mostly compatible with [`std::borrow::Cow`](https://doc.rust-lang.org/std/borrow/enum.Cow.html).
+///
+/// This type is using a generic `U: Capacity`. Use either [`beef::Cow`](../type.Cow.html) or [`beef::lean::Cow`](../lean/type.Cow.html) in your code.
+pub struct Cow<'a, T: Beef + ?Sized + 'a, U: Capacity> {
+ /// Pointer to data
+ ptr: NonNull<T::PointerT>,
+
+ /// This usize contains length, but it may contain other
+ /// information pending on impl of `Capacity`, and must therefore
+ /// always go through `U::len` or `U::unpack`
+ fat: usize,
+
+ /// Capacity field. For `beef::lean::Cow` this is 0-sized!
+ cap: U::Field,
+
+ /// Lifetime marker
+ marker: PhantomData<&'a T>,
+}
+
+impl<T, U> Cow<'_, T, U>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+{
+ /// Owned data.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use beef::Cow;
+ ///
+ /// let owned: Cow<str> = Cow::owned("I own my content".to_string());
+ /// ```
+ #[inline]
+ pub fn owned(val: T::Owned) -> Self {
+ let (ptr, fat, cap) = T::owned_into_parts::<U>(val);
+
+ Cow {
+ ptr,
+ fat,
+ cap,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'a, T, U> Cow<'a, T, U>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+{
+ /// Borrowed data.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use beef::Cow;
+ ///
+ /// let borrowed: Cow<str> = Cow::borrowed("I'm just a borrow");
+ /// ```
+ #[inline]
+ pub fn borrowed(val: &'a T) -> Self {
+ let (ptr, fat, cap) = T::ref_into_parts::<U>(val);
+
+ Cow {
+ ptr,
+ fat,
+ cap,
+ marker: PhantomData,
+ }
+ }
+
+ /// Extracts the owned data.
+ ///
+ /// Clones the data if it is not already owned.
+ #[inline]
+ pub fn into_owned(self) -> T::Owned {
+ let cow = ManuallyDrop::new(self);
+
+ match cow.capacity() {
+ Some(capacity) => unsafe { T::owned_from_parts::<U>(cow.ptr, cow.fat, capacity) },
+ None => unsafe { &*T::ref_from_parts::<U>(cow.ptr, cow.fat) }.to_owned(),
+ }
+ }
+
+ /// Extracts borrowed data.
+ ///
+ /// Panics: If the data is owned.
+ #[inline]
+ pub fn unwrap_borrowed(self) -> &'a T {
+ if self.capacity().is_some() {
+ panic!("Can not turn owned beef::Cow into a borrowed value")
+ }
+ unsafe { &*T::ref_from_parts::<U>(self.ptr, self.fat) }
+ }
+
+ /// Returns `true` if data is borrowed or had no capacity.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use beef::Cow;
+ ///
+ /// let borrowed: Cow<str> = Cow::borrowed("Borrowed");
+ /// let no_capacity: Cow<str> = Cow::owned(String::new());
+ /// let owned: Cow<str> = Cow::owned(String::from("Owned"));
+ ///
+ /// assert_eq!(borrowed.is_borrowed(), true);
+ /// assert_eq!(no_capacity.is_borrowed(), true);
+ /// assert_eq!(owned.is_borrowed(), false);
+ /// ```
+ #[inline]
+ pub fn is_borrowed(&self) -> bool {
+ self.capacity().is_none()
+ }
+
+ /// Returns `true` if data is owned and has non-0 capacity.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use beef::Cow;
+ ///
+ /// let borrowed: Cow<str> = Cow::borrowed("Borrowed");
+ /// let no_capacity: Cow<str> = Cow::owned(String::new());
+ /// let owned: Cow<str> = Cow::owned(String::from("Owned"));
+ ///
+ /// assert_eq!(borrowed.is_owned(), false);
+ /// assert_eq!(no_capacity.is_owned(), false);
+ /// assert_eq!(owned.is_owned(), true);
+ /// ```
+ #[inline]
+ pub fn is_owned(&self) -> bool {
+ self.capacity().is_some()
+ }
+
+ /// Internal convenience method for casting `ptr` into a `&T`
+ #[inline]
+ fn borrow(&self) -> &T {
+ unsafe { &*T::ref_from_parts::<U>(self.ptr, self.fat) }
+ }
+
+ #[inline]
+ fn capacity(&self) -> Option<U::NonZero> {
+ U::maybe(self.fat, self.cap)
+ }
+}
+
+impl<'a> Cow<'a, str, Wide> {
+ /// Borrowed data.
+ ///
+ /// This is functionally identical to [`borrow`](./generic/struct.Cow.html#method.borrow).
+ /// We use impl specialization to allow this function to be `const`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use beef::Cow;
+ ///
+ /// const HELLO: Cow<str> = Cow::const_str("Hello");
+ /// ```
+ pub const fn const_str(val: &'a str) -> Self {
+ Cow {
+ // We are casting *const T to *mut T, however for all borrowed values
+ // this raw pointer is only ever dereferenced back to &T.
+ ptr: unsafe { NonNull::new_unchecked(val.as_ptr() as *mut u8) },
+ fat: val.len(),
+ cap: None,
+ marker: PhantomData,
+ }
+ }
+}
+
+#[cfg(target_pointer_width = "64")]
+impl<'a> Cow<'a, str, Lean> {
+ /// Borrowed data.
+ ///
+ /// This is functionally identical to [`borrow`](./generic/struct.Cow.html#method.borrow).
+ /// We use impl specialization to allow this function to be `const`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use beef::lean::Cow;
+ ///
+ /// const HELLO: Cow<str> = Cow::const_str("Hello");
+ /// ```
+ pub const fn const_str(val: &'a str) -> Self {
+ Cow {
+ // We are casting *const T to *mut T, however for all borrowed values
+ // this raw pointer is only ever dereferenced back to &T.
+ ptr: unsafe { NonNull::new_unchecked(val.as_ptr() as *mut u8) },
+ fat: Lean::mask_len(val.len()),
+ cap: Lean,
+ marker: PhantomData,
+ }
+ }
+}
+
+// This requires nightly:
+// https://github.com/rust-lang/rust/issues/57563
+#[cfg(feature = "const_fn")]
+impl<'a, T> Cow<'a, [T], Wide>
+where
+ T: Clone,
+{
+ /// Borrowed data.
+ ///
+ /// This is functionally identical to [`borrow`](./generic/struct.Cow.html#method.borrow).
+ /// We use impl specialization to allow this function to be `const`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use beef::Cow;
+ ///
+ /// const HELLO: Cow<[u8]> = Cow::const_slice(&[1, 2, 3]);
+ /// ```
+ pub const fn const_slice(val: &'a [T]) -> Self {
+ Cow {
+ // We are casting *const T to *mut T, however for all borrowed values
+ // this raw pointer is only ever dereferenced back to &T.
+ ptr: unsafe { NonNull::new_unchecked(val.as_ptr() as *mut T) },
+ fat: val.len(),
+ cap: None,
+ marker: PhantomData,
+ }
+ }
+}
+
+// This requires nightly:
+// https://github.com/rust-lang/rust/issues/57563
+#[cfg(all(feature = "const_fn", target_pointer_width = "64"))]
+impl<'a, T> Cow<'a, [T], Lean>
+where
+ T: Clone,
+{
+ /// Borrowed data.
+ ///
+ /// This i functionally identical to [`borrow`](./generic/struct.Cow.html#method.borrow).
+ /// We use impl specialization to allow this function to be `const`.
+ ///
+ /// # Example
+ ///
+ /// ```rust
+ /// use beef::lean::Cow;
+ ///
+ /// const HELLO: Cow<[u8]> = Cow::const_slice(&[1, 2, 3]);
+ /// ```
+ pub const fn const_slice(val: &'a [T]) -> Self {
+ Cow {
+ // We are casting *const T to *mut T, however for all borrowed values
+ // this raw pointer is only ever dereferenced back to &T.
+ ptr: unsafe { NonNull::new_unchecked(val.as_ptr() as *mut T) },
+ fat: Lean::mask_len(val.len()),
+ cap: Lean,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<T, U> Hash for Cow<'_, T, U>
+where
+ T: Hash + Beef + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.borrow().hash(state)
+ }
+}
+
+impl<'a, T, U> Default for Cow<'a, T, U>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+ &'a T: Default,
+{
+ #[inline]
+ fn default() -> Self {
+ Cow::borrowed(Default::default())
+ }
+}
+
+impl<T, U> Eq for Cow<'_, T, U>
+where
+ T: Eq + Beef + ?Sized,
+ U: Capacity,
+{
+}
+
+impl<A, B, U, V> PartialOrd<Cow<'_, B, V>> for Cow<'_, A, U>
+where
+ A: Beef + ?Sized + PartialOrd<B>,
+ B: Beef + ?Sized,
+ U: Capacity,
+ V: Capacity,
+{
+ #[inline]
+ fn partial_cmp(&self, other: &Cow<'_, B, V>) -> Option<Ordering> {
+ PartialOrd::partial_cmp(self.borrow(), other.borrow())
+ }
+}
+
+impl<T, U> Ord for Cow<'_, T, U>
+where
+ T: Ord + Beef + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn cmp(&self, other: &Self) -> Ordering {
+ Ord::cmp(self.borrow(), other.borrow())
+ }
+}
+
+impl<'a, T, U> From<&'a T> for Cow<'a, T, U>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn from(val: &'a T) -> Self {
+ Cow::borrowed(val)
+ }
+}
+
+impl<U> From<String> for Cow<'_, str, U>
+where
+ U: Capacity,
+{
+ #[inline]
+ fn from(s: String) -> Self {
+ Cow::owned(s)
+ }
+}
+
+impl<T, U> From<Vec<T>> for Cow<'_, [T], U>
+where
+ T: Clone,
+ U: Capacity,
+{
+ #[inline]
+ fn from(v: Vec<T>) -> Self {
+ Cow::owned(v)
+ }
+}
+
+impl<T, U> Drop for Cow<'_, T, U>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn drop(&mut self) {
+ if let Some(capacity) = self.capacity() {
+ unsafe { T::owned_from_parts::<U>(self.ptr, self.fat, capacity) };
+ }
+ }
+}
+
+impl<'a, T, U> Clone for Cow<'a, T, U>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn clone(&self) -> Self {
+ match self.capacity() {
+ Some(_) => Cow::owned(self.borrow().to_owned()),
+ None => Cow { ..*self },
+ }
+ }
+}
+
+impl<T, U> core::ops::Deref for Cow<'_, T, U>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+{
+ type Target = T;
+
+ #[inline]
+ fn deref(&self) -> &T {
+ self.borrow()
+ }
+}
+
+impl<T, U> AsRef<T> for Cow<'_, T, U>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn as_ref(&self) -> &T {
+ self.borrow()
+ }
+}
+
+impl<T, U> Borrow<T> for Cow<'_, T, U>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn borrow(&self) -> &T {
+ self.borrow()
+ }
+}
+
+impl<'a, T, U> From<StdCow<'a, T>> for Cow<'a, T, U>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn from(stdcow: StdCow<'a, T>) -> Self {
+ match stdcow {
+ StdCow::Borrowed(v) => Self::borrowed(v),
+ StdCow::Owned(v) => Self::owned(v),
+ }
+ }
+}
+
+impl<'a, T, U> From<Cow<'a, T, U>> for StdCow<'a, T>
+where
+ T: Beef + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn from(cow: Cow<'a, T, U>) -> Self {
+ let cow = ManuallyDrop::new(cow);
+
+ match cow.capacity() {
+ Some(capacity) => {
+ StdCow::Owned(unsafe { T::owned_from_parts::<U>(cow.ptr, cow.fat, capacity) })
+ }
+ None => StdCow::Borrowed(unsafe { &*T::ref_from_parts::<U>(cow.ptr, cow.fat) }),
+ }
+ }
+}
+
+impl<A, B, U, V> PartialEq<Cow<'_, B, V>> for Cow<'_, A, U>
+where
+ A: Beef + ?Sized,
+ B: Beef + ?Sized,
+ U: Capacity,
+ V: Capacity,
+ A: PartialEq<B>,
+{
+ fn eq(&self, other: &Cow<B, V>) -> bool {
+ self.borrow() == other.borrow()
+ }
+}
+
+macro_rules! impl_eq {
+ ($($(@for< $bounds:tt >)? $ptr:ty => $([$($deref:tt)+])? <$with:ty>,)*) => {$(
+ impl<U $(, $bounds)*> PartialEq<$with> for Cow<'_, $ptr, U>
+ where
+ U: Capacity,
+ $( $bounds: Clone + PartialEq, )*
+ {
+ #[inline]
+ fn eq(&self, other: &$with) -> bool {
+ self.borrow() == $($($deref)*)* other
+ }
+ }
+
+ impl<U $(, $bounds)*> PartialEq<Cow<'_, $ptr, U>> for $with
+ where
+ U: Capacity,
+ $( $bounds: Clone + PartialEq, )*
+ {
+ #[inline]
+ fn eq(&self, other: &Cow<$ptr, U>) -> bool {
+ $($($deref)*)* self == other.borrow()
+ }
+ }
+ )*};
+}
+
+impl_eq! {
+ str => <str>,
+ str => [*]<&str>,
+ str => <String>,
+ @for<T> [T] => <[T]>,
+ @for<T> [T] => [*]<&[T]>,
+ @for<T> [T] => [&**]<Vec<T>>,
+}
+
+impl<T, U> fmt::Debug for Cow<'_, T, U>
+where
+ T: Beef + fmt::Debug + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.borrow().fmt(f)
+ }
+}
+
+impl<T, U> fmt::Display for Cow<'_, T, U>
+where
+ T: Beef + fmt::Display + ?Sized,
+ U: Capacity,
+{
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.borrow().fmt(f)
+ }
+}
+
+// Safety: Same bounds as `std::borrow::Cow`.
+unsafe impl<T, U> Sync for Cow<'_, T, U>
+where
+ U: Capacity,
+ T: Beef + Sync + ?Sized,
+ T::Owned: Sync,
+{
+}
+
+unsafe impl<T, U> Send for Cow<'_, T, U>
+where
+ U: Capacity,
+ T: Beef + Sync + ?Sized,
+ T::Owned: Send,
+{
+}
+
+impl<T, U> Unpin for Cow<'_, T, U>
+where
+ U: Capacity,
+ T: Beef + ?Sized,
+ T::Owned: Unpin,
+{
+}
diff --git a/vendor/beef/src/lean.rs b/vendor/beef/src/lean.rs
new file mode 100644
index 00000000..cb3c1943
--- /dev/null
+++ b/vendor/beef/src/lean.rs
@@ -0,0 +1,69 @@
+//! Namespace containing the 2-word `Cow` implementation.
+
+use crate::traits::Capacity;
+
+/// Faster, 2-word `Cow`. This version is available only on 64-bit architecture,
+/// and it puts both capacity and length together in a fat pointer. Both length and capacity
+/// is limited to 32 bits.
+///
+/// # Panics
+///
+/// [`Cow::owned`](../generic/struct.Cow.html#method.owned) will panic if capacity is larger than `u32::max_size()`. Use the
+/// top level `beef::Cow` if you wish to avoid this problem.
+pub type Cow<'a, T> = crate::generic::Cow<'a, T, Lean>;
+
+pub(crate) mod internal {
+ #[derive(Clone, Copy, PartialEq, Eq)]
+ pub struct Lean;
+}
+use internal::Lean;
+
+const MASK_LO: usize = u32::MAX as usize;
+const MASK_HI: usize = !MASK_LO;
+
+impl Lean {
+ #[inline]
+ pub const fn mask_len(len: usize) -> usize {
+ len & MASK_LO
+ }
+}
+
+impl Capacity for Lean {
+ type Field = Lean;
+ type NonZero = Lean;
+
+ #[inline]
+ fn len(fat: usize) -> usize {
+ fat & MASK_LO
+ }
+
+ #[inline]
+ fn empty(len: usize) -> (usize, Lean) {
+ (len & MASK_LO, Lean)
+ }
+
+ #[inline]
+ fn store(len: usize, capacity: usize) -> (usize, Lean) {
+ if capacity & MASK_HI != 0 {
+ panic!("beef::lean::Cow: Capacity out of bounds");
+ }
+
+ let fat = ((capacity & MASK_LO) << 32) | (len & MASK_LO);
+
+ (fat, Lean)
+ }
+
+ #[inline]
+ fn unpack(fat: usize, _: Lean) -> (usize, usize) {
+ (fat & MASK_LO, (fat & MASK_HI) >> 32)
+ }
+
+ #[inline]
+ fn maybe(fat: usize, _: Lean) -> Option<Lean> {
+ if fat & MASK_HI != 0 {
+ Some(Lean)
+ } else {
+ None
+ }
+ }
+}
diff --git a/vendor/beef/src/lib.rs b/vendor/beef/src/lib.rs
new file mode 100644
index 00000000..62a503a3
--- /dev/null
+++ b/vendor/beef/src/lib.rs
@@ -0,0 +1,285 @@
+//! Faster, more compact implementation of `Cow`.
+//!
+//! **[Changelog](https://github.com/maciejhirsz/beef/releases) -**
+//! **[Cargo](https://crates.io/crates/beef) -**
+//! **[Repository](https://github.com/maciejhirsz/beef)**
+//!
+//! ```rust
+//! use beef::Cow;
+//!
+//! let borrowed: Cow<str> = Cow::borrowed("Hello");
+//! let owned: Cow<str> = Cow::owned(String::from("World"));
+//!
+//! assert_eq!(
+//! format!("{} {}!", borrowed, owned),
+//! "Hello World!",
+//! );
+//! ```
+//!
+//! There are two versions of `Cow` exposed by this crate:
+//!
+//! + `beef::Cow` is 3 words wide: pointer, length, and capacity. It stores the ownership tag in capacity.
+//! + `beef::lean::Cow` is 2 words wide, storing length, capacity, and the ownership tag all in one word.
+//!
+//! Both versions are leaner than the `std::borrow::Cow`:
+//!
+//! ```rust
+//! use std::mem::size_of;
+//!
+//! const WORD: usize = size_of::<usize>();
+//!
+//! assert_eq!(size_of::<std::borrow::Cow<str>>(), 4 * WORD);
+//! assert_eq!(size_of::<beef::Cow<str>>(), 3 * WORD);
+//!
+//! // Lean variant is two words on 64-bit architecture
+//! #[cfg(target_pointer_width = "64")]
+//! assert_eq!(size_of::<beef::lean::Cow<str>>(), 2 * WORD);
+//! ```
+#![cfg_attr(feature = "const_fn", feature(const_fn_trait_bound))]
+#![warn(missing_docs)]
+#![cfg_attr(not(test), no_std)]
+extern crate alloc;
+
+mod traits;
+mod wide;
+
+#[cfg(feature = "impl_serde")]
+mod serde;
+
+pub mod generic;
+#[cfg(target_pointer_width = "64")]
+pub mod lean;
+
+#[cfg(not(target_pointer_width = "64"))]
+pub mod lean {
+ /// Re-exports 3-word Cow for non-64-bit targets
+ pub use super::wide::Cow;
+}
+
+pub use wide::Cow;
+
+#[rustfmt::skip]
+macro_rules! test { ($tmod:ident => $cow:path) => {
+ #[cfg(test)]
+ mod $tmod {
+ use $cow;
+
+ #[test]
+ fn borrowed_str() {
+ let s = "Hello World";
+ let c = Cow::borrowed(s);
+
+ assert_eq!(s, c);
+ assert_eq!(s, c.as_ref());
+ assert_eq!(s, &*c);
+ }
+
+ #[test]
+ fn owned_string() {
+ let s = String::from("Hello World");
+ let c: Cow<str> = Cow::owned(s.clone());
+
+ assert_eq!(s, c);
+ }
+
+ #[test]
+ fn into_owned() {
+ let hello = "Hello World";
+ let borrowed = Cow::borrowed(hello);
+ let owned: Cow<str> = Cow::owned(String::from(hello));
+
+ assert_eq!(borrowed.into_owned(), hello);
+ assert_eq!(owned.into_owned(), hello);
+ }
+
+ #[test]
+ fn borrowed_slice() {
+ let s: &[_] = &[1, 2, 42];
+ let c = Cow::borrowed(s);
+
+ assert_eq!(s, c);
+ assert_eq!(s, c.as_ref());
+ assert_eq!(s, &*c);
+ }
+
+ #[test]
+ fn owned_slice() {
+ let s = vec![1, 2, 42];
+ let c: Cow<[_]> = Cow::owned(s.clone());
+
+ assert_eq!(s, c);
+ }
+
+ #[test]
+ fn into_owned_vec() {
+ let hello: &[u8] = b"Hello World";
+ let borrowed = Cow::borrowed(hello);
+ let owned: Cow<[u8]> = Cow::owned(hello.to_vec());
+
+ assert_eq!(borrowed.into_owned(), hello);
+ assert_eq!(owned.into_owned(), hello);
+ }
+
+ #[test]
+ fn hash() {
+ use std::collections::hash_map::DefaultHasher;
+ use std::hash::{Hash, Hasher};
+
+ let slice = "Hello World!";
+ let borrowed = Cow::borrowed(slice);
+ let owned: Cow<str> = Cow::owned(slice.to_owned());
+
+ let hash1 = {
+ let mut hasher = DefaultHasher::default();
+
+ slice.hash(&mut hasher);
+
+ hasher.finish()
+ };
+
+ let hash2 = {
+ let mut hasher = DefaultHasher::default();
+
+ borrowed.hash(&mut hasher);
+
+ hasher.finish()
+ };
+
+ let hash3 = {
+ let mut hasher = DefaultHasher::default();
+
+ owned.hash(&mut hasher);
+
+ hasher.finish()
+ };
+
+ assert_eq!(hash1, hash2);
+ assert_eq!(hash1, hash3);
+ assert_eq!(hash2, hash3);
+ }
+
+ #[test]
+ fn ord_and_partial_ord() {
+ use std::cmp::Ordering;
+
+ macro_rules! generate_order_tests {
+ ( $f:tt => $order:expr => $left:expr, $right:expr ) => {
+ assert_eq!(
+ Cow::<str>::borrowed($left).$f(&Cow::<str>::borrowed($right)),
+ $order
+ );
+
+ assert_eq!(
+ Cow::<str>::owned($left.to_owned())
+ .$f(&Cow::<str>::borrowed($right)),
+ $order
+ );
+
+ assert_eq!(
+ Cow::<str>::borrowed($left)
+ .$f(&Cow::<str>::owned($right.to_owned())),
+ $order
+ );
+
+ assert_eq!(
+ Cow::<str>::owned($left.to_owned())
+ .$f(&Cow::<str>::owned($right.to_owned())),
+ $order
+ );
+ }
+ }
+
+ generate_order_tests!(partial_cmp => Some(Ordering::Equal) => "a", "a");
+ generate_order_tests!(partial_cmp => Some(Ordering::Less) => "a", "b");
+ generate_order_tests!(partial_cmp => Some(Ordering::Greater) => "b", "a");
+
+ generate_order_tests!(cmp => Ordering::Equal => "a", "a");
+ generate_order_tests!(cmp => Ordering::Less => "a", "b");
+ generate_order_tests!(cmp => Ordering::Greater => "b", "a");
+ }
+
+ #[test]
+ fn from_std_cow() {
+ let std = std::borrow::Cow::Borrowed("Hello World");
+ let beef = Cow::from(std.clone());
+
+ assert_eq!(&*std, &*beef);
+ }
+
+ #[test]
+ fn unwrap_borrowed() {
+ let borrowed = Cow::borrowed("Hello");
+
+ assert_eq!(borrowed.unwrap_borrowed(), "Hello");
+ }
+
+ #[test]
+ #[should_panic]
+ fn unwrap_owned() {
+ let borrowed: Cow<str> = Cow::owned("Hello".to_string());
+
+ borrowed.unwrap_borrowed();
+ }
+
+ #[test]
+ fn stress_test_owned() {
+ let mut expected = String::from("Hello... ");
+ let mut cow: Cow<str> = Cow::borrowed("Hello... ");
+
+ #[cfg(not(miri))]
+ let iterations = 1024;
+ #[cfg(miri)]
+ let iterations = 10;
+
+ for i in 0..iterations {
+ if i % 3 == 0 {
+ let old = cow;
+ cow = old.clone();
+
+ std::mem::drop(old);
+ }
+
+ let mut owned = cow.into_owned();
+
+ expected.push_str("Hello?.. ");
+ owned.push_str("Hello?.. ");
+
+ cow = owned.into();
+ }
+
+ assert_eq!(expected, cow.into_owned());
+ }
+
+ #[test]
+ fn const_fn_str() {
+ const HELLO: Cow<str> = Cow::const_str("Hello");
+
+ assert_eq!(&*HELLO, "Hello");
+ }
+
+ #[test]
+ #[cfg(feature = "const_fn")]
+ fn const_fn_slice() {
+ const FOO: Cow<[u8]> = Cow::const_slice(b"bar");
+
+ assert_eq!(&*FOO, b"bar");
+ }
+
+ #[test]
+ fn default_str() {
+ let empty: Cow<str> = Default::default();
+
+ assert_eq!(&*empty, "");
+ }
+
+ #[test]
+ fn default_slice() {
+ let empty: Cow<[u8]> = Default::default();
+
+ assert_eq!(&*empty, b"");
+ }
+ }
+} }
+
+test!(test_wide => crate::wide::Cow);
+test!(test_lean => crate::lean::Cow);
diff --git a/vendor/beef/src/serde.rs b/vendor/beef/src/serde.rs
new file mode 100644
index 00000000..a85fbc6f
--- /dev/null
+++ b/vendor/beef/src/serde.rs
@@ -0,0 +1,149 @@
+use alloc::{borrow::ToOwned, string::String};
+use core::{fmt, marker::PhantomData};
+
+use serde::de::{self, Deserialize, Deserializer, Visitor};
+use serde::ser::{Serialize, Serializer};
+
+use crate::generic::Cow;
+use crate::traits::internal::{Beef, Capacity};
+
+impl<T, U> Serialize for Cow<'_, T, U>
+where
+ T: Beef + Serialize + ?Sized,
+ U: Capacity,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ T::serialize(self.as_ref(), serializer)
+ }
+}
+
+struct CowVisitor<'de, 'a, T: Beef + ?Sized, U: Capacity>(
+ PhantomData<fn() -> (&'de T, Cow<'a, T, U>)>,
+);
+
+impl<'de, 'a, U> Visitor<'de> for CowVisitor<'de, 'a, str, U>
+where
+ 'de: 'a,
+ U: Capacity,
+{
+ type Value = Cow<'a, str, U>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a string")
+ }
+
+ fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Cow::borrowed(value))
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Cow::owned(value.to_owned()))
+ }
+
+ fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Cow::owned(value))
+ }
+}
+
+impl<'de, 'a, U> Deserialize<'de> for Cow<'a, str, U>
+where
+ 'de: 'a,
+ U: Capacity,
+{
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_str(CowVisitor::<'de, 'a, str, U>(PhantomData))
+ }
+}
+
+impl<'de, 'a, T, U> Deserialize<'de> for Cow<'a, [T], U>
+where
+ [T]: Beef,
+ U: Capacity,
+ <[T] as ToOwned>::Owned: Deserialize<'de>,
+{
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ <[T] as ToOwned>::Owned::deserialize(deserializer).map(Cow::owned)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use serde_derive::{Deserialize, Serialize};
+
+ #[test]
+ fn wide_cow_de() {
+ use crate::Cow;
+
+ #[derive(Serialize, Deserialize)]
+ struct Test<'a> {
+ #[serde(borrow)]
+ foo: Cow<'a, str>,
+ bar: Cow<'a, str>,
+ }
+
+ let json = r#"{"foo":"Hello","bar":"\tWorld!"}"#;
+ let test: Test = serde_json::from_str(json).unwrap();
+
+ assert_eq!(test.foo, "Hello");
+ assert_eq!(test.bar, "\tWorld!");
+
+ assert!(test.foo.is_borrowed());
+ assert!(test.bar.is_owned());
+
+ let out = serde_json::to_string(&test).unwrap();
+
+ assert_eq!(json, out);
+ }
+
+ #[test]
+ fn wide_cow_direct() {
+ use crate::Cow;
+
+ let json = r#""foo""#;
+ let cow: Cow<str> = serde_json::from_str(json).unwrap();
+
+ assert_eq!(cow, "foo");
+
+ assert!(cow.is_borrowed());
+
+ let json = r#""\tfoo""#;
+ let cow: Cow<str> = serde_json::from_str(json).unwrap();
+
+ assert_eq!(cow, "\tfoo");
+
+ assert!(cow.is_owned());
+ }
+
+ #[test]
+ fn wide_cow_direct_bytes() {
+ use crate::Cow;
+
+ let json = r#"[102, 111, 111]"#;
+ let cow: Cow<[u8]> = serde_json::from_str(json).unwrap();
+
+ assert_eq!(cow, &b"foo"[..]);
+
+ // We need to stay generic over `[T]`, so no specialization for byte slices
+ assert!(cow.is_owned());
+ }
+}
diff --git a/vendor/beef/src/traits.rs b/vendor/beef/src/traits.rs
new file mode 100644
index 00000000..4be2d2d0
--- /dev/null
+++ b/vendor/beef/src/traits.rs
@@ -0,0 +1,175 @@
+pub(crate) use internal::Beef;
+pub(crate) use internal::Capacity;
+
+pub(crate) mod internal {
+ use alloc::borrow::ToOwned;
+ use alloc::string::String;
+ use alloc::vec::Vec;
+ use core::mem::ManuallyDrop;
+ use core::ptr::{slice_from_raw_parts, NonNull};
+
+ pub trait Capacity {
+ type Field: Copy;
+ type NonZero: Copy;
+
+ fn len(fat: usize) -> usize;
+
+ fn empty(len: usize) -> (usize, Self::Field);
+
+ fn store(len: usize, capacity: usize) -> (usize, Self::Field);
+
+ fn unpack(fat: usize, capacity: Self::NonZero) -> (usize, usize);
+
+ fn maybe(fat: usize, capacity: Self::Field) -> Option<Self::NonZero>;
+ }
+
+ /// Helper trait required by `Cow<T>` to extract capacity of owned
+ /// variant of `T`, and manage conversions.
+ ///
+ /// This can be only implemented on types that match requirements:
+ ///
+ /// + `T::Owned` has a `capacity`, which is an extra word that is absent in `T`.
+ /// + `T::Owned` with `capacity` of `0` does not allocate memory.
+ /// + `T::Owned` can be reconstructed from `*mut T` borrowed out of it, plus capacity.
+ pub unsafe trait Beef: ToOwned {
+ type PointerT;
+
+ fn ref_into_parts<U>(&self) -> (NonNull<Self::PointerT>, usize, U::Field)
+ where
+ U: Capacity;
+
+ unsafe fn ref_from_parts<U>(ptr: NonNull<Self::PointerT>, len: usize) -> *const Self
+ where
+ U: Capacity;
+
+ /// Convert `T::Owned` to `NonNull<T>` and capacity.
+ /// Return `None` for `0` capacity.
+ fn owned_into_parts<U>(owned: Self::Owned) -> (NonNull<Self::PointerT>, usize, U::Field)
+ where
+ U: Capacity;
+
+ /// Rebuild `T::Owned` from `NonNull<T>` and `capacity`. This can be done by the likes
+ /// of [`Vec::from_raw_parts`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.from_raw_parts).
+ unsafe fn owned_from_parts<U>(
+ ptr: NonNull<Self::PointerT>,
+ fat: usize,
+ capacity: U::NonZero,
+ ) -> Self::Owned
+ where
+ U: Capacity;
+ }
+
+ unsafe impl Beef for str {
+ type PointerT = u8;
+
+ #[inline]
+ fn ref_into_parts<U>(&self) -> (NonNull<u8>, usize, U::Field)
+ where
+ U: Capacity,
+ {
+ let (fat, cap) = U::empty(self.len());
+
+ // A note on soundness:
+ //
+ // We are casting *const T to *mut T, however for all borrowed values
+ // this raw pointer is only ever dereferenced back to &T.
+ (
+ unsafe { NonNull::new_unchecked(self.as_ptr() as *mut u8) },
+ fat,
+ cap,
+ )
+ }
+
+ #[inline]
+ unsafe fn ref_from_parts<U>(ptr: NonNull<u8>, fat: usize) -> *const str
+ where
+ U: Capacity,
+ {
+ slice_from_raw_parts(ptr.as_ptr(), U::len(fat)) as *const str
+ }
+
+ #[inline]
+ fn owned_into_parts<U>(owned: String) -> (NonNull<u8>, usize, U::Field)
+ where
+ U: Capacity,
+ {
+ // Convert to `String::into_raw_parts` once stabilized
+ // We need to go through Vec here to get provenance for the entire allocation
+ // instead of just the initialized parts.
+ let mut owned = ManuallyDrop::new(owned.into_bytes());
+ let (fat, cap) = U::store(owned.len(), owned.capacity());
+
+ (
+ unsafe { NonNull::new_unchecked(owned.as_mut_ptr()) },
+ fat,
+ cap,
+ )
+ }
+
+ #[inline]
+ unsafe fn owned_from_parts<U>(ptr: NonNull<u8>, fat: usize, capacity: U::NonZero) -> String
+ where
+ U: Capacity,
+ {
+ let (len, cap) = U::unpack(fat, capacity);
+
+ String::from_utf8_unchecked(Vec::from_raw_parts(ptr.as_ptr(), len, cap))
+ }
+ }
+
+ unsafe impl<T: Clone> Beef for [T] {
+ type PointerT = T;
+
+ #[inline]
+ fn ref_into_parts<U>(&self) -> (NonNull<T>, usize, U::Field)
+ where
+ U: Capacity,
+ {
+ let (fat, cap) = U::empty(self.len());
+
+ // A note on soundness:
+ //
+ // We are casting *const T to *mut T, however for all borrowed values
+ // this raw pointer is only ever dereferenced back to &T.
+ (
+ unsafe { NonNull::new_unchecked(self.as_ptr() as *mut T) },
+ fat,
+ cap,
+ )
+ }
+
+ #[inline]
+ unsafe fn ref_from_parts<U>(ptr: NonNull<T>, fat: usize) -> *const [T]
+ where
+ U: Capacity,
+ {
+ slice_from_raw_parts(ptr.as_ptr(), U::len(fat))
+ }
+
+ #[inline]
+ fn owned_into_parts<U>(owned: Vec<T>) -> (NonNull<T>, usize, U::Field)
+ where
+ U: Capacity,
+ {
+ // Convert to `Vec::into_raw_parts` once stabilized
+ let mut owned = ManuallyDrop::new(owned);
+ let (fat, cap) = U::store(owned.len(), owned.capacity());
+
+ (
+ unsafe { NonNull::new_unchecked(owned.as_mut_ptr()) },
+ fat,
+ cap,
+ )
+ }
+
+ #[inline]
+ unsafe fn owned_from_parts<U>(ptr: NonNull<T>, fat: usize, capacity: U::NonZero) -> Vec<T>
+ where
+ U: Capacity,
+ {
+ let (len, cap) = U::unpack(fat, capacity);
+
+ Vec::from_raw_parts(ptr.as_ptr(), len, cap)
+ }
+ }
+}
diff --git a/vendor/beef/src/wide.rs b/vendor/beef/src/wide.rs
new file mode 100644
index 00000000..466e594c
--- /dev/null
+++ b/vendor/beef/src/wide.rs
@@ -0,0 +1,42 @@
+use crate::traits::Capacity;
+use core::num::NonZeroUsize;
+
+/// Compact three word `Cow` that puts the ownership tag in capacity.
+/// This is a type alias, for documentation see [`beef::generic::Cow`](./generic/struct.Cow.html).
+pub type Cow<'a, T> = crate::generic::Cow<'a, T, Wide>;
+
+pub(crate) mod internal {
+ #[derive(Clone, Copy, PartialEq, Eq)]
+ pub struct Wide;
+}
+use internal::Wide;
+
+impl Capacity for Wide {
+ type Field = Option<NonZeroUsize>;
+ type NonZero = NonZeroUsize;
+
+ #[inline]
+ fn len(fat: usize) -> usize {
+ fat
+ }
+
+ #[inline]
+ fn empty(len: usize) -> (usize, Self::Field) {
+ (len, None)
+ }
+
+ #[inline]
+ fn store(len: usize, capacity: usize) -> (usize, Self::Field) {
+ (len, NonZeroUsize::new(capacity))
+ }
+
+ #[inline]
+ fn unpack(fat: usize, capacity: NonZeroUsize) -> (usize, usize) {
+ (fat, capacity.get())
+ }
+
+ #[inline]
+ fn maybe(_: usize, capacity: Option<NonZeroUsize>) -> Option<NonZeroUsize> {
+ capacity
+ }
+}