Expand description
Mitsein provides strongly typed APIs for non-empty collections and views, including (but not limited to) iterators, slices, and containers. Where possible, unnecessary branches are omitted and APIs enforce and reflect the non-empty invariant.
use mitsein::prelude::*;
let mut xs = vec1![0i64, 1, -3];
xs.push(2);
assert_eq!(&0, xs.first());
assert_eq!(6, xs.into_iter1().map(|x| x * 2).map(i64::abs).max());
Note in the above example that operations on xs
yield non-optional outputs,
because xs
is non-empty.
Modules in this crate reflect corresponding modules in core
, alloc
, and std
, though
collection modules are exported at the crate root rather than a collections
module. For
example, Vec
is exported in alloc::vec::Vec
and its non-empty counterpart Vec1
is
exported in mitsein::vec1::Vec1
. APIs in this crate are typically named by appending 1
to
the names of their counterparts.
At time of writing, rustdoc
ignores input type parameters in the “Methods from
Deref<Target = _>
” section. For types that implement Deref<Target = NonEmpty<_>>
, the API
documentation may be misleading and list all methods of NonEmpty
regardless of its input
type parameter. This is mostly a problem for types that dereference to Slice1
, such as
Vec1
. See this rustdoc
bug.
§Non-Empty Types
Types that represent non-empty collections, containers, or views present APIs that reflect the
non-empty guarantee. The names of these types are formed by appending 1
to the name of their
counterparts. For example, the non-empty Vec
type is Vec1
.
§Collections
This crate provides the following non-empty collections and supporting APIs (depending on which Cargo features are enabled):
Non-empty collections are represented with the NonEmpty
type constructor. These types are
exported as type definitions in their respective modules. Similarly to std::prelude
, the
prelude
module notably re-exports Vec1
and the vec1!
macro.
use mitsein::prelude::*;
let mut xs = Vec1::from_head_and_tail(0i64, [1, 2, 3]);
while let Ok(_) = xs.pop_or().get_only() {}
assert_eq!(xs.as_slice(), &[0]);
§Slices
Like collections, non-empty slices are represented with the NonEmpty
type constructor and
the Slice1
and Str1
type definitions. These types are unsized and so are accessed via
references just like standard slices. The prelude
module re-exports Slice1
and the
slice1!
macro.
use mitsein::prelude::*;
fn fold_terminals<T, U, F>(xs: &Slice1<T>, f: F) -> U
where
F: FnOnce(&T, &T) -> U,
{
f(xs.first(), xs.last())
}
let xs = slice1![0i64, 1, 2, 3];
let y = fold_terminals(xs, |first, last| first + last);
assert_eq!(y, 3);
See the slice1
and str1
modules.
§Containers
This crate provides the following non-empty containers for slices (depending on which Cargo features are enabled):
Each of these type definitions has an accompanying extension trait for operations and
conversions that take advantage of the non-empty guarantee. For example, ArcSlice1Ext
provides APIs for non-empty slices in an Arc
. Some collection types like Vec1
support
conversions from and into these containers.
§Iterators
Non-empty iterators are provided by the Iterator1
type constructor. Iterator1
types can
be fallibly constructed from Iterator
types and support many infallible constructions from
non-empty collections and views as well as combinators that cannot reduce cardinality to zero
(e.g., map
).
Supporting traits are re-exported in the prelude
module and provide methods for bridging
between non-empty Iterator1
types and Iterator
types.
use mitsein::iter1;
use mitsein::prelude::*;
let xs = iter1::head_and_tail(0i32, [1, 2]);
let xs: Vec1<_> = xs.into_iter().skip(3).or_non_empty([3]).collect1();
let ys = Vec::new();
let ys: Vec1<_> = ys.extend_non_empty([0i32]);
assert_eq!(xs.as_slice(), &[3]);
assert_eq!(ys.as_slice(), &[0]);
Non-empty collections and views naturally support iteration, collection, etc. via
Iterator1
. When the rayon
feature is enabled, the ParallelIterator1
type implements
parallel and non-empty iterators.
See the iter1
module.
§Arrays
Because primitive arrays must contain initialized items at capacity in safe code, the only
empty array types are [_; 0]
. The Array1
trait is implemented for arrays with a non-zero
cardinality and provides conversions and operations that take advantage of the non-empty
guarantee of such arrays.
use mitsein::prelude::*;
let mut xs = [0i64, 1, 2, 3];
let x = xs.as_mut_slice1().first_mut();
*x = 4;
assert_eq!(xs.as_slice(), &[4, 1, 2, 3]);
At time of writing, it is not possible to implement Array1
for any and all non-empty array
types, so this trait is only implemented for arrays with one to 64 items.
See the array1
module.
§Segmentation
A Segment
is a view over a subset of a collection that can mutate both the items and
topology of its target. This is somewhat similar to a mutable slice, but items can also be
inserted and removed through a Segment
. This crate implements segmentation for both
standard and non-empty collections and is one of the most efficient ways to remove and drain
items from non-empty collections.
use mitsein::prelude::*;
let mut xs = vec1![0i64, 1, 2, 3, 4];
xs.tail().clear(); // Efficiently clears the tail segment of `xs`.
assert_eq!(xs.as_slice(), &[0]);
See the Segmentation
trait.
§Integrations and Cargo Features
Mitsein supports no_std
environments and provides features for integrating as needed with
alloc
and std
. By default, the std
feature is enabled for complete support of the
standard library.
The following table summarizes supported Cargo features and integrations.
Feature | Default | Primary Dependency | Description |
---|---|---|---|
alloc | No | alloc | Non-empty collections that allocate, like Vec1 . |
arbitrary | No | arbitrary | Construction of arbitrary non-empty collections. |
arrayvec | No | arrayvec | Non-empty implementations of arrayvec types. |
indexmap | No | indexmap | Non-empty implementations of indexmap types. |
itertools | No | itertools | Combinators from itertools for Iterator1 . |
rayon | No | rayon | Parallel operations for non-empty types. |
serde | No | serde | De/serialization of non-empty collections with serde . |
smallvec | No | smallvec | Non-empty implementations of smallvec types. |
std | Yes | std | Integrations with std::io . |
Modules§
- array1
- Non-empty arrays.
- array_
vec1 arrayvec
- A non-empty
ArrayVec
. - borrow1
alloc
- Non-empty copy-on-write types.
- boxed1
alloc
- Non-empty boxed collections.
- btree_
map1 alloc
- A non-empty
BTreeMap
. - btree_
set1 alloc
- A non-empty
BTreeSet
. - cmp
- Comparison and ordering extensions.
- index_
map1 indexmap
- A non-empty
IndexMap
. - index_
set1 indexmap
- A non-empty
IndexSet
. - iter1
- Non-empty iterators.
- prelude
- Re-exports of recommended APIs and extension traits for glob imports.
- slice1
- A non-empty slice.
- small_
vec1 smallvec
- A non-empty
SmallVec
. - str1
- A non-empty str.
- string1
alloc
- A non-empty
String
. - sync1
alloc
andtarget_has_atomic="ptr"
- Non-empty synchronized collections.
- vec1
alloc
- A non-empty
Vec
. - vec_
deque1 alloc
- A non-empty
VecDeque
.
Macros§
Structs§
Enums§
Traits§
- Segmentation
arrayvec
oralloc
- Segmented
By arrayvec
oralloc
- Segmented
Over arrayvec
oralloc