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/slab/.cargo-checksum.json vendored Normal file
View File

@@ -0,0 +1 @@
{"files":{"CHANGELOG.md":"cb9f260f16019027a100d74b92ac12f4ee9b522f5b6ddb32f804a6ced39746b7","Cargo.lock":"cdd9ac07a3c835f3340778974314a7b35144895fe9ce1a2cdb1672490bc9c583","Cargo.toml":"057ba9c56a3d11d7f30ea20351a5540d524da699628778e983b732c66b71ed8e","LICENSE":"8ce0830173fdac609dfb4ea603fdc002c2f4af0dc9b1a005653f5da9cf534b18","README.md":"6e8d6d493aec6526593ae9b05e3b21d3f878c5816a94af9d372598e03406b35f","src/builder.rs":"87e629b1f9853d910389635b27a42391f1681cd5638d81e386215211e8b67847","src/lib.rs":"3cf902e951dec7166f779b1930b24a26ab2f2a20ce7298888f0bebadbd96ad94","src/serde.rs":"e58650a04644cb732119f50eefe6a3066104b5b41be7074e12525e05e2ad21b7","tests/serde.rs":"bb28112509dbb6949528802d05a1b1e34d2e5ff9d3ba5f62aa801cfb3de7a78e","tests/slab.rs":"98688c5a5d67eaed7378b6ffa76bdf6b4f0c8d507def550574fef6630375f087"},"package":"7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"}

66
vendor/slab/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,66 @@
# 0.4.11 (August 8, 2025)
* Fix `Slab::get_disjoint_mut` out of bounds (#152)
# 0.4.10 (June 15, 2025)
* Add `Slab::get_disjoint_mut` (#149)
* Drop build script and `autocfg` dependency (#150)
* Fix redundant import warning in no_std builds (#143)
* Fix `clippy::needless_lifetimes` warning (#147)
* Internal CI improvements (#141, #146)
# 0.4.9 (August 22, 2023)
* Avoid reallocations in `Slab::clone_from` (#137)
# 0.4.8 (January 20, 2023)
* Fixed documentation about overflow (#124)
* Document panic in `get2_mut` (#131)
* Refactoring (#129, #132)
# 0.4.7 (July 19, 2022)
* Use `#[track_caller]` on Rust 1.46+ (#119)
* Make `Slab::new` const on Rust 1.39+ (#119)
# 0.4.6 (April 2, 2022)
* Add `Slab::vacant_key` (#114)
* Fix stacked borrows violation in `Slab::get2_unchecked_mut` (#115)
# 0.4.5 (October 13, 2021)
* Add alternate debug output for listing items in the slab (#108)
* Fix typo in debug output of IntoIter (#109)
* Impl 'Clone' for 'Iter' (#110)
# 0.4.4 (August 06, 2021)
* Fix panic in `FromIterator` impl (#102)
* Fix compatibility with older clippy versions (#104)
* Add `try_remove` method (#89)
* Implement `ExactSizeIterator` and `FusedIterator` for iterators (#92)
# 0.4.3 (April 20, 2021)
* Add no_std support for Rust 1.36 and above (#71).
* Add `get2_mut` and `get2_unchecked_mut` methods (#65).
* Make `shrink_to_fit()` remove trailing vacant entries (#62).
* Implement `FromIterator<(usize, T)>` (#62).
* Implement `IntoIterator<Item = (usize, T)>` (#62).
* Provide `size_hint()` of the iterators (#62).
* Make all iterators reversible (#62).
* Add `key_of()` method (#61)
* Add `compact()` method (#60)
* Add support for serde (#85)
# 0.4.2 (January 11, 2019)
* Add `Slab::drain` (#56).
# 0.4.1 (July 15, 2018)
* Improve `reserve` and `reserve_exact` (#37).
* Implement `Default` for `Slab` (#43).

73
vendor/slab/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,73 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_test"
version = "1.0.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f901ee573cab6b3060453d2d5f0bae4e6d628c23c0a962ff9b5f1d7c8d4f1ed"
dependencies = [
"serde",
]
[[package]]
name = "slab"
version = "0.4.11"
dependencies = [
"serde",
"serde_test",
]
[[package]]
name = "syn"
version = "2.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"

67
vendor/slab/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,67 @@
# 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 = "slab"
version = "0.4.11"
authors = ["Carl Lerche <me@carllerche.com>"]
build = false
exclude = ["/.*"]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Pre-allocated storage for a uniform data type"
readme = "README.md"
keywords = [
"slab",
"allocator",
"no_std",
]
categories = [
"memory-management",
"data-structures",
"no-std",
]
license = "MIT"
repository = "https://github.com/tokio-rs/slab"
[features]
default = ["std"]
std = []
[lib]
name = "slab"
path = "src/lib.rs"
[[test]]
name = "serde"
path = "tests/serde.rs"
[[test]]
name = "slab"
path = "tests/slab.rs"
[dependencies.serde]
version = "1.0.95"
features = ["alloc"]
optional = true
default-features = false
[dev-dependencies.serde]
version = "1"
features = ["derive"]
[dev-dependencies.serde_test]
version = "1"

25
vendor/slab/LICENSE vendored Normal file
View File

@@ -0,0 +1,25 @@
Copyright (c) 2019 Carl Lerche
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.

51
vendor/slab/README.md vendored Normal file
View File

@@ -0,0 +1,51 @@
# Slab
Pre-allocated storage for a uniform data type.
[![Crates.io][crates-badge]][crates-url]
[![Build Status][ci-badge]][ci-url]
[crates-badge]: https://img.shields.io/crates/v/slab
[crates-url]: https://crates.io/crates/slab
[ci-badge]: https://img.shields.io/github/actions/workflow/status/tokio-rs/slab/ci.yml?branch=master
[ci-url]: https://github.com/tokio-rs/slab/actions
[Documentation](https://docs.rs/slab)
## Usage
To use `slab`, first add this to your `Cargo.toml`:
```toml
[dependencies]
slab = "0.4"
```
Next, add this to your crate:
```rust
use slab::Slab;
let mut slab = Slab::new();
let hello = slab.insert("hello");
let world = slab.insert("world");
assert_eq!(slab[hello], "hello");
assert_eq!(slab[world], "world");
slab[world] = "earth";
assert_eq!(slab[world], "earth");
```
See [documentation](https://docs.rs/slab) for more details.
## License
This project is licensed under the [MIT license](LICENSE).
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in `slab` by you, shall be licensed as MIT, without any additional
terms or conditions.

63
vendor/slab/src/builder.rs vendored Normal file
View File

@@ -0,0 +1,63 @@
use crate::{Entry, Slab};
// Building `Slab` from pairs (usize, T).
pub(crate) struct Builder<T> {
slab: Slab<T>,
vacant_list_broken: bool,
first_vacant_index: Option<usize>,
}
impl<T> Builder<T> {
pub(crate) fn with_capacity(capacity: usize) -> Self {
Self {
slab: Slab::with_capacity(capacity),
vacant_list_broken: false,
first_vacant_index: None,
}
}
pub(crate) fn pair(&mut self, key: usize, value: T) {
let slab = &mut self.slab;
if key < slab.entries.len() {
// iterator is not sorted, might need to recreate vacant list
if let Entry::Vacant(_) = slab.entries[key] {
self.vacant_list_broken = true;
slab.len += 1;
}
// if an element with this key already exists, replace it.
// This is consistent with HashMap and BtreeMap
slab.entries[key] = Entry::Occupied(value);
} else {
if self.first_vacant_index.is_none() && slab.entries.len() < key {
self.first_vacant_index = Some(slab.entries.len());
}
// insert holes as necessary
while slab.entries.len() < key {
// add the entry to the start of the vacant list
let next = slab.next;
slab.next = slab.entries.len();
slab.entries.push(Entry::Vacant(next));
}
slab.entries.push(Entry::Occupied(value));
slab.len += 1;
}
}
pub(crate) fn build(self) -> Slab<T> {
let mut slab = self.slab;
if slab.len == slab.entries.len() {
// no vacant entries, so next might not have been updated
slab.next = slab.entries.len();
} else if self.vacant_list_broken {
slab.recreate_vacant_list();
} else if let Some(first_vacant_index) = self.first_vacant_index {
let next = slab.entries.len();
match &mut slab.entries[first_vacant_index] {
Entry::Vacant(n) => *n = next,
_ => unreachable!(),
}
} else {
unreachable!()
}
slab
}
}

1644
vendor/slab/src/lib.rs vendored Normal file

File diff suppressed because it is too large Load Diff

62
vendor/slab/src/serde.rs vendored Normal file
View File

@@ -0,0 +1,62 @@
use core::fmt;
use core::marker::PhantomData;
use serde::de::{Deserialize, Deserializer, MapAccess, Visitor};
use serde::ser::{Serialize, SerializeMap, Serializer};
use super::{builder::Builder, Slab};
impl<T> Serialize for Slab<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map_serializer = serializer.serialize_map(Some(self.len()))?;
for (key, value) in self {
map_serializer.serialize_key(&key)?;
map_serializer.serialize_value(value)?;
}
map_serializer.end()
}
}
struct SlabVisitor<T>(PhantomData<T>);
impl<'de, T> Visitor<'de> for SlabVisitor<T>
where
T: Deserialize<'de>,
{
type Value = Slab<T>;
fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "a map")
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut builder = Builder::with_capacity(map.size_hint().unwrap_or(0));
while let Some((key, value)) = map.next_entry()? {
builder.pair(key, value)
}
Ok(builder.build())
}
}
impl<'de, T> Deserialize<'de> for Slab<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(SlabVisitor(PhantomData))
}
}

49
vendor/slab/tests/serde.rs vendored Normal file
View File

@@ -0,0 +1,49 @@
#![cfg(feature = "serde")]
#![warn(rust_2018_idioms)]
use serde::{Deserialize, Serialize};
use serde_test::{assert_tokens, Token};
use slab::Slab;
#[derive(Debug, Serialize, Deserialize)]
#[serde(transparent)]
struct SlabPartialEq<T>(Slab<T>);
impl<T: PartialEq> PartialEq for SlabPartialEq<T> {
fn eq(&self, other: &Self) -> bool {
self.0.len() == other.0.len()
&& self
.0
.iter()
.zip(other.0.iter())
.all(|(this, other)| this.0 == other.0 && this.1 == other.1)
}
}
#[test]
fn test_serde_empty() {
let slab = Slab::<usize>::new();
assert_tokens(
&SlabPartialEq(slab),
&[Token::Map { len: Some(0) }, Token::MapEnd],
);
}
#[test]
fn test_serde() {
let vec = vec![(1, 2), (3, 4), (5, 6)];
let slab: Slab<_> = vec.iter().cloned().collect();
assert_tokens(
&SlabPartialEq(slab),
&[
Token::Map { len: Some(3) },
Token::U64(1),
Token::I32(2),
Token::U64(3),
Token::I32(4),
Token::U64(5),
Token::I32(6),
Token::MapEnd,
],
);
}

782
vendor/slab/tests/slab.rs vendored Normal file
View File

@@ -0,0 +1,782 @@
#![warn(rust_2018_idioms)]
use slab::*;
use std::{
iter::FromIterator,
panic::{catch_unwind, resume_unwind, AssertUnwindSafe},
};
#[test]
fn insert_get_remove_one() {
let mut slab = Slab::new();
assert!(slab.is_empty());
let key = slab.insert(10);
assert_eq!(slab[key], 10);
assert_eq!(slab.get(key), Some(&10));
assert!(!slab.is_empty());
assert!(slab.contains(key));
assert_eq!(slab.remove(key), 10);
assert!(!slab.contains(key));
assert!(slab.get(key).is_none());
}
#[test]
fn insert_get_many() {
let mut slab = Slab::with_capacity(10);
for i in 0..10 {
let key = slab.insert(i + 10);
assert_eq!(slab[key], i + 10);
}
assert_eq!(slab.capacity(), 10);
// Storing another one grows the slab
let key = slab.insert(20);
assert_eq!(slab[key], 20);
// Capacity grows by 2x
assert_eq!(slab.capacity(), 20);
}
#[test]
fn insert_get_remove_many() {
let mut slab = Slab::with_capacity(10);
let mut keys = vec![];
for i in 0..10 {
for j in 0..10 {
let val = (i * 10) + j;
let key = slab.insert(val);
keys.push((key, val));
assert_eq!(slab[key], val);
}
for (key, val) in keys.drain(..) {
assert_eq!(val, slab.remove(key));
}
}
assert_eq!(10, slab.capacity());
}
#[test]
fn insert_with_vacant_entry() {
let mut slab = Slab::with_capacity(1);
let key;
{
let entry = slab.vacant_entry();
key = entry.key();
entry.insert(123);
}
assert_eq!(123, slab[key]);
}
#[test]
fn get_vacant_entry_without_using() {
let mut slab = Slab::<usize>::with_capacity(1);
let key = slab.vacant_entry().key();
assert_eq!(key, slab.vacant_entry().key());
}
#[test]
#[should_panic(expected = "invalid key")]
fn invalid_get_panics() {
let slab = Slab::<usize>::with_capacity(1);
let _ = &slab[0];
}
#[test]
#[should_panic(expected = "invalid key")]
fn invalid_get_mut_panics() {
let mut slab = Slab::<usize>::new();
let _ = &mut slab[0];
}
#[test]
#[should_panic(expected = "invalid key")]
fn double_remove_panics() {
let mut slab = Slab::<usize>::with_capacity(1);
let key = slab.insert(123);
slab.remove(key);
slab.remove(key);
}
#[test]
#[should_panic(expected = "invalid key")]
fn invalid_remove_panics() {
let mut slab = Slab::<usize>::with_capacity(1);
slab.remove(0);
}
#[test]
fn slab_get_mut() {
let mut slab = Slab::new();
let key = slab.insert(1);
slab[key] = 2;
assert_eq!(slab[key], 2);
*slab.get_mut(key).unwrap() = 3;
assert_eq!(slab[key], 3);
}
#[test]
fn key_of_tagged() {
let mut slab = Slab::new();
slab.insert(0);
assert_eq!(slab.key_of(&slab[0]), 0);
}
#[test]
fn key_of_layout_optimizable() {
// Entry<&str> doesn't need a discriminant tag because it can use the
// nonzero-ness of ptr and store Vacant's next at the same offset as len
let mut slab = Slab::new();
slab.insert("foo");
slab.insert("bar");
let third = slab.insert("baz");
slab.insert("quux");
assert_eq!(slab.key_of(&slab[third]), third);
}
#[test]
fn key_of_zst() {
let mut slab = Slab::new();
slab.insert(());
let second = slab.insert(());
slab.insert(());
assert_eq!(slab.key_of(&slab[second]), second);
}
#[test]
fn reserve_does_not_allocate_if_available() {
let mut slab = Slab::with_capacity(10);
let mut keys = vec![];
for i in 0..6 {
keys.push(slab.insert(i));
}
for key in 0..4 {
slab.remove(key);
}
assert!(slab.capacity() - slab.len() == 8);
slab.reserve(8);
assert_eq!(10, slab.capacity());
}
#[test]
fn reserve_exact_does_not_allocate_if_available() {
let mut slab = Slab::with_capacity(10);
let mut keys = vec![];
for i in 0..6 {
keys.push(slab.insert(i));
}
for key in 0..4 {
slab.remove(key);
}
assert!(slab.capacity() - slab.len() == 8);
slab.reserve_exact(8);
assert_eq!(10, slab.capacity());
}
#[test]
#[should_panic(expected = "capacity overflow")]
fn reserve_does_panic_with_capacity_overflow() {
let mut slab = Slab::with_capacity(10);
slab.insert(true);
slab.reserve(isize::MAX as usize);
}
#[test]
#[should_panic(expected = "capacity overflow")]
fn reserve_does_panic_with_capacity_overflow_bytes() {
let mut slab = Slab::with_capacity(10);
slab.insert(1u16);
slab.reserve((isize::MAX as usize) / 2);
}
#[test]
#[should_panic(expected = "capacity overflow")]
fn reserve_exact_does_panic_with_capacity_overflow() {
let mut slab = Slab::with_capacity(10);
slab.insert(true);
slab.reserve_exact(isize::MAX as usize);
}
#[test]
fn retain() {
let mut slab = Slab::with_capacity(2);
let key1 = slab.insert(0);
let key2 = slab.insert(1);
slab.retain(|key, x| {
assert_eq!(key, *x);
*x % 2 == 0
});
assert_eq!(slab.len(), 1);
assert_eq!(slab[key1], 0);
assert!(!slab.contains(key2));
// Ensure consistency is retained
let key = slab.insert(123);
assert_eq!(key, key2);
assert_eq!(2, slab.len());
assert_eq!(2, slab.capacity());
// Inserting another element grows
let key = slab.insert(345);
assert_eq!(key, 2);
assert_eq!(4, slab.capacity());
}
#[test]
fn into_iter() {
let mut slab = Slab::new();
for i in 0..8 {
slab.insert(i);
}
slab.remove(0);
slab.remove(4);
slab.remove(5);
slab.remove(7);
let vals: Vec<_> = slab
.into_iter()
.inspect(|&(key, val)| assert_eq!(key, val))
.map(|(_, val)| val)
.collect();
assert_eq!(vals, vec![1, 2, 3, 6]);
}
#[test]
fn into_iter_rev() {
let mut slab = Slab::new();
for i in 0..4 {
slab.insert(i);
}
let mut iter = slab.into_iter();
assert_eq!(iter.next_back(), Some((3, 3)));
assert_eq!(iter.next_back(), Some((2, 2)));
assert_eq!(iter.next(), Some((0, 0)));
assert_eq!(iter.next_back(), Some((1, 1)));
assert_eq!(iter.next_back(), None);
assert_eq!(iter.next(), None);
}
#[test]
fn iter() {
let mut slab = Slab::new();
for i in 0..4 {
slab.insert(i);
}
let vals: Vec<_> = slab
.iter()
.enumerate()
.map(|(i, (key, val))| {
assert_eq!(i, key);
*val
})
.collect();
assert_eq!(vals, vec![0, 1, 2, 3]);
slab.remove(1);
let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
assert_eq!(vals, vec![0, 2, 3]);
}
#[test]
fn iter_rev() {
let mut slab = Slab::new();
for i in 0..4 {
slab.insert(i);
}
slab.remove(0);
let vals = slab.iter().rev().collect::<Vec<_>>();
assert_eq!(vals, vec![(3, &3), (2, &2), (1, &1)]);
}
#[test]
fn iter_mut() {
let mut slab = Slab::new();
for i in 0..4 {
slab.insert(i);
}
for (i, (key, e)) in slab.iter_mut().enumerate() {
assert_eq!(i, key);
*e += 1;
}
let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
assert_eq!(vals, vec![1, 2, 3, 4]);
slab.remove(2);
for (_, e) in slab.iter_mut() {
*e += 1;
}
let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
assert_eq!(vals, vec![2, 3, 5]);
}
#[test]
fn iter_mut_rev() {
let mut slab = Slab::new();
for i in 0..4 {
slab.insert(i);
}
slab.remove(2);
{
let mut iter = slab.iter_mut();
assert_eq!(iter.next(), Some((0, &mut 0)));
let mut prev_key = !0;
for (key, e) in iter.rev() {
*e += 10;
assert!(prev_key > key);
prev_key = key;
}
}
assert_eq!(slab[0], 0);
assert_eq!(slab[1], 11);
assert_eq!(slab[3], 13);
assert!(!slab.contains(2));
}
#[test]
fn from_iterator_sorted() {
let mut slab = (0..5).map(|i| (i, i)).collect::<Slab<_>>();
assert_eq!(slab.len(), 5);
assert_eq!(slab[0], 0);
assert_eq!(slab[2], 2);
assert_eq!(slab[4], 4);
assert_eq!(slab.vacant_entry().key(), 5);
}
#[test]
fn from_iterator_new_in_order() {
// all new keys come in increasing order, but existing keys are overwritten
let mut slab = [(0, 'a'), (1, 'a'), (1, 'b'), (0, 'b'), (9, 'a'), (0, 'c')]
.iter()
.cloned()
.collect::<Slab<_>>();
assert_eq!(slab.len(), 3);
assert_eq!(slab[0], 'c');
assert_eq!(slab[1], 'b');
assert_eq!(slab[9], 'a');
assert_eq!(slab.get(5), None);
assert_eq!(slab.vacant_entry().key(), 8);
}
#[test]
fn from_iterator_unordered() {
let mut slab = vec![(1, "one"), (50, "fifty"), (3, "three"), (20, "twenty")]
.into_iter()
.collect::<Slab<_>>();
assert_eq!(slab.len(), 4);
assert_eq!(slab.vacant_entry().key(), 0);
let mut iter = slab.iter();
assert_eq!(iter.next(), Some((1, &"one")));
assert_eq!(iter.next(), Some((3, &"three")));
assert_eq!(iter.next(), Some((20, &"twenty")));
assert_eq!(iter.next(), Some((50, &"fifty")));
assert_eq!(iter.next(), None);
}
// https://github.com/tokio-rs/slab/issues/100
#[test]
fn from_iterator_issue_100() {
let mut slab: slab::Slab<()> = vec![(1, ())].into_iter().collect();
assert_eq!(slab.len(), 1);
assert_eq!(slab.insert(()), 0);
assert_eq!(slab.insert(()), 2);
assert_eq!(slab.insert(()), 3);
let mut slab: slab::Slab<()> = vec![(1, ()), (2, ())].into_iter().collect();
assert_eq!(slab.len(), 2);
assert_eq!(slab.insert(()), 0);
assert_eq!(slab.insert(()), 3);
assert_eq!(slab.insert(()), 4);
let mut slab: slab::Slab<()> = vec![(1, ()), (3, ())].into_iter().collect();
assert_eq!(slab.len(), 2);
assert_eq!(slab.insert(()), 2);
assert_eq!(slab.insert(()), 0);
assert_eq!(slab.insert(()), 4);
let mut slab: slab::Slab<()> = vec![(0, ()), (2, ()), (3, ()), (5, ())]
.into_iter()
.collect();
assert_eq!(slab.len(), 4);
assert_eq!(slab.insert(()), 4);
assert_eq!(slab.insert(()), 1);
assert_eq!(slab.insert(()), 6);
}
#[test]
fn clear() {
let mut slab = Slab::new();
for i in 0..4 {
slab.insert(i);
}
// clear full
slab.clear();
assert!(slab.is_empty());
assert_eq!(0, slab.len());
assert_eq!(4, slab.capacity());
for i in 0..2 {
slab.insert(i);
}
let vals: Vec<_> = slab.iter().map(|(_, r)| *r).collect();
assert_eq!(vals, vec![0, 1]);
// clear half-filled
slab.clear();
assert!(slab.is_empty());
}
#[test]
fn shrink_to_fit_empty() {
let mut slab = Slab::<bool>::with_capacity(20);
slab.shrink_to_fit();
assert_eq!(slab.capacity(), 0);
}
#[test]
fn shrink_to_fit_no_vacant() {
let mut slab = Slab::with_capacity(20);
slab.insert(String::new());
slab.shrink_to_fit();
assert!(slab.capacity() < 10);
}
#[test]
fn shrink_to_fit_doesnt_move() {
let mut slab = Slab::with_capacity(8);
slab.insert("foo");
let bar = slab.insert("bar");
slab.insert("baz");
let quux = slab.insert("quux");
slab.remove(quux);
slab.remove(bar);
slab.shrink_to_fit();
assert_eq!(slab.len(), 2);
assert!(slab.capacity() >= 3);
assert_eq!(slab.get(0), Some(&"foo"));
assert_eq!(slab.get(2), Some(&"baz"));
assert_eq!(slab.vacant_entry().key(), bar);
}
#[test]
fn shrink_to_fit_doesnt_recreate_list_when_nothing_can_be_done() {
let mut slab = Slab::with_capacity(16);
for i in 0..4 {
slab.insert(Box::new(i));
}
slab.remove(0);
slab.remove(2);
slab.remove(1);
assert_eq!(slab.vacant_entry().key(), 1);
slab.shrink_to_fit();
assert_eq!(slab.len(), 1);
assert!(slab.capacity() >= 4);
assert_eq!(slab.vacant_entry().key(), 1);
}
#[test]
fn compact_empty() {
let mut slab = Slab::new();
slab.compact(|_, _, _| panic!());
assert_eq!(slab.len(), 0);
assert_eq!(slab.capacity(), 0);
slab.reserve(20);
slab.compact(|_, _, _| panic!());
assert_eq!(slab.len(), 0);
assert_eq!(slab.capacity(), 0);
slab.insert(0);
slab.insert(1);
slab.insert(2);
slab.remove(1);
slab.remove(2);
slab.remove(0);
slab.compact(|_, _, _| panic!());
assert_eq!(slab.len(), 0);
assert_eq!(slab.capacity(), 0);
}
#[test]
fn compact_no_moves_needed() {
let mut slab = Slab::new();
for i in 0..10 {
slab.insert(i);
}
slab.remove(8);
slab.remove(9);
slab.remove(6);
slab.remove(7);
slab.compact(|_, _, _| panic!());
assert_eq!(slab.len(), 6);
for ((index, &value), want) in slab.iter().zip(0..6) {
assert!(index == value);
assert_eq!(index, want);
}
assert!(slab.capacity() >= 6 && slab.capacity() < 10);
}
#[test]
fn compact_moves_successfully() {
let mut slab = Slab::with_capacity(20);
for i in 0..10 {
slab.insert(i);
}
for &i in &[0, 5, 9, 6, 3] {
slab.remove(i);
}
let mut moved = 0;
slab.compact(|&mut v, from, to| {
assert!(from > to);
assert!(from >= 5);
assert!(to < 5);
assert_eq!(from, v);
moved += 1;
true
});
assert_eq!(slab.len(), 5);
assert_eq!(moved, 2);
assert_eq!(slab.vacant_entry().key(), 5);
assert!(slab.capacity() >= 5 && slab.capacity() < 20);
let mut iter = slab.iter();
assert_eq!(iter.next(), Some((0, &8)));
assert_eq!(iter.next(), Some((1, &1)));
assert_eq!(iter.next(), Some((2, &2)));
assert_eq!(iter.next(), Some((3, &7)));
assert_eq!(iter.next(), Some((4, &4)));
assert_eq!(iter.next(), None);
}
#[test]
fn compact_doesnt_move_if_closure_errors() {
let mut slab = Slab::with_capacity(20);
for i in 0..10 {
slab.insert(i);
}
for &i in &[9, 3, 1, 4, 0] {
slab.remove(i);
}
slab.compact(|&mut v, from, to| {
assert!(from > to);
assert_eq!(from, v);
v != 6
});
assert_eq!(slab.len(), 5);
assert!(slab.capacity() >= 7 && slab.capacity() < 20);
assert_eq!(slab.vacant_entry().key(), 3);
let mut iter = slab.iter();
assert_eq!(iter.next(), Some((0, &8)));
assert_eq!(iter.next(), Some((1, &7)));
assert_eq!(iter.next(), Some((2, &2)));
assert_eq!(iter.next(), Some((5, &5)));
assert_eq!(iter.next(), Some((6, &6)));
assert_eq!(iter.next(), None);
}
#[test]
fn compact_handles_closure_panic() {
let mut slab = Slab::new();
for i in 0..10 {
slab.insert(i);
}
for i in 1..6 {
slab.remove(i);
}
let result = catch_unwind(AssertUnwindSafe(|| {
slab.compact(|&mut v, from, to| {
assert!(from > to);
assert_eq!(from, v);
if v == 7 {
panic!("test");
}
true
})
}));
match result {
Err(ref payload) if payload.downcast_ref() == Some(&"test") => {}
Err(bug) => resume_unwind(bug),
Ok(()) => unreachable!(),
}
assert_eq!(slab.len(), 5 - 1);
assert_eq!(slab.vacant_entry().key(), 3);
let mut iter = slab.iter();
assert_eq!(iter.next(), Some((0, &0)));
assert_eq!(iter.next(), Some((1, &9)));
assert_eq!(iter.next(), Some((2, &8)));
assert_eq!(iter.next(), Some((6, &6)));
assert_eq!(iter.next(), None);
}
#[test]
fn fully_consumed_drain() {
let mut slab = Slab::new();
for i in 0..3 {
slab.insert(i);
}
{
let mut drain = slab.drain();
assert_eq!(Some(0), drain.next());
assert_eq!(Some(1), drain.next());
assert_eq!(Some(2), drain.next());
assert_eq!(None, drain.next());
}
assert!(slab.is_empty());
}
#[test]
fn partially_consumed_drain() {
let mut slab = Slab::new();
for i in 0..3 {
slab.insert(i);
}
{
let mut drain = slab.drain();
assert_eq!(Some(0), drain.next());
}
assert!(slab.is_empty())
}
#[test]
fn drain_rev() {
let mut slab = Slab::new();
for i in 0..10 {
slab.insert(i);
}
slab.remove(9);
let vals: Vec<u64> = slab.drain().rev().collect();
assert_eq!(vals, (0..9).rev().collect::<Vec<u64>>());
}
#[test]
fn try_remove() {
let mut slab = Slab::new();
let key = slab.insert(1);
assert_eq!(slab.try_remove(key), Some(1));
assert_eq!(slab.try_remove(key), None);
assert_eq!(slab.get(key), None);
}
#[test]
fn const_new() {
static _SLAB: Slab<()> = Slab::new();
}
#[test]
fn clone_from() {
let mut slab1 = Slab::new();
let mut slab2 = Slab::new();
for i in 0..5 {
slab1.insert(i);
slab2.insert(2 * i);
slab2.insert(2 * i + 1);
}
slab1.remove(1);
slab1.remove(3);
slab2.clone_from(&slab1);
let mut iter2 = slab2.iter();
assert_eq!(iter2.next(), Some((0, &0)));
assert_eq!(iter2.next(), Some((2, &2)));
assert_eq!(iter2.next(), Some((4, &4)));
assert_eq!(iter2.next(), None);
assert!(slab2.capacity() >= 10);
}
#[test]
fn get_disjoint_mut() {
let mut slab = Slab::from_iter((0..5).enumerate());
slab.remove(1);
slab.remove(3);
assert_eq!(slab.get_disjoint_mut([]), Ok([]));
assert_eq!(
slab.get_disjoint_mut([4, 2, 0]).unwrap().map(|x| *x),
[4, 2, 0]
);
assert_eq!(
slab.get_disjoint_mut([42, 2, 1, 2]),
Err(GetDisjointMutError::OverlappingIndices)
);
assert_eq!(
slab.get_disjoint_mut([1, 5]),
Err(GetDisjointMutError::IndexVacant)
);
assert_eq!(
slab.get_disjoint_mut([5, 1]),
Err(GetDisjointMutError::IndexOutOfBounds)
);
let [a, b] = slab.get_disjoint_mut([0, 4]).unwrap();
(*a, *b) = (*b, *a);
assert_eq!(slab[0], 4);
assert_eq!(slab[4], 0);
}
#[test]
fn get_disjoint_mut_out_of_bounds_index_error() {
let mut slab: Slab<i32> = Slab::with_capacity(10);
slab.insert(1);
slab.insert(2);
// Index 0 and 1 are valid, but index 5 is out of bounds (beyond len)
assert_eq!(
slab.get_disjoint_mut([0, 1, 5]),
Err(GetDisjointMutError::IndexOutOfBounds)
);
}