thisisplural

Crates.iothisisplural
lib.rsthisisplural
version0.7.0
created_at2021-09-11 18:16:10.062691+00
updated_at2025-05-11 05:52:20.726486+00
description#[derive(Plural)] for creating frictionless new types with any collection type like Vec or HashMap
homepagehttps://github.com/ryo33/thisisplural
repositoryhttps://github.com/ryo33/thisisplural
max_upload_size
id449816
size30,501
Ryo Hirayama (ryo33)

documentation

README

thisisplural

GitHub MIT/Apache 2.0 Crates.io docs.rs

#[derive(Plural)] for creating frictionless new types with any collection type.

Features

  • Automatically implements From, Into, FromIterator, IntoIterator, and methods like .len() or ::with_capacity.
  • Supports any collection that behaves like Vec and HashMap.

Example

// 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());
}

Selective Implementation with #[plural(...)]

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: Implements fn len(&self) -> usize.
  • is_empty: Implements fn is_empty(&self) -> bool.
  • iter: Implements fn iter(&self) -> impl Iterator<Item = &ItemType>.
  • capacity: Implements fn capacity(&self) -> usize.
  • reserve: Implements fn reserve(&mut self, additional: usize).
  • with_capacity: Implements fn with_capacity(capacity: usize) -> Self.
  • new: Implements fn new() -> Self.
  • clear: Implements fn clear(&mut self).
  • extend: Implements impl Extend<ItemType> for Self.
  • from_plural: Implements impl From<Self> for UnderlyingCollectionType.
  • from_inner: Implements impl From<UnderlyingCollectionType> for Self.
  • into_iter: Implements impl IntoIterator for Self (consuming self).
  • into_iter_ref: Implements impl IntoIterator for &Self.
  • from_iter: Implements impl 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);
}
Commit count: 21

cargo fmt