#[derive(Plural)] for creating frictionless new types with any collection
type.
- Automatically implements
From,Into,FromIterator,IntoIterator, and methods like.len()or::with_capacity. - Supports any collection that behaves like
VecandHashMap.
// This implements `From`, `Into`, `FromIterator`, `IntoIterator`.
#[derive(Plural)]
struct Numbers(Vec<u32>);
// use `From` trait
let my_favorite_numbers: Numbers = vec![].into();
// methods like `len()` are implemented
assert_eq!(my_favorite_numbers.len(), 0);
assert!(my_favorite_numbers.is_empty());
// `FromIterator` allows this `collect()`
let doubled_numbers: Numbers = my_favorite_numbers.iter().map(|x| x * 2).collect();
// `HashMap` like collections are also supported
#[derive(Plural)]
struct FavoriteNumbers(HashMap<&'static str, Numbers>);
// construct the struct with using `FromIterator`
let favorite_numbers =
FavoriteNumbers::from_iter([("ryo33", my_favorite_numbers), ("someone", doubled_numbers)]);
// use it in a `for` loop (`IntoIterator` trait)
for (name, numbers) in favorite_numbers {
// use Deref trait
println!("{} has {} favorite number(s)", name, numbers.0.len());
}By default, #[derive(Plural)] implements a comprehensive set of methods and traits. However, you can gain finer-grained control over what gets generated by using the #[plural(...)] attribute.
If you specify methods or traits within the plural attribute, only those specified will be implemented.
Available options for #[plural(...)]:
len: Implementsfn len(&self) -> usize.is_empty: Implementsfn is_empty(&self) -> bool.iter: Implementsfn iter(&self) -> impl Iterator<Item = &ItemType>.capacity: Implementsfn capacity(&self) -> usize.reserve: Implementsfn reserve(&mut self, additional: usize).with_capacity: Implementsfn with_capacity(capacity: usize) -> Self.new: Implementsfn new() -> Self.clear: Implementsfn clear(&mut self).extend: Implementsimpl Extend<ItemType> for Self.from_plural: Implementsimpl From<Self> for UnderlyingCollectionType.from_inner: Implementsimpl From<UnderlyingCollectionType> for Self.into_iter: Implementsimpl IntoIterator for Self(consumingself).into_iter_ref: Implementsimpl IntoIterator for &Self.from_iter: Implementsimpl FromIterator<ItemType> for Self.
Example of selective implementation:
use thisisplural::Plural;
use std::collections::VecDeque;
// Only implement `new`, `len`, and the `Extend` trait.
#[derive(Plural, Debug, PartialEq)]
#[plural(new, len, extend)]
struct MyQueue(VecDeque<String>);
fn main() {
let mut queue = MyQueue::new();
assert_eq!(queue.len(), 0);
queue.extend(vec!["hello".to_string(), "world".to_string()]);
assert_eq!(queue.len(), 2);
}