Skip to content

collection_cap

Build Docs dependency status codecov GitHub License

A lightweight crate for defining and validating capacity constraints.

This crate is no_std compatible and contains no unsafe code.

Core Traits

  • Capacity: Validates iterator compatibility against a capacity constraint.
  • StaticCap: Declares a compile-time capacity constraint.
  • VariableCap: Declares a runtime capacity constraint.

Implementations are provided for Array by default. See the features section for more conditional enabled implementations.

Types that have a compile-time capacity constraint (like arrays) can implement StaticCap. And select a static Capacity implementation to use. This is most useful for pre-validating collection type operations.

use collection_cap::StaticCap;
use collection_cap::cap::StaticMaxCap;

struct MyStaticCollection;

impl StaticCap for MyStaticCollection {
    type Cap = StaticMaxCap<10>;
    const CAP: Self::Cap = StaticMaxCap::<10>;
}

Types that have a capacity constraint that can change or is determined at runtime (like ArrayVec) can implement VariableCap. And return a Capacity implementation that reflects the current capacity constraint. This is most useful for pre-validating extension operations.

use collection_cap::VariableCap;
use collection_cap::cap::MaxCapVal;

struct MyDynamicCollection { remaining: usize }

impl VariableCap for MyDynamicCollection {
    type Cap = MaxCapVal;
    fn capacity(&self) -> Self::Cap { MaxCapVal(self.remaining) }
}

While the Capacity trait can be used directly, it is most useful when combined with the IterCapExt extension trait. This trait provides a number of methods for checking iterator compatibility and fit.

use collection_cap::IterCapExt;
use arrayvec::ArrayVec;

(0..10).ensure_compatible::<[i32; 10]>().expect("Exact match");
(0..11).ensure_compatible::<ArrayVec<i32, 10>>().expect_err("Overflow");

let mut vec: ArrayVec<i32, 10> = (0..5).collect();
(0..3).ensure_compatible_with(&vec).expect("Fits remaining");
(0..6).ensure_compatible_with(&vec).expect_err("Too many");

Capacity types

The following Capacity implementations are provided.

Represents Variable Static Range equivalent
Minimum MinCapVal StaticMinCap min..
Maximum MaxCapVal StaticMaxCap ..=max
Min & Max MinMaxCapVal StaticMinMaxCap min..=max
Exact ExactCapVal StaticExactCap size..=size
Unbounded UnboundedCap UnboundedCap ..

These types can be used either directly, or as a return type parameter for StaticCap or VariableCap. VariableCap is also implemented for std range types, as indicated.

use collection_cap::IterCapExt;
use collection_cap::cap::StaticExactCap;

(0..5).ensure_compatible_with(..=5).expect("should be compatible");
(0..6).ensure_compatible_with(..=5).expect_err("should not be compatible");

(0..5).ensure_compatible::<StaticExactCap<5>>().expect("should be compatible");
(0..6).ensure_compatible::<StaticExactCap<5>>().expect_err("should not be compatible");

Capacity 'Compatibility'

Note that for non-ExactSizeIterator, these checks only guarantee that an iterator's size_hint is compatible with the given capacity. They do not guarantee that an iterator will actually fit the capacity during iteration, as the size_hint only reports the minimum and maximum number of elements an iterator might produce. An error is only returned if the iterator's size_hint indicates that it cannot fit the capacity constraint.

For a stronger guarantee, IterCapExt::ensure_fit and IterCapExt::ensure_fits_into can be used. These methods check if the entire range reported by an iterator's size_hint fits within the capacity constraints. If any possible count of elements could violate the constraint, these methods will return an error.

Put another way, ensure_compatible has the possibility of a false positive, while ensure_fit has the possibility of a false negative.

use collection_cap::IterCapExt;

let max_5_elements = ..=4;

let produces_10 = (0..10).filter(|_| true);
assert_eq!(produces_10.size_hint(), (0, Some(10)), "Can produce 0 to 10 elements");
produces_10.ensure_compatible_with(max_5_elements)
    .expect("Compatibility only requires that it MIGHT fit");

let produces_3 = (0..10).filter(|x| *x < 3);
assert_eq!(produces_3.size_hint(), (0, Some(10)), "Can produce 0 to 10 elements");
produces_3.ensure_fits_into(max_5_elements)
    .expect_err("Fit requires that it MUST fit");

See the Capacity#note-on-fit documentation for more details.

Installation

It's on crates.io: collection_cap

Features

  • arrayvec: Implements StaticCap and VariableCap for ArrayVec.
  • alloc: Adds the SpareCapacityExt extension trait for Vec, String, and VecDeque to allow querying their remaining capacity as a MaxCapVal.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages