#collection #collect #macro

collect-mac

This crate provides the collect! macro, which can be used to easily construct arbitrary collections, including Vec, String, and HashMap. It also endeavours to construct the collection with a single allocation, where possible.

1 unstable release

Uses old Rust 2015

0.1.0 Nov 13, 2015

#2698 in Rust patterns

Download history 264/week @ 2023-10-29 196/week @ 2023-11-05 184/week @ 2023-11-12 174/week @ 2023-11-19 174/week @ 2023-11-26 136/week @ 2023-12-03 144/week @ 2023-12-10 224/week @ 2023-12-17 301/week @ 2023-12-24 188/week @ 2023-12-31 248/week @ 2024-01-07 295/week @ 2024-01-14 148/week @ 2024-01-21 111/week @ 2024-01-28 146/week @ 2024-02-04 142/week @ 2024-02-11

569 downloads per month
Used in 18 crates (10 directly)

MIT license

8KB
83 lines

collect!

This crate provides the collect! macro, which can be used to easily construct arbitrary collections, including Vec, String, and HashMap. It also endeavours to construct the collection with a single allocation, where possible.

(Documentation for the master branch.)


lib.rs:

This crate provides the collect! macro, which can be used to easily construct arbitrary collections, including Vec, String, and HashMap. It also endeavours to construct the collection with a single allocation, where possible.

Example

// In the crate root module:
#[macro_use] extern crate collect_mac;

// Initialise an empty collection.
let a: Vec<i32> = collect![];
let b: HashMap<String, bool> = collect![];

// Initialise a sequence.
let c: String = collect!['a', 'b', 'c'];

// Initialise a sequence with a type constraint.
let d = collect![as HashSet<_>: 0, 1, 2];

// Initialise a map collection.
let e: BTreeMap<i32, &str> = collect![
1 => "one",
2 => "two",
3 => "many",
4 => "lots",
];

// Initialise a map with a type constraint.
let f: HashMap<_, u8> = collect![as HashMap<i32, _>: 42 => 0, -11 => 2];

Details

The macro supports any collection which implements both the Default and Extend traits. Specifically, it creates a new, empty collection using Default, then calls Extend once for each element.

Single-allocation construction is tested and guaranteed for the following standard containers:

In general, single-allocation construction is done by providing the number of elements through the Iterator::size_hint of the first call to Extend. The expectation is that the collection will, if possible, pre-allocate enough space for all the elements when it goes to insert the first.

As an example, here is a simplified version of the Extend implementation for Vec:

impl<T> Extend<T> for Vec<T> {
#[inline]
fn extend<I: IntoIterator<Item=T>>(&mut self, iterable: I) {
let mut iterator = iterable.into_iter();
while let Some(element) = iterator.next() {
let len = self.len();
if len == self.capacity() {
let (lower, _) = iterator.size_hint();
self.reserve(lower.saturating_add(1));
}
self.push(element);
}
}
}

No runtime deps