copy-stack-vec
A no_std, fixed-capacity, stack-allocated vector type for Copy elements, with no unsafe code by default.
CopyStackVec<T, N> stores up to N elements inline and provides familiar slice/Vec-like ergonomics without heap
allocation or runtime growth. In the default backend, many constructors require T: Copy + Default,
while some helpers (like new_with and From<[T; N]>) only need T: Copy. With the
unsafe-maybe-uninit backend, only T: Copy is required.
no_stdcompatible.- no internal
unsafein the default backend (#![forbid(unsafe_code)]). - stack-allocated, fixed capacity (
Nknown at compile time). - the container itself is
Copy(value semantics; moving copies the whole buffer). - optional
unsafe-maybe-uninitbackend. - separation between fallible and truncating operations.
- optional
serdesupport.
Using copy-stack-vec
Add the crate to your project
cargo add copy-stack-vec
Example
use CopyStackVec;
let mut v: = default;
v.extend_from_slice.unwrap;
assert_eq!;
let mut w: = default;
w.push.unwrap;
w.extend_from_slice.unwrap;
assert_eq!;
Crate usage
The copy-stack-vec crate can be a good fit when:
- you need a small fixed-capacity buffer on the stack;
- you prefer value semantics (the container itself is
Copy) and your element type isCopy; - you want a crate that defaults to no unsafe code;
- you want deterministic, heap-allocation-free behavior.
It may not be the best tool if:
- you need large capacities or large element types;
- you frequently move the vector by value (moving copies the entire [T; N] buffer);
- you need non-Copy elements or drop semantics;
- you need dynamically growing capacity.
Alternatives
Well-established alternatives exist already (arrayvec, heapless, smallvec, or tinyvec to name a few).
copy-stack-vec is a focused option built around value semantics (the container itself is Copy) and
safe-by-default internals for Copy element types.
Backends
Default backend (safe)
- storage is
[T; N]. - requires
T: Copy + Defaultfor most constructors that build a fresh buffer [1] - all internal code is safe (
#![forbid(unsafe_code)]). - initialization cost is
O(N)when constructing a new vector (eager initialization).
[1] some helpers like CopyStackVec::new_with and From<[T; N]> only require T: Copy. See method documentation.
unsafe-maybe-uninit backend (optional)
- storage is
[MaybeUninit<T>; N] - only requires
T: Copy - avoids eager initialization of all
Nelements - uses minimal, well-scoped internal
unsafe
Range and indexing behavior
CopyStackVec follows Rust slice and Vec semantics for indexing and range-based operations:
- Indexing (
v[i],v[start..end], etc.) panics on out-of-bounds or inverted ranges - just like slices. drain(range)behaves the same asVec::drain(range):start > endorend > len()-> panicstart == end-> empty iterator, no changes- valid ranges remove the elements immediately and shift the tail left
Capacity errors never panic; only range / indexing violations do.
Fallible vs truncating operations
The API explicitly distinguishes two behaviors for capacity-sensitive operations.
Fallible (error if it doesn't fit; no partial writes)
pushextend_from_sliceresizetry_frominserttry_from_itertry_removetry_swap_remove
Truncating (take as much as fits; ignore the rest)
These take up to capacity and do not consume further items once the vector is full:
push_truncatedextend_from_slice_truncatedfrom_slice_truncatedfrom_array_truncatedExtend<T>FromIterator<T>
Note: unlike Vec, collecting into CopyStackVec (via FromIterator / collect::<CopyStackVec<_, N>>())
takes at most the first N elements from the iterator and stops there, leaving the remaining items unconsumed.
Features
serde- enableSerialize/Deserializeunsafe-maybe-uninit- switch to theMaybeUninitbackend and relaxT: Defaultrequirements
Minimum Supported Rust Version (MSRV)
This crate is tested on and supports Rust 1.85 and newer.
MSRV policy:
- The MSRV will not be increased in a patch release.
- The MSRV may be increased in a minor release (e.g.
0.3.x->0.4.0).
License
MIT OR Apache-2.0